RFDGameStudio
The Idea
Most game engines are built for one game. The engine I wanted to build is a studio � a set of shared primitives that compounds across games rather than getting rewritten from scratch every time.
RFDGameStudio is four complete games sharing one engine. Every mechanic that survives production in one game gets promoted to a primitive available to all games that come after.
The Four Games
Horse Racing Sim � Discrete event engine. Horses have genetics, form, and career stats. You bet, breed, and build a stable. Tests the Port-Engine pattern: pure Lua logic exposed as a clean API that both TypeScript and PyGame consume identically.
Slither Rogue � Real-time snake roguelike with evolution cards. Collision detection, real-time tick loop, emergent power systems. Tests the real-time physics primitive at speed.
Mutant Battle Ball � 2v2 possession-based combat sport. Mutants have parts (head, chest, arms, legs) that drive stats and visual appearance. Tests the possession system, AI role assignment, and composite figure rendering.
SlimeCoin � Coin-pusher roguelike with a token economy. Three physics layers (shelf, floor, vat), pairwise chip synergies, a shot queue, and a mid-round exchange system. Directly inspired by Raccoin. Tests economy loops and physics simulation.
The Engine
The stack is deliberately minimal:
data.yaml -- entity definitions, config, opponent data
logic.lua -- game simulation (runs identically everywhere)
TypeScript -- browser renderer (Vite + React)
PyGame -- desktop renderer (same logic.lua, different canvas)
Lua was chosen because it runs in both environments without modification. The same tick_game(dt, input) call that drives the browser also drives PyGame. The renderers are interchangeable. The logic is never duplicated.
Shared primitives in engine/primitives/:
movement.lua� vector math, move_toward, atan2physics.lua� grid collision, wall bounce, coin physicsaction.lua� input handling, collect() for Lua/Python bridgingresolution.lua� weighted outcomes, affinity scoringlifecycle.lua� entity lifecycle event constants
Each primitive was extracted when the same logic appeared in two or more games. Nothing was abstracted speculatively.
The Methodology
Every feature starts as a directive:
- Scope defined � files listed, read-only files named explicitly
- Test anchors written � behavior specified before implementation
- Agent implements
- Floor verified � raw pytest output only, never agent summaries
- Phase certified � floor locked, next phase begins
Current certified floors: 86 passed, 0 failed (Python) and 39 passed, 0 failed (TypeScript).
No phase advances without a passing floor. No exceptions.
The MCP Server
RFDStudioMCP runs as an NSSM service with 11 tools for live game inspection:
studio_load_game� load any game by IDstudio_get_state� inspect live GAME_STATEstudio_call� call any Lua function directlystudio_screenshot� render a frame and return PNGstudio_run_tests� run the full test suitestudio_balance_report� simulate N races, return win distribution
The studio is designed to be interrogated, not just played.
Coming to The Arcade
All four games will be playable in the browser. The Vite build produces a static dist/ that deploys to The Arcade. PyGame ports serve as the desktop and development renderer.
GitHub: RFDGameStudio
Built with Lua, TypeScript, and Python. Four games, one engine. The engine is the point.