Many people ask, how can we empower designers to design levels while we (developers) are using Entitas.
I am sorry, but in order to answer this question I have to get all philosophical.
The main idea behind Entitas is separation of state and behaviour. State is basically data representation, so I would like to use this two terms interchangeable.
What kind of data do we have in games?
We can divide data into three categories.
- Configuration. This is „fixed“ data which developers/designers define.
- Player state, represents players progression through multiple previous sessions.
- Runtime data. Runtime data is the result of game being played in current session.
When we start a game (or a level) we take configuration and player state turn it into runtime data which than will be transformed by game logic (simulation).
Entitas is designed to represent runtime data as entities and game logic as a chain of systems.
If we want to empower designers to be able to try out different things in the game, we have to define expressive configurations.
How do we define them?
This is pretty much dependent on what kind of tool your designer is comfortable with.
Most of the designers that I know, love spreadsheets. However I also worked only on simulation games. In other games, where you need more of the spacial definition of the level, you need better tools. And as a matter of fact, Unity Editor itself, by providing us with a possibility to create prefabs, is such a tool. If we think about it, Unity prefabs and Unity scenes are just configuration files. When we hit play, Unity will transform this configuration into runtime data and mono behaviours will start acting on this runtime data.
By using Entitas, we create parallel runtime data. Mostly because we want to decouple visual data from logical. However we want to have links between those two state representations. To be able to achieve this, we can create components which have a GameObject field. And mono behaviour which has an Entity public field.
In order to link entities with game objects we have two options:
- If the game object is part of the scene which is already loaded, we can create or find an entity we want it to be linked with, than query for the game object in the scene and connect them by adding a component with a GameObject field in it.
- A more cleaner way (in my opinion) is when we have an entity which represents something in the game and we have to add a game object to the scene in order to display it. In this case we just have to instantiate a game object from a prefab and connect game object with entity.
I would like to point out one more thing.
A careful reader might noticed that I wrote configuration is „fixed“ data. I put the word fixed in quotes. I did it on purpose because configurations are not always fixed. Some times designers might want to change them even when the game is already rolled out. A designer might even want the configuration to be changed for a random amount of users. This technique is called A/B Testing.
This is why having a configuration as a JSON or XML file downloadable from a server is a good idea. I am not sure how easy it is to make prefabs support A/B Testing.
Therefor I want to propose following solution. Have a separate scene for game designers where they can place game objects, balance the data, but than have a „generate config“ button so that the data is not captured as a prefab, but a simpler representation that you can use for A/B Testing.