Building my own gamedev tools and utilities, from the start, for the future
When I started my gamedev journey at the beginning of the previous year, one important objective in mind was to work in building a set of tools and utilities while developing each minigame, prototype, experience, etc, to be used for the next ones, and so on.
For that purpose I created an open source repo named Unity Gemserk Utilities (Gemserk was my previous blog/company name, might rename to Pixel Core Utilities in the future?). This repo consist in a set of projects with different levels of abstraction and for various usages.
This set of projects is meant to be used mainly by me and for my own games but there are some useful things that could be handy for someone else and that is why I prefer to have it open source, just in case I want to share something, it is just there.
In fact, when I started working in Cleared Hot, at the end of the last year, we decided to integrate and use some of these projects. That allows me to adapt, abstract, and improve those projects by using them in different contexts and by getting feedback from other developers.
Unity Triggers’ Logic
The main project we are using is named Unity Triggers’ Logic and it is heavily inspired by the Starcraft2 Editor. Triggers are a set of Events, Conditions and Actions and when one of the Events is triggered, a set of Conditions is evaluated if all of them pass then a list of Actions is executed. We used something pretty similar for Iron Marines and Iron Marines 2, and I wrote about that in the Gemserk devblog.
A pseudo example:
When Unit1 Enters Area3,
if
Unit1 IsAlive
and
Unit1 HasWeapons
Spawn GroupOfEnemies1
Move Camera to Area3
Here is a screenshot of how triggers look in the SC2 Editor:
The implementation for this over Unity uses GameObjects and MonoBehaviours and is pretty simple.
The core is simple, the main idea with this system is the custom events, conditions and actions you implement for the game you are making, and from Cleared Hot we already have a lot of them, some for development, some for testing, and most of them for the logic of the levels. Here is an example of a work in progress mission:
One interesting thing is, since they are GameObjects, we can use them as prefabs too. This comes with all the normal prefab features, for example, prefab instance modifications, prefab variants, nested prefabs and reuse the same prefab in different scenes, etc.
Some of the generic elements we created in Cleared Hot, for example a condition to check if an GameObject has a tag or not, could be integrated in the core project to make them useful for more people and/or for our own projects in the future.
Common Utilities
The other one we are using in Cleared Hot and Ship Miner is the Unity Utilities project. It contains several utilities but one that I like a lot is the Object picker, a c# attribute and a custom editor window that in combination allow the selection of Objects (GameObjects or Assets), from scene or from assets folder, implementing some API, in the case of GameObjects it looks for at least one MonoBehaviour implementing it, in the case of assets it checks for implementing the API directly.
[ObjectType(typeof(IEntityDefinition), disableAssetReferences = false)]
public Object entityArchetype;
To then use the Object reference, there is a useful extension method to get the API from it:
public static T GetInterface<T>(this UnityEngine.Object obj) where T : class
{
if (!obj)
return null;
if (obj is T t)
return t;
if (obj is GameObject go)
return go.GetComponentInChildren<T>();
if (obj is Component component)
return component.GetComponentInChildren<T>();
return null;
}
This works with any interface or class.
In the case of my games there is a concept for entity archetypes named EntityDefinition used when creating new entities in the ECS system (might be an interesting topic to talk in another blog post).
In the case of Cleared Hot, we have a concept named Spawnable which is a combination of a prefab we want to spawn and some configuration override. We use this to abstract how to override values for different unit prefab structures (an NPC is pretty different to a vehicle). For example, we want to spawn an enemy NPC with a rocket launcher, it is the same prefab, we just spawn it and override the weapon, instead of having a prefab variant of an expensive prefab with only 1 value changed.
The important conclusion here is that keeping the objective of working in those projects all the time pays for itself in middle to long term, and the effort of maintaining those projects start to decrease over time while the value increases. In some way it feels like I am building something bigger than just one thing.
That’s all for now, just wanted to do a simple blog post with a bit of technical content since I didn’t do that for a while and I was missing it.
Thanks for reading!!