Before making Kaban Engine public, I started reworking the asset system. What was supposed to be a small, focused change turned into a larger cleanup pass, because once I touched it, several weak spots became obvious.
The original goal was simple: end up with a built asset file that the game can load quickly and query efficiently. That meant tightening definitions, removing ambiguity, and enforcing rules.
Tags
The first thing I tackled was the tag system.
Previously, tags existed in a more loosely defined form. Editing worked, but the internal representation wasn’t clean, and relationships between assets and tags were harder to reason about than they should be. I already wrote about the old system in earlier posts, where tags were functional but lacked a rigid structure that would scale well as the engine grew.
The new direction is intentionally simple. Each tag is represented by two strings: a key and a value. A GUID is generated from the key itself, and each value also gets its own GUID generated from the concatenation of the key and that value. This removes ambiguity, makes tags deterministic, and allows them to be sorted, indexed, and versioned reliably.
Asset GUIDs
The second step was asset identification.
Each asset now receives a 64-bit GUID generated from its source file name, along with any additional source extensions if the asset is composed of multiple inputs. If the source is the same, the GUID is guaranteed to be the same. There is no runtime randomness and no dependency on build order. This decision later eliminated several problems related to asset references and build ordering that existed in the old system.
Nuklear Integration Cleanup
While working on the asset system, I also reworked the Nuklear integration.
Previously, Nuklear lived entirely inside win32_engine, the platform layer. That layer owned the implementation, created the context, handled rendering, and exposed functionality to the engine through a large table of function pointers. It worked, but it was fragile and unnecessarily complex.
The new setup compiles Nuklear as a static library and links it into both win32_engine.exe and engine.dll. The platform layer still creates the nk_context, processes input, and performs rendering, but the massive pointer table is gone. Functionally, nothing changed. Architecturally, a large amount of code disappeared, which is usually a good sign.
Making Versioning Explicit
Version control was another area that needed attention. It existed before, but it was vague and difficult to reason about. I replaced implicit assumptions with explicit rules.
When the engine starts, it first loads editor_meta.json. This file contains the version of the KESA (Kaban Engine Stored Asset file) that should be loaded. If the file does not exist, the engine creates a new one using that version. By default, the version is [0, 0, 0, 0].
Once KESA is loaded, the engine reads its header to determine which KET (Kaban Engine Tag file) version to load. The .ket file contains all user-defined tags created during asset editing. Internally, it stores a kea_tag_map structure that includes the tag GUID generated from the key, the key string itself, an array of values, and a corresponding array of GUIDs generated from each key + value pair.
After the KET file is loaded, the user can edit assets, create new tags, and modify existing metadata.
At that point, the user can choose to build the KEA (Kaban Engine Asset file). KEA is the finalized asset file that the game and its tools will consume. KEA also has a version, and this version must exactly match the KESA version it was built from. This restriction is intentional and enforced.
I also spent some time thinking about a KEWM (Kaban Engine World Map) format, which would represent a game environment. I decided not to implement it. World formats are inherently game-specific; they depend on gameplay rules, entity logic, and simulation models. As a result, world files should be produced by game-specific tools, not by the engine itself. What will remain is the requirement that a world file stores the version of the KEA it was created with.
Why I’m Not Building a General-Purpose Engine
During this process, I realized I was drifting toward building a general-purpose game engine—something closer to Godot or Unity. That path is possible, but it requires a massive investment in tooling, abstraction, and long-term maintenance.
That was never the original goal.
This project started as a way to make a game. Making the engine public shifted my attention toward infrastructure that, while interesting, does not actually matter for finishing a game. So I changed direction.
The engine will provide essential systems and act more like a library or a starting point than a fully abstracted framework. Everything else becomes game-specific. If a game needs a tilemap, I will implement a tilemap. If it needs a specific entity update model, I will implement that model. If it needs custom tools, those tools will be written for that game.
This approach assumes that the person using the engine understands C/C++ and how the engine works internally. For a personal project that is not intended to be a general-audience engine, that is an acceptable tradeoff.
What’s Next
With that clarified, I’m moving on to an actual game.
I’m starting work on Arkham Horror, a card game that does not have an electronic version. The plan is to implement only a core set, including three scenarios and a small selection of investigators. The goal is not completeness or commercial viability, but to explore how a complex rules-driven game fits into the engine and to identify where the current architecture holds up or falls apart.
This project is purely for fun. I have no intention of profiting from it.
I didn’t go into detail about the asset system implementation itself because it is not finished yet. Once it is, I will write a dedicated post focused entirely on that.
That’s where things stand right now.