Finding Your Core
'But my game is different' - what Core looks like across genres, from RPGs to physics puzzlers.
The Objection
After seeing the Architecture Model, a common reaction is:
“This makes sense for an RPG with stats and inventories. But my game is a physics sandbox / a rhythm game / a platformer. The gameplay IS the engine. There’s nothing to put in Core.”
This is the most natural objection - and the most important one to address honestly.
What Core Actually Means
The Core is not “the fun part of the game.” It’s not the moment-to-moment experience the player has. It’s not the thing that makes the trailer exciting.
The Core is the state and rules that determine what’s true about the game world.
- Is this enemy alive or dead?
- Has this level been completed?
- What score did the player achieve?
- What items does the player own?
- What abilities are unlocked?
- What is the player’s progression through the game?
These truths exist independent of rendering, physics, audio, or any engine system. They could be written on paper. They could be stored in a spreadsheet. They are pure information and pure rules - and that’s exactly what belongs in the Core layer.
The engine produces inputs to this truth (“the projectile collided with the enemy” Core decides “the enemy takes 25 damage and dies”) and consumes outputs from it (“the enemy is dead” engine plays death animation). But the truth itself has no engine dependency.
The CLI Test
Here’s a thought experiment that makes this concrete: strip your game down to a text-based command-line interface. No graphics, no physics, no audio. Just a terminal that displays the current state of the game and lets the player type commands that change that state, eventually leading to success or failure.
Could you play your game this way? You’d never want to - but could you?
Consider Angry Birds as a CLI:
> status
Level 3-5. Pigs remaining: 3. Birds remaining: 2. Score: 1,500.
> fire bird angle:45 force:80
[Physics service resolves trajectory and impact...]
Result: Hit structure. Pig #2 destroyed. +500 points.
> status
Level 3-5. Pigs remaining: 2. Birds remaining: 1. Score: 2,000.
That’s ugly and no fun - but it’s playable. The game state is real. The rules work. The success/failure criteria are evaluable. Everything that makes this CLI version functional is Core. Everything that makes the real version enjoyable - the trajectory arc, the satisfying physics, the squealing pigs - is Services and Views.
This works for nearly every game:
- Platformer CLI: “Position: checkpoint 3. Health: 2/5. Collected: 12/20 coins. Abilities: dash, wall-jump. > move right, jump” - the physics of the jump is a Service, but the state is Core.
- Rhythm game CLI: “Song: Track 5. Combo: 47. Score: 12,400. Grade: A. > hit beat offset:+15ms” - the audio timing is a Service, the scoring rules are Core.
- Strategy game CLI: “Turn 15. Gold: 340. Army: 12 units. Enemy at sector 7. > attack sector:7 units:8” - this one is practically a board game already.
If you can describe your game’s state in text and accept commands that change it, you’ve found your Core. The rest is presentation.
Genre by Genre
RPG / Strategy / Management Sim
Core is obvious and large.
The game is fundamentally a data model with rules. Character stats, inventory, skill trees, quest state machines, economic formulas, tech trees, diplomatic relationships. The engine renders all of this, but the game logic is pure domain.
Core might represent 60-70% of the meaningful logic in the project.
Example - an RPG:
- Character attributes and leveling formulas
- Inventory: item definitions, capacity rules, equipment slots
- Quest system: objectives, prerequisites, completion criteria, rewards
- Combat formulas: damage calculation, status effects, resistances
- Dialogue state: conversation trees, skill checks, relationship values
- Economy: currency, crafting recipes, merchant pricing
Card Game / Turn-Based Game
Core is almost the entire game.
The rules of the game - card effects, deck composition constraints, turn order, win/loss conditions, scoring - are all pure logic. The engine is little more than a card renderer and animation player.
Core might represent 80%+ of the logic.
Example - a deck builder:
- Card definitions: cost, effects, synergies
- Deck rules: size limits, faction restrictions
- Turn structure: draw, play, discard, end turn
- Combat resolution: damage, blocking, status effects
- Progression: unlocked cards, completed runs, meta-currency
Physics-Based Puzzle (Angry Birds, Bridge Constructor, Cut the Rope)
This is where the objection starts to feel valid. The core gameplay loop - launching birds, watching structures collapse - IS the physics engine. You can’t unit test whether a tower falls in a satisfying way.
But look at what surrounds the physics:
The level truth:
- Which targets (pigs) are alive, which are destroyed
- How many birds the player has remaining
- Score awarded for specific destruction events
- Whether the level objective is met (all targets destroyed)
The metagame:
- Star rating per level (1/2/3 based on score thresholds or birds remaining)
- Level unlock progression (completing world 1 unlocks world 2)
- Collectibles and achievements
- Player currency and power-up inventory
The physics simulation produces events (“pig #3 was hit with force exceeding its HP threshold”), and the Core processes those events according to its rules (“pig #3 is now dead, award 500 points, check if all pigs are dead”). The simulation is a Service. The truth about the game state is Core.
Core might represent 20-30% of the logic - but it’s the part that determines progression, saves, scoring, and everything the player cares about between levels.
Platformer (Celeste, Hollow Knight, Super Meat Boy)
The moment-to-moment gameplay - running, jumping, wall-sliding - is deeply engine-dependent. Frame-rate-sensitive movement, pixel-perfect collision, animation cancelling, input buffering. This lives in the engine layer and that’s where it belongs.
But platformers are rarely just the platforming:
Core - player state:
- Health / lives
- Unlocked abilities (double jump, dash, wall climb)
- Current checkpoint
Core - world state:
- Collectibles found (strawberries in Celeste, grubs in Hollow Knight)
- Doors or barriers opened
- NPCs rescued or defeated
- Bosses conquered
Core - progression:
- Map regions discovered and completed
- Ability unlock prerequisites (beat boss X to gain ability Y)
- Currency and shop inventory (charms in Hollow Knight)
- Achievement tracking
A player who has collected 150 out of 175 strawberries, unlocked the dash ability, and opened the path to Chapter 7 - that entire state is pure Core. The engine makes the platforming feel good. The Core determines what’s true about the player’s journey.
Rhythm Game (Beat Saber, Guitar Hero, Osu!)
The gameplay is tightly coupled to audio timing and input precision. The “is this input within the timing window” check depends on the audio system’s clock. That’s inherently engine-adjacent.
But the Core is still substantial:
Core - per-song logic:
- Beat map definitions (note positions, types, timing offsets)
- Scoring formulas (how timing precision maps to points)
- Combo rules (what breaks a combo, multiplier progression)
- Grade calculation (S/A/B/C thresholds)
Core - metagame:
- Song unlock progression
- Player rank and experience
- High score records
- Currency and cosmetic inventory
The timing check itself might live at the boundary between Core and Services - the audio system reports “input arrived at offset X relative to beat Y” and the Core decides “that’s within the Perfect window, award 300 points and continue combo.” The raw timing measurement is engine-dependent; the interpretation of that timing is pure domain.
Multiplayer / Networked Game
“Our game lives on the server. The Core IS the network layer.”
No - the Core is the game rules that the server executes. What happens when a player fires a weapon. How damage is calculated. How the match state transitions from “in progress” to “completed.” These rules are identical whether they run on a server, a client (for prediction), or in a test harness.
The network layer is a transport adapter - a Service that moves data between instances of the same Core.
Example - a multiplayer shooter:
- Core: weapon damage, health, armor, hit detection rules, match state machine, scoring
- Service: network transport, client prediction, server reconciliation, matchmaking API
Open World / Sandbox (Minecraft, Terraria)
“Everything is procedural. The world IS the engine.”
The engine handles chunk loading, rendering, and voxel manipulation. But the rules of the world are domain logic:
Core:
- Block/material types and their properties (hardness, tool requirements, drops)
- Crafting recipes and workbench requirements
- Entity behavior rules (mob spawning conditions, AI state machines)
- Biome definitions and generation parameters
- Player inventory, health, hunger
The procedural generation algorithm might straddle the boundary - the parameters and rules live in Core, the execution (which needs to be performant and may use engine-specific optimizations) lives in Services. The Core says “desert biomes spawn between temperature 0.8 and 1.0 with sandstone below Y=64.” The generation Service uses that data to actually build the world.
The Honest Answer
The amount of code that lives in Core varies by genre:
| Genre | Approximate Core Share |
|---|---|
| RPG / Strategy / Management | 60-70% |
| Card Game / Turn-Based | 80%+ |
| Narrative / Visual Novel | 70-80% |
| Multiplayer Shooter | 40-50% |
| Open World / Sandbox | 30-50% |
| Platformer | 20-40% |
| Physics Puzzle | 20-30% |
| Rhythm Game | 25-35% |
These numbers are rough and project-dependent. The point is not that Core is always the majority of your code. It’s that:
- Core is never zero. Every game has state, rules, and progression that exist independent of the engine.
- Core is almost always more than you think. When you actually list out everything that constitutes “truth” in your game, the list is longer than expected.
- Core is the most valuable code. It’s where correctness matters most, where bugs are most impactful, and where testability pays the highest dividends.
- The architecture benefits the other layers too. Even code that lives in Services or Components is better organized when it interacts with a clean Core through defined interfaces. The layered structure provides value regardless of how the code volume is distributed across layers.
The Metagame Argument
Here’s a pattern that makes the case even stronger: almost every commercially successful game has a metagame. And metagames are almost entirely Core.
- Angry Birds: star ratings, level progression, unlockable episodes
- Beat Saber: campaign progression, score leaderboards, song unlocks
- Celeste: strawberry collection, B-side unlocks, assist mode settings
- Fortnite: battle pass, challenges, cosmetic inventory, player stats
- Minecraft: achievements, crafting discovery, enchantment system
Even in genres where the core gameplay loop is engine-driven, the metagame - the systems that keep players coming back, that provide progression and goals, that drive monetization and retention - is pure domain logic. And in live-service games, the metagame is often where most of the ongoing development happens.
If the only thing Clean Game Architecture gave you was a testable, maintainable metagame layer with clean boundaries - that alone would justify the approach for most commercial projects.
Finding Your Core
If you’re unsure what belongs in Core for your game, ask these questions:
- What would you need to save? Everything that must persist between sessions is Core state.
- What determines if the player won or lost? Those rules are Core logic.
- What could you describe on paper without screenshots? That’s Core domain.
- What stays the same if you switched engines? That’s engine-independent - Core or Use Cases.
- What do you need to be correct, not just “feel right”? Correctness-critical logic belongs in Core.
The answers might surprise you. Most games have more Core than their developers realize - it’s just buried inside engine objects where it’s invisible, untestable, and tightly coupled to everything else. Clean Game Architecture doesn’t create the Core. It extracts it.
For the code that genuinely is performance-critical - the tight loops over thousands of entities, the spatial queries, the procedural generation - the Core still owns the contract (the rules, the interface), while a high-performance Service implementation handles the execution using Data-Oriented Design. See The Performance Dilemma for the full treatment.