My friend Alex sent this to me. It was kind of funny as I was talking to him about issues I’m facing considering how to do game abstraction in code and the stuff in the PDF is pretty much what I was ranting about.
Haskell was the reason for learning F#, for instance, as functional methods are increasingly relevant to modern CPUs.
Concurrency is an irritating problem even when you don’t have threads. AI / logic often has multiple concurrent states which need to work together and know about each other, yet you’re always trying to find ways to abstract it because they shouldn’t implicitly know about each other.
Example: An invulnerability timer that runs at the same time as your player logic. The timer internally modifies the player to flash, which could be a problem if any other state needs to change the brightness for some other effect.
- States could know deep info about each other, telling the other to turn off the effect when necessary.
- Move the logic to parent code (such as the Player class) which plays the effect based on states it sees running. This could lead to complex high level logic juggling lower level things around.
- FSMs / Classes could use messaging to communicate 'pauseCurrentAlphaEffects'. Helps the architecture but still has vague concurrency threats.
- Effect class which exposes functions such as addEffect(priority, effectType). Exposure could be through delegates or just through being written as a child. The introduction of a separate system helps if it can automatically manage the problems of concurrency through priority. Your effect state could fall back to the previous state or a default when completed.
- Extract the flash functionality as a separately running functional element and place it in a slot in a generalized manager with type 'effectAlpha'. If you needed to you could add the concept of priority to each slot. This is like the effect class, but more extensible. My current preference.