HomeGamesUpdatesPricingMethodology
Steam News2 January 20251y ago

Diary Page #12: Systemic Architecture (Part 2)

Dear Scholars, Continuing where I left off in the first part, I would like to show you the building blocks of my new architecture and how it compares to the typical ways of working in the Unity engine.

In this update4

Full notes

Full Selenwald update

Read the full published notes in a cleaner layout. The original post stays linked below.

What changed

0 fixes2 additions5 changes0 removals
  • Performance
  • Gameplay
  • Maps
  • Balance
addedDear Scholars, Continuing where I left off in the first part , I would like to show you the building blocks of my new architecture and how it compares to the typical ways of working in the Unity engine.
changedInspirationmy past experience with Entity Component System (ECS) style framework ( Entitas , to be specific) which I had previously worked with on a different project,
addedNot ECSWhether you're familiar with ECS frameworks or not, I should make it clear that my architecture is not an ECS despite me using the terms "entity" and "system". They are just convenient names that I stuck with. One of the key distinctions is that my systems are a combination of systems and components known from ECS - they contain logic but also data. Thus, every entity that uses a specific system has its own instance of it. Also, the Entity class and System-derived classes are MonoBehaviour scripts attached to game objects which is still "the Unity way" adding logic to objects. This comes with some overhead and I have plans to make Systems regular classes instead of MonoBehaviours to make the game loop a little bit faster. However, it's not a high priority and it can easily be done in very late stages of development. That being said, I will never fully utilise the performance benefits that actual ECS frameworks are known for because—like I said—creating an ECS wasn't my goal here. I just borrowed some ideas from it.
changedEntityEvery object in the game is built of two things - the Entity class instance and a stack of ordered systems. The main purpose of the Entity class is to gather special events which are how systems communicate with each other in a decoupled way (without knowing about each other). An event might be something like having a collision with another entity, receiving damage, or triggering the action of picking an item up from the ground. What's important is that these events are actually just data containers with unique types.
changedThe System StackNow what actually happens during a frame? First take a look at this diagram showing the system stack on a timeline. Under the hood, each system type has an explicit order assigned. Bear in mind that the entities you can see here actually have much more systems but I skipped them to shorten and simplify the example.
changedThe System StackWhen a frame starts, the Entity class on each object in the game gets rid of the events from the previous frame and prepares events that were deliberately triggered by some systems in the previous frame to fire on the next frame (so the frame we're currently looking at).

Selenwald changes

addedDear Scholars, Continuing where I left off in the first part , I would like to show you the building blocks of my new architecture and how it compares to the typical ways of working in the Unity engine.
changedmy past experience with Entity Component System (ECS) style framework ( Entitas , to be specific) which I had previously worked with on a different project,
addedWhether you're familiar with ECS frameworks or not, I should make it clear that my architecture is not an ECS despite me using the terms "entity" and "system". They are just convenient names that I stuck with. One of the key distinctions is that my systems are a combination of systems and components known from ECS - they contain logic but also data. Thus, every entity that uses a specific system has its own instance of it. Also, the Entity class and System-derived classes are MonoBehaviour scripts attached to game objects which is still "the Unity way" adding logic to objects. This comes with some overhead and I have plans to make Systems regular classes instead of MonoBehaviours to make the game loop a little bit faster. However, it's not a high priority and it can easily be done in very late stages of development. That being said, I will never fully utilise the performance benefits that actual ECS frameworks are known for because—like I said—creating an ECS wasn't my goal here. I just borrowed some ideas from it.
changedEvery object in the game is built of two things - the Entity class instance and a stack of ordered systems. The main purpose of the Entity class is to gather special events which are how systems communicate with each other in a decoupled way (without knowing about each other). An event might be something like having a collision with another entity, receiving damage, or triggering the action of picking an item up from the ground. What's important is that these events are actually just data containers with unique types.
changedNow what actually happens during a frame? First take a look at this diagram showing the system stack on a timeline. Under the hood, each system type has an explicit order assigned. Bear in mind that the entities you can see here actually have much more systems but I skipped them to shorten and simplify the example.

Dear Scholars, Continuing where I left off in the first part, I would like to show you the building blocks of my new architecture and how it compares to the typical ways of working in the Unity engine.

Inspiration

The idea for how the code architecture in Selenwald is going to look didn't come out of nowhere. The biggest influences were:

my past experience with Entity Component System (ECS) style framework (Entitas, to be specific) which I had previously worked with on a different project,

Brian's Bucklew's talk on the systemic and data driven architecture used in Sproggiwood and Caves of Qud,

my own journey of gradually making Selenwald more and more data-driven (mostly through various ways of utilising Scriptable Objects, heavily influenced by Ryan Hipple's talk on this subject) throughout the recent years.

Not ECS

Whether you're familiar with ECS frameworks or not, I should make it clear that my architecture is not an ECS despite me using the terms "entity" and "system". They are just convenient names that I stuck with. One of the key distinctions is that my systems are a combination of systems and components known from ECS - they contain logic but also data. Thus, every entity that uses a specific system has its own instance of it. Also, the Entity class and System-derived classes are MonoBehaviour scripts attached to game objects which is still "the Unity way" adding logic to objects. This comes with some overhead and I have plans to make Systems regular classes instead of MonoBehaviours to make the game loop a little bit faster. However, it's not a high priority and it can easily be done in very late stages of development. That being said, I will never fully utilise the performance benefits that actual ECS frameworks are known for because—like I said—creating an ECS wasn't my goal here. I just borrowed some ideas from it.

Entity

Every object in the game is built of two things - the Entity class instance and a stack of ordered systems. The main purpose of the Entity class is to gather special events which are how systems communicate with each other in a decoupled way (without knowing about each other). An event might be something like having a collision with another entity, receiving damage, or triggering the action of picking an item up from the ground. What's important is that these events are actually just data containers with unique types.

The System Stack

Now what actually happens during a frame? First take a look at this diagram showing the system stack on a timeline. Under the hood, each system type has an explicit order assigned. Bear in mind that the entities you can see here actually have much more systems but I skipped them to shorten and simplify the example.

When a frame starts, the Entity class on each object in the game gets rid of the events from the previous frame and prepares events that were deliberately triggered by some systems in the previous frame to fire on the next frame (so the frame we're currently looking at).

Then, the system with the lowest execution order executes on all entities that have it. No events have been raised at this point yet (except for some exceptions like the deliberately deferred events I mentioned before) so these early systems usually raise their own events and process their internal data instead of reacting to events sent by other systems. An example of such a system is the Player Controls System. It

Source

Steam News / 2 January 2025

Open original post

Changelog.gg summarizes and formats this update. How we read updates.