Decoupling in games is one of those things that is incredibly hard to get right. I cannot count the one of times I have ended up with giant bowl of spaghetti code. If anyone can recommend some material on this subject, please do not hesitate to share it
If you haven't done so already, I would recommend trying to create a sample game with an ECS framework. It was genuinely a game changing (snicker) idea for me, as I had never really understood how far Composition Over Inheritance could be taken.
The author seems to be amused by ECS idea in general and doesn't go too deep into the questions surrounding it (like, safe parallel processing of systems). I wonder what are these 25 scrapped designs/architectures that they tried...
Systems operating on the same frame can run in parallel with a simple double buffering scheme. That is, have two copies of the game state: one "current" and one "next"; and all updates go to the "next" copy. After the current frame is rendered, the buffers switch roles: next becomes the new current and current becomes the new next.
That way, the "current" view of the game state never changes and multiple threads can work with it in parallel. Race conditions may still occur if multiple systems update the same bit of data in "next" but if your systems are well divided then this is unlikely or irrelevant and may be mitigated using locks with far less resource contention than everybody updating the same state vector they're reading.
Double buffering is easy to do in an ECS; not so much with the time-honored LOO (List of Objects) architecture.
Naughty Dog also presented some stuff at GDC this year wrt. parallelizing their game-engine using "fibers"[0]. It sounded a lot like present implementations of co-routines with some hardware support for swapping stacks around to different cores on the PS4 processor.
It appears that such a design could mitigate most resource sharing issues with traditional threads.
I call this the "blackboard architecture". Not only is it great for locality of reference (and therefore easy on your data cache), but game state can be easily serialized, deserialized, and double buffered.
I freakin' love stationery. If I had the money I would join a stationery subscription club similar to Candy Japan. It wouldn't have to be exotic Japanese stationery - just very good and interesting bits and pieces from around the world.
I freakin' love stationery. If I had the money I would join a stationery subscription club similar to Candy Japan
I sometimes wonder why I don't just have my paycheck direct-deposited to Jetpens, especially since I moved to CA and get next day delivery from their San Jose warehouse.
At one point I started one called Pen Japan and soon realized I don't have a passion for stationery or know anything about it. So at the very least I would need someone else do the curating.
It's similar, but not quite the same. The built-in components work like this (although I'm not deeply knowledgeable of Unity internals or anything, just have been working with it for a few years).
But any game-specific logic written by a developer, while technically using the same component system, is usually written from an individual scene object's perspective rather than from a "system processing components associated with various game objects in bulk" perspective.
You can still write code that looks like a system, but the framework really encourages you to attach those scripts to scene objects, so you end up basing a lot of logic around the structure of the game object hierarchy.
(The alternative to putting a script on a game object is to have one Master script of a scene that delegates updates to several subsystems, but you lose the benefit of things such as disabling a gameobject while the scene is running to temporarily disable a system.)
For instance, you'll see a lot of addons (example Fabric: http://www.tazman-audio.co.uk/?page_id=73#! ) that use prefabs to create hierarchical data even when it's not necessarily appropriate. But it's the path of least resistance.
When you go to implement gameplay logic, you're usually not writing systems as rasmusrn describes, you're writing behavior scripts on the roots of game objects hierarchies (not unlike Actors as you'd see in Unreal and other game engines).
Trying to make a bunch of click-together MonoBehaviours usually makes a mess.
These slides give a good overview of generally good ways to not shoot yourself in the foot in Unity, and it mentions this actor-ish approach: http://slides.com/cratesmith/how-to-use-unity#/
The hope (or at least my hope after working with Unity for a while) with the design rasmusrn is using is that composing per-entity data is more flexible than composing per-entity behavior.
So Unity in general hasn't a good design overall? I mean on the development perspective, and UE its much free of those kind of design pattern seems, didn't know exactly how it works either, so you can adopt the pattern that fits better with you, without issues.
17 comments
[ 2.7 ms ] story [ 53.6 ms ] thread1) https://molecularmusings.wordpress.com/ 2) http://bitsquid.blogspot.com/ 3) http://gamesfromwithin.com/
They can feel a little esoteric but there's a lot of golden nuggets if you're willing to dig a little.
Also, check out this book by Jason Gregory: http://www.gameenginebook.com/
I wrote it specifically to deal with this exact problem.
That way, the "current" view of the game state never changes and multiple threads can work with it in parallel. Race conditions may still occur if multiple systems update the same bit of data in "next" but if your systems are well divided then this is unlikely or irrelevant and may be mitigated using locks with far less resource contention than everybody updating the same state vector they're reading.
Double buffering is easy to do in an ECS; not so much with the time-honored LOO (List of Objects) architecture.
It appears that such a design could mitigate most resource sharing issues with traditional threads.
[0] http://gdcvault.com/play/1022186/Parallelizing-the-Naughty-D...
What type of eraser is that on the end of your pencil? Someone mentioned it might be a kneaded rubber eraser that you sorta just molded on.
re: http://www.bonsai7.dk/assets/images/coffee-shop-work.jpg
I don't know what it is called. It was just mounted on top of the pencil when I bought it. Like a little hat. It works great. Have a look.
http://www.bonsai7.dk/assets/images/pencil-eraser.jpg
http://www.faber-castell.co.uk/products/more-products/eraser...
http://www.tigerpens.co.uk/faber-castell-grip-2001-eraser-ca...
I freakin' love stationery. If I had the money I would join a stationery subscription club similar to Candy Japan. It wouldn't have to be exotic Japanese stationery - just very good and interesting bits and pieces from around the world.
I sometimes wonder why I don't just have my paycheck direct-deposited to Jetpens, especially since I moved to CA and get next day delivery from their San Jose warehouse.
But any game-specific logic written by a developer, while technically using the same component system, is usually written from an individual scene object's perspective rather than from a "system processing components associated with various game objects in bulk" perspective.
You can still write code that looks like a system, but the framework really encourages you to attach those scripts to scene objects, so you end up basing a lot of logic around the structure of the game object hierarchy.
(The alternative to putting a script on a game object is to have one Master script of a scene that delegates updates to several subsystems, but you lose the benefit of things such as disabling a gameobject while the scene is running to temporarily disable a system.)
For instance, you'll see a lot of addons (example Fabric: http://www.tazman-audio.co.uk/?page_id=73#! ) that use prefabs to create hierarchical data even when it's not necessarily appropriate. But it's the path of least resistance.
When you go to implement gameplay logic, you're usually not writing systems as rasmusrn describes, you're writing behavior scripts on the roots of game objects hierarchies (not unlike Actors as you'd see in Unreal and other game engines).
Trying to make a bunch of click-together MonoBehaviours usually makes a mess.
These slides give a good overview of generally good ways to not shoot yourself in the foot in Unity, and it mentions this actor-ish approach: http://slides.com/cratesmith/how-to-use-unity#/
The hope (or at least my hope after working with Unity for a while) with the design rasmusrn is using is that composing per-entity data is more flexible than composing per-entity behavior.