State Changes in a Component Based Architecture [closed]
- by Maxem
I'm currently working on a game and using the naive component based architecture thingie (Entities are a bag of components, entity.Update() calls Update on each updateable component),
while the addition of new features is really simple, it makes a few things really difficult: a) multithreading / currency b) networking c) unit testing.
Multithreading / Concurrency is difficult because I basically have to
do poor mans concurrency (running the entity updates in separate
threads while locking only stuff that crashes (like lists) and
ignoring the staleness of read state (some states are already
updated, others aren't))
Networking: There are no explicit state changes that I could
efficiently push over the net.
Unit testing: All updates may or may not conflict, so automated
testing is at least awkward.
I was thinking about these issues a bit and would like your input on these changes / idea:
Switch from the naive cba to a cba with sub systems that work on
lists of components
Make all state changes explicit
Combine 1 and 2 :p
Example world update:
statePostProcessing.Wait() // ensure that post processing has finished
Apply(postProcessedState)
state = new StateBag()
Concurrently(
() => LifeCycleSubSystem.Update(state), // populates the state bag
() => MovementSubSystem.Update(state), // populates the state bag
....
})
statePostProcessing = Future(() => PostProcess(state))
statePostProcessing.Start()
// Tick is finished, the post processing happens in the background
So basically the changes are (consistently) based on the data for the last tick; the post processing can a) generate network packages and b) fix conflicts / remove useless changes (example: entity has been destroyed - ignore movement etc.).
EDIT: To clarify the granularity of the state changes:
If I save these post processed state bags and apply them to an empty world, I see exactly what has happened in the game these state bags originated from - "Free" replay capability.
EDIT2: I guess I should have used the term Event instead of State Change and point out that I kind of want to use the Event Sourcing pattern