Tag: ecs

  • The Engine Legacy: From Asteroids to rpgCore

    The Engine Legacy: From Asteroids to rpgCore

    At some point I stopped counting how many times I’d written the same movement system.

    It wasn’t any one project’s fault. Every game had its own physics, its own collision logic, its own state management — each a reasonable decision in isolation, collectively a pattern I was tired of repeating. The tenth time you write an entity update loop you start asking a different question: not “how do I build this game” but “what would make the next one easier to start.”


    rpgCore started as a refactoring project and became something else entirely.

    The idea was simple: extract the patterns that kept repeating and build a reusable toolkit. A simplified Entity-Component-System in Python — modular enough that adding a genetics system didn’t require touching the movement code, adding a lifecycle system didn’t require touching the genetics code. Each piece independent, each piece composable.

    Simple ideas scale badly. The toolkit grew. A thousand tests. Then eleven hundred. GeneticsComponent. LifecycleComponent. DispatchSystem. ResourceFlow. A scene system, a UI theme, a demo registry. At some point it stopped being a toolkit and started being a codebase worth protecting.


    The mistake I kept almost making was treating rpgCore as a means to an end. It isn’t. The foundation is the thing.

    When you build something generic enough to support any idea, you start seeing which ideas are worth having. The genetics system in rpgCore is the same system that ran TurboShells’ turtle breeding. The dispatch pattern is the same one VoidDrift’s Scout drones use. The resource flow is the same loop that appears in SlimeGarden. rpgCore didn’t just save me from rewriting code — it made the pattern visible, and once the pattern is visible you can apply it deliberately.

    The 1,122 tests aren’t there because I’m disciplined. They’re there because a foundation without verification isn’t a foundation, it’s a guess.


    The BreedingSystem is still queued. Allele resolution, trait inheritance, phenotype expression from genotype. When it ships it connects to every genetics-adjacent idea I’ve had since TurboShells. ConquestSystem is queued behind it.

    rpgCore doesn’t ship. It makes shipping possible.

    That’s a slower kind of value than a finished game. It’s also the only kind that compounds.

  • Building rpgCore: Cross-Language Architecture for Multi-Genre Games

    Building rpgCore: One Engine, Four Genres

    The original ambition was simple: build something that didn’t need to be rebuilt every time an idea changed direction.

    The execution was not simple.


    rpgCore went through a phase that most solo projects don’t survive. Godot C# bridges wired to Python servers via IPC. Rust DLL experiments. Terminal rendering adapters. A cinematic simulator. A vector space battle engine. Dozens of game concepts running in parallel, each pulling the codebase in a different direction. At some point there were more than 60 test files archived as referencing modules that no longer existed.

    The project had discovered everything it didn’t want to be.

    The Architectural Singularity refactoring pulled 21,000+ items into a legacy vault — not deleted, preserved — and left behind something clean: a pure Python engine, pygame for rendering, a single command to run any of four distinct games.


    The Orange Box was Valve’s 2007 bundle that shipped Half-Life 2, Portal, and Team Fortress 2 together. Three completely different genres, one release. The concept that stuck with me wasn’t the games — it was that the same underlying systems could drive experiences that felt nothing alike.

    rpgCore now ships four built-in games testing the limits of the shared architecture:

    Slime Clan — turn-based faction strategy. Grid simulation, overworld nodes, automated battle resolution. The engine’s systems thinking expressed as territory and conflict.

    Last Appointment — narrative dialogue. You are Death. Your client has questions. Dialogue trees, dynamic UI card layouts, complex state across conversational nodes. No combat. No score.

    TurboShells — breeding and racing simulation. Deep genetics, time progression, legacy management across generations of turtles.

    Asteroids Roguelike — real-time action. The same engine’s high-performance rendering and physics under pressure.

    The Constitution Law: nothing is built twice, and demos never reimplement shared engine systems. If a system exists in src/shared/, it belongs to all four games.

    296 tests enforcing it.


    The cross-language experiments are archived, not deleted. The Godot C# bridge that drove a Python core via WebSocket is documented as the blueprint for any future migration away from pygame. The Rust performance harness is there for the day it matters. Nothing was thrown away — it’s in cold storage, preserved as evidence of what was tried.

    The lesson from the Architectural Singularity isn’t “don’t experiment.” It’s “know when the experiment phase is over.” The 21,000 archived items are the proof of work that made the current clean state possible.

    A sprawling codebase that tried everything became an engine that does four distinct things well, from one shared foundation.

    That was the point from the beginning. It just took a while to get there.