Back to list

Modding ECS in Gamecraft

Gamecraft is built on an entity component system created by FreeJam's CTO called Svelto.ECS, which is a quite powerful piece of open-source software. The ECS paradigm is a relatively novel programming concept, but many frameworks exist including one made by the Unity Engine devs specifically for their engine called UECS. ECS is a data-oriented system which uses "entities" instead of "objects" from object-oriented programming. An entity is comprised of independent components which act like individual properties for an object in OOP. All of the components are stored in some sort of fast in-memory database (Svelto.ECS uses a Dictionary). What makes ECS great is that it's fast, since the computer only needs to worry about the component in cache instead of the entire object, and it makes the code easier to maintain, since you can add a new component to an existing entity without touching other components in the same entity.

ECS is great, but it can be a lot to wrap your head around. I've found that the best way to understand it is to jump in, swear at your computer a bit, and slowly accept it for what it is. A lot of material I've seen says that ECS is really only practical for games, but the idea of data-oriented design is a universal concept. Data-oriented programs are the future, since big data and machine learning are focused on number-crunching. So if you need a reason to persevere through your ECS learning, think of that. Unfortunately, ECS is unlikely to be the way to get there, but it is the way to make a (good) modern game. And Gamecraft is one of those modern good games... well at least it uses ECS.

Gamecraft is FreeJam's first completely ECS-based game. Robocraft and CardLife both used Svelto.ECS as well, but the game logic wasn't completely reliant on it. Because all of Gamecraft's data is handled by Svelto.ECS, it's easier to mod than CardLife and Robocraft (or so I'd imagine, I've never tried). The biggest hurdle is to get access to the database containing all of the entity components. Luckily, Svelto.ECS will automatically provide that database to engines, the logic and behaviour implementors in Svelto.ECS. In Gamecraft, engines are usually registered during the "compose" stage, which occurs in loading screens or when switching gamemode. I think of the compose stage as when the composer taps his baton on the stand in front of him, right after the musicians have walked on stage and sat down (init stage) and right before the music starts playing (gameplay stage). Registering an engine to Svelto.ECS is made quite trivial by Harmony, which can intercept a method call and its parameters to allow you to perform your own operations. Specifically, all of the compose methods in Gamecraft get passed a Svelto.ECS EngineRoots object, which is how Gamecraft (and now me) registers engines to operate on entity components.

In the interest of not getting sued for reverse-engineering Gamecraft or divulging company secrets, I won't go into much more detail (although they're not very good company secrets if me, a person living on a different continent, working for a different company, figured them out in my spare time). You can find out more details about Gamecraft by using a C# decompiler to view the original code, no reverse-engineering required. By the way, reverse-engineering is usually legal anyway. Of course, I'm not a lawyer, and I don't like closed-source software that much so I'm a bit biased. Interestingly, the European laws about software protection seem to explicitly allow external mods and servers (you can tell I'm still a bit annoyed about RC14 getting shutdown). Regardless, FreeJam seems to be ok with the unofficial Gamecraft mods that have been created so far, so I wouldn't expect them to suddenly change their stance on mods in the near future.

The GamecraftModdingAPI is probably the best example of modding with ECS. It provides a friendly object-oriented API for developers who want simplicity. For developers who want performance or understand the ECS paradigm, the modding API offers an easy way to register engines, so that Harmony isn't even required in the process of getting the entities database for modding entity components. As a major contributor to the GamecraftModdingAPI, I've seen how ECS has simplified modding. One of Svelto.ECS's primary focuses is code maintainability, which is very obvious whenever Gamecraft is updated. The average Gamecraft update breaks one or two parts of the API, and that's usually only caused by one or two variables changing name or location. I'd bet that if half of Gamecraft were rewritten, the biggest fix that the GamecraftModdingAPI would need would be changing the name of the components the API queries. The focus on maintainability doesn't just make Gamecraft easier to develop, it also makes mods easier.

The data-oriented design of ECS helps as well. The object-oriented API in the GamecraftModdingAPI still queries entity components behind-the-scenes, so even OOP can take advantage of ECS design, albeit with some drawbacks. The database system in Svelto.ECS purposely allows for new entities to be created but not made queriable immediately for some deterministic reason. If a new entity is created as an object through the object-oriented API, the GamecraftModdingAPI has to force the database to sync new entities before any of the object's properties can be accessed. This database sync operation is a lot of unnecessary overhead which could be avoided with pure ECS. Pure ECS modding is easy, since almost every operation can be accomplished by operating on one or more entity components in the entity database. In Gamecraft's case, there's never more than one entity database on the go at once, which makes modding easy with a single point of contact. Once you've got the active entities database, you've basically completely pwned Gamecraft.

A year ago, I thought ECS was a fancy niche concept which would be worthless for me to learn. It may still be worthless for my job, but it's a vital part of Gamecraft and mods that I wouldn't pass up. I wonder when FreeJam will give us an official modding API for interacting with Svelto.ECS...