Jump to content

  • Log In with Google      Sign In   
  • Create Account

AllEightUp

Member Since 24 Apr 2011
Offline Last Active Today, 11:54 AM

Posts I've Made

In Topic: Do you usually prefix your classes with the letter 'C' or something e...

Yesterday, 07:50 AM

It is worth mentioning that the history of the C prefix is directly tied to the history of C++.  Back when MFC was written C++ namespaces were a horrible mess of half implemented concepts in the compilers and barely worked.  C prefix was a useful work around to prevent conflicts in the global namespace.  There were other examples of this such as an entire Os where all classes were prefixed with B I believe it was.  Anyway, as others have mentioned, C++ has moved on and prefixes are rarely desirable compared to using namespaces.  Also, as others have said, certain types of instances still tend to use Hungarian notations such as g_ or variations.

 

My preferences are generally:

namespaces instead of class prefixes.

often I will use a 't' in front of template class names to differentiate a utility template from a base class, but it is generally only in the case where the template is a helper to implement boilerplate code over the base class.

generally I use the g_ or other prefix to differentiate special scoping of items.

Unless I'm using a class style enum, I tend to drop a little 'e' in front of enumeration types.  I.e. enum Blargo {eFail} versus enum class Blargo {Fail}.

 

The point of listing this is to reinforce what others have said: while the class names themselves have moved along, there are still reasons to for similar practices in other areas of the language.  So long as you come up with a consistent set of rules, you can write clean code.


In Topic: responsiveness of main game loop designs

25 May 2016 - 06:05 PM

While I agree that you are overthinking this, there is also a gross simplification you are making.  Even if you follow your intention of limiting things to input then immediately render, that won't make the game feel responsive.  The key word is 'feel', it's not about absolute numbers here, it is about perception.  Even the most twitchy of games is not able to apply input immediately, it is often several frames later.  The difference between feeling responsive and the latency issues some games have is in application.  Basically the trick is *not* to act immediately but to buffer just enough such that all input is equally latent.  The human mind is a masterful computation device, without knowing it, the player will adapt to slight amounts of latency.  If that latency is bouncing all over the place, the player can not adapt, if it is consistent on the other hand, the player will generally not notice.

 

If things were about the absolute latency, games would never have been able to survive triple buffering, remote streaming etc.  Those things seem to work (ok, streaming not so well yet) and the reason is generally that folks put the time to smooth the latency, not try and remove it completely.


In Topic: when to use concurrency in video games

14 May 2016 - 11:44 PM

 

*except on some MS compilers, where on x86, volatile reads/writes are generated using the LOCK instruction prefix

 
MS doesn't use the LOCK instruction for volatile reads and writes. LOCK would provide sequential consistency, but MS volatile only guarantees acquire/release. On x86, reads naturally have acquire semantics and writes naturally have release semantics (assuming they're not non-temporal). The MS volatile just ensures that the compiler doesn't re-order or optimize out instructions in a way that would violate the acquire/release semantics.

Yeah, you're right - I've struck that bit out in my above post. From memory I thought that they'd gone as far as basically using their Interlocked* intrinsics silently on volatile integers, but it's a lot weaker than that. I even just gave it a go in my compiler and couldn't get it to emit a LOCK prefix except when calling InterlockedCompareExchange/InterlockedIncrement manually :)

 

This means that even with MS's stricter form of volatile, it would be very hard to use them to write correct inter-thread synchronization (i.e. you should still only see them deep in the guts of synchronization primitives, and not in user code).

 

 

As a general note involving the volatiles, I also went and did a test for fun.  I took the scheduler for my distribution system and added a single volatile to the head index of the lazy ring buffer.  I changed nothing else, I'm still using explicit atomic load/store to access it.  It slowed down the loop by about 10%.  That's quite a bit worse than my worst guess.  This was on a dual Xeon and compiled by Clang, I'd be terrified to see what happens with the MS hackery on volatiles.  As a note: there is an option in VC2015 to disable the MS specific behavior now I believe, so it may not be any worse than Clang with that set.

 

As to volatiles and threading in general, I don't believe I use the keyword volatile anywhere in my code, both home and work, and it is fully multi-core from the ground up.  Unlike what I called out above, I'm not using it just to ship, it is a fundamental design goal of the overall architecture.


In Topic: when to use concurrency in video games

13 May 2016 - 12:25 PM

I think one key point is being glossed over in regards to the when portion of the question... When do you use concurrency? "Only when you need it to ship!"  I have shipped many games where I've added threading engines but only bothered to port bits and pieces of code to the parallel models to hit a solid 60FPS with a little headroom.  I just wanted to point this out as it seemed to be getting glossed over in the 'shiny' reasons you do concurrency.. :)


In Topic: How do I design this kind of feature?

08 May 2016 - 06:32 AM

 

There is another manner to look at this which may be a variation of haegarr's response.  ...

Yes, that is definitely what I meant except that you're going the refactoring way (which, of course, is totally fine) where I already have been trapped once back in time and hence know of that particular necessity we're talking about here.

 

Interestingly enough, there is many good stuff to learn from TA / IF engines, where the interaction of the player is focused on performing such kind of actions.

 

 

My primary motivation for separation of usable from use in this case is that the results can now be exposed to script systems considerably easier.  I generally dump most of these items into a behavior tree since the simple 'use a key' example can be extended to include a lot more checks and becomes the basis of a puzzle system also.  I.e.:

 

sequence

-  haveItem(key, "Some door")

-  haveItem(scroll, "Nasty Green Ritual")

-  isDay("Tuesday")

-  isHour("Noon")

-  actorInVicinity(Player, "Nasty Green Altar", 5)

-  actorHasPerformed(Player, "Sacrifice", "Chicken Feet")

-  makeActionAvailable("Trigger Nasty Green Apocalypse")

 

Now the player can destroy the world by reusing prior work.  With enough generic actions, even the final line can be pushed off to script such that none of this requires custom code.  Maybe the OP is not making a game with puzzles, maybe he is, either way though fixing SRP allows throwing this stuff in script where it is easier to reconfigure and experiment.


PARTNERS