There is a difference between making a game with a fixed set of rules and making one whose rules keep growing. At first, asking AI to build a game may seem like enough. But if you have to rework the structure every time you add a rule, things change.
Rules Without a Finished Example to Follow
The game INSIGNIA, covered in the video, is based on Stratego. It adds rules that do not exist in the original game.
Missiles fly in a straight line for exactly 2 or 3 spaces. Engineers turn an adjacent obstacle into a path and move forward. Commandos can make a one-time jump to attack a space 3 spaces away. They are shot down if there is a sniper near the landing spot.
There is no finished example for AI to refer to for rules like these. Asking AI to build the game for the first time was one problem. Continuing to add rules and cards, such as those for commandos and snipers, was another. Every time a rule was added, the existing structure had to be reworked. This was not because AI had done something wrong. The existing structure made it hard to implement new rules.
Separating Game Flow from Rules
So I divided the elements in the game into cells, units, players, cards, and a referee. Game handles only the flow, while Referee handles the rules.
Game receives a move, passes it to the referee, and asks the referee whether the game has ended. Game rules do not belong in Game.
Referee is an abstract class. It includes legalActions, which provides the moves that can be made now, and resolve, which handles a move and decides whose turn is next. Each game gets its own referee class.
Cells and units are also separated so they do not know the game rules. A cell does not know which unit is on it.
Making Room for Each Rule
Separating the structure creates places to add rules.
Hidden ranks are represented with a unit's perceived value, which separates the identity shown to the opponent from its true rank. Missiles are handled through a unit's range. The engineer's path-building ability is a rule that changes whether a cell can be crossed during the game. The commando's jump is a one-time ability.
Adding a new rule changes from reworking the structure to adding a feature. Object-oriented design does not put each requirement directly into a feature. Instead, it structures objects to fit the requirements and lets those objects interact to produce results.
Think about whether people often change their orders to a different dish while the food is being prepared at a restaurant. This can show us something about software: requirements often keep changing. Object-oriented design is one approach that developed to help handle these changes.
A Shared Engine and Game-Specific Rules
I tried putting several games on the same engine. Here are the line counts:
- Shared engine: about 400 lines
- Ladder game: 80 lines
- Yut Nori (a traditional Korean board game): 127 lines
- Blue Marble (a Korean Monopoly-like game): 167 lines
- Dominion: 171 lines
- Janggi (Korean chess): 257 lines
- INSIGNIA: 393 lines
Instead of building each new game from scratch, I inherit from the referee class and fill in the rules. Starting with the second game, I did not change a single line of the engine. The time it took to create the abstraction and build six games was shorter than the time it took to build INSIGNIA alone.
I did not generalize everything from the start. I moved shared parts into the engine only when the second game needed them. Yut Nori's branching paths and the Ladder game's one-way shortcuts connect cells in different ways. A card game without a board, like Dominion, can also run using only the game flow, without using cells.
In this video, I look at how I divided the game structure as rules kept being added, and at the results of putting several games on a shared engine.
If You Expect Requirements to Keep Changing
If you plan to make one game with fixed rules, like Janggi or Gomoku, and then stop, you may not need this kind of structure. Just asking AI to build it may be enough.
But if you plan to keep adding rules or features, it may be worth considering this structure for modules that change often and have frequent errors, rather than making everything object-oriented from the start. It may now be more important to ask how little existing code needs to change when a new requirement comes in than how long coding takes.
In a program that gets frequent new requirements, which parts would be helpful to separate first?
This article summarizes my Korean YouTube video. It was translated with AI and reviewed by me. #ABotWroteThis
Original video (Korean, with English subtitles): https://youtu.be/4brdEOdyRAM
Previous video: What Matters More Than How to Use Claude Code








