Kang's Carts (Game and Tools)
Kang's Carts is a 2D action platform reminiscent of the "mine cart" levels in Donkey Kong Country for the SNES. The game uses 3D character models exported to 2D flipbook animations.
Game systems
- Splines/physics (physics vs manual control) As a spline heavy game, the Unity splines package was used as a base for spline workflows, however modification/extension was needed for this package to support our use cases.
- Animation (frame selection logic across trajectory)
Engine andΒ workflow
For this project I teamed up with an artist and game designer, with me owning the tech. The game is built in Unity, with extensive tooling built into the game for us by the game designer. I opted for in-game tooling as opposed to leveraging Unity's extensible tools system for a few reasons:Β
- The game designer had no Unity experience.
- I wanted to leverage the advantage of run-time, on-device tools for faster prototyping and iteration.
- Wanting to avoid tying development so closely to proprietary Unity tech, as an engineer that works across engines, with some of these tools designed around cross-game re-usability.
In-game parameters
Similar to Unity's inspector flow, nearly every gameplay parameter is controllable from an in-game settings window.The settings panel comes in as a sidebar, with the gameplay area adjusted to a smaller viewport, allowing you to see the full game content while the sidebar is open, which is useful for tweaking camera options.
Level editor
A robust level editor was created for building and testing levels. The levels can be serialized to save and load from disk and passed back and forth between team mates.Β
All in-game objects can be added via the editor, with transform, rotation, scale, and similar controls available. Spline drawing tools are used to draw the Bezier curves that the player will ride on. An extendable LevelObject class was used for tracking game objects.
public class LevelObject
{
public Guid uuid;
public LevelObjectType type;
...
public virtual void Init(DataObject dataObj)
{
var prefab = PrefabManager.GetPrefab(dataObj.type));
obj = UnityEngine.Object.Instantiate(prefab);
...
ObjectManager.AddLevelObject(this);
}
public virtual void Destroy()
{
UnityEngine.Object.Destroy(obj);
}
public virtual void Tick() {}
}
public class CustomLevelObject : LevelObject
{
public override void Init(DataObject dataObj)
{
base.Init(saveData, worldCanvas);
// .. custom object logic
}
}
public class ObjectManager
{
...
public T GetObject<T>(Guid uuid) where T : LevelObject
{
var obj = objects[uuid];
if (obj == null) throw new NullReferenceException();
if (obj is T cast) return cast;
throw new InvalidCastException();
}
}
The editor includes basic quality of life features such as a windowing system, zoom/pan controls, undo/redo history, copy and paste, and an easy way to move back and forth from the editor to play testing. The undo/redo history is supported by making every action you can do in the editor reversible. This is done in a simple way via function pointers, uuid-based entity component system, and a fixed size circular buffer.
var historyItem = new HistoryItem
{
Type = HistoryItemType.DELETE,
Perform = () => Delete(obj.uuid),
Undo = () => Create(objData);
};
historyItem.Perform();
addToHistory(historyItem);
CI/CD
Automated build pipelines were created in GitHub Actions to build for various supported platforms. They included a version parameter to allow version tracking. The version entered here will apply to the level editor save data for easy tracking; there also is a version for the level data format, to better support tracking backwards compatibility across versions.

TODO Proceural track art?