Author: rdugger

  • 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.

  • Automating Most of My Job: I Didn’t Want to Babysit a Dialer Forever

    I Didn’t Want to Babysit a Dialer Forever

    The unglamorous version of data administration is a lot of watching. Watching a dialer load leads. Watching a queue fill and drain. Watching the same manual processes run the same way they’ve always run because no one has had time to change them.

    I didn’t want to do that indefinitely.


    The first experiments were messy. Early Google Gemini API calls combined with Python Selenium — browser automation that could handle the dialer interactions I was tired of doing myself. The code was fragile, the model was still finding its footing, and the results weren’t perfect. But they were good enough to prove something: the repetitive parts of this job could be handled by something that wasn’t me.

    That realization changed what I built next.


    The Telesero Balancer is the clearest example — a live system that handles the distribution logic I used to manage manually. Convoso tools that shave seconds off agent workflows at scale. Brownbook Tools for the data sourcing problem. External partnerships that bring in raw lead data without someone manually pulling it.

    None of these have a clean ROI number attached. I haven’t measured hours saved per week and multiplied by fifty-two. What I can say is that the class of work I was doing when I started — the babysitting — occupies a fraction of the same time, and what replaced it is more interesting.