Why all your enemies feel the same: one rule per enemy, an answer grid and three more enemy design tricks
Five enemy design tricks so every enemy asks something different, shown side by side: one rule each, an answer grid, spaced introductions, variants and outgrowing old foes. With a Claude Code skill.

What we asked“Make a web page that demonstrates the enemy design tricks that make every enemy ask something different one at a time, so anyone can see and feel each one within a few seconds. For each one, show the same short moment side by side: without it on the left, with it on the right, playing in a loop, with a caption that says what just happened and a replay button. Where it helps, let me play the moment myself. It will sit inside a blog post about 720 pixels wide, so it has to look good at that width and on a phone. Also make each one viewable alone with ?trick=<id>&solo, using these ids: one-rule, answer-grid, spaced-intros, variants, outgrow-old. Use the same simple player with the same moves on both sides; on the left the enemies differ only in numbers (size, health, speed), on the right each one has its rule. Use the internet freely for better results: free CC0 art, fonts or small libraries (for example Kenney's CC0 assets) are welcome; download anything you use into this folder so the page works without outside links, and list each item with its licence and source in CREDITS.md.”
What happened
- Loaded the enemy-roster skill
- Downloaded Kenney's free Pixel Platformer art and fonts
- Wrote one small simulation for all five moments, with a player who has four moves: Shoot, Aim up, Jump and Wall
- Ran a scripted bot through every moment in Node to check each one plays out as intended
- Made the spaced-intros captions name the move used, and showed each enemy's name tag only the first time it appears
- Checked the page at 720 px, inside a 375 px phone-sized frame, in light and dark mode, and in play mode
You have a slime, a big slime, a fast slime and an armoured slime. They look different and have different numbers, but the player beats all of them the same way: hold the fire button until they stop moving. A good set of enemies is a list of questions, and here every enemy asks the same one. Super Mario Bros. shows the alternative: a Goomba takes “a quick stomp”, a Spiny can’t be stomped, so “you have to use fire power”, and fire is “useless” against a Buzzy Beetle, which you stomp instead (StrategyWiki).
In the demos below the player is the same on both sides, with four moves: Shoot (a low shot), Aim up (a high shot), Jump (land on top) and Wall (a crate that stops walkers). On the left, enemies differ only in size, health and speed. On the right, each has one rule you can see. A bot plays both sides; Play “Without” or Play “With” lets you take over one of them with the on-screen move buttons or the keys Z, X, C (or Space) and V.
1. One rule per enemy
Give each enemy one rule that changes the answer, and make the rule visible in its look: a shield in front, wings, a heavy charge. Numbers alone change how long a fight takes, not what you do. Plants vs. Zombies is built this way: its zombies “have their own special behaviors and their own weaknesses to different plants”; the Pole Vaulting Zombie leaps over a Wall-nut, and the Balloon Zombie floats over plants until a Cactus pops it (Wikipedia). On the right of our demo, a Grunt walks in (Shoot), a Flyer floats over low shots (Aim up), a Shield blocks shots from the front (Jump on it), and a Charger is too tough to shoot (put up a Wall, and it crashes). On the left, all four are answered by holding Shoot, 17 presses in a row.
2. An answer grid with no duplicates
Write a table: enemies down the side, the player’s moves across the top, and mark the best answer to each. Two checks. Every enemy should have a different best answer; if two share one, change one or cut it. And every move should be the best answer to at least one enemy; a move that answers nothing is a button the player will forget. In the demo, a bot that only ever uses Shoot plays the same wave, and the grid fills in what it beat. On the left, Shoot beats all four, and three moves beat nothing. On the right, the Shoot-only bot beats the Grunt and gets stuck on the other three: each move beats exactly one enemy.
3. Spaced introductions
Bring in one new type at a time, spread across the game: first alone, so the player can work out its answer, then paired with one they already know. Plants vs. Zombies creator George Fan told GDC to “spread out the teaching of game mechanics” (Game Developer). This demo plays a new player who starts out guessing Shoot and only works out an answer when an enemy is alone on screen. Both sides use the same rule enemies; only the order changes. On the left, all four types arrive at once in level 1, then nothing new: 6 hits taken, and only 1 of 4 answers worked out. On the right, one new type per level, alone first, then paired with an old one: 0 hits.
4. One-rule variants
New enemies are expensive to draw. A cheap trick: take an old enemy, change one rule, and swap its colour so the player can see something changed. Super Mario Bros. does this with Koopa Troopas: green ones walk off ledges, while red ones pace back and forth and “won’t fall off a ledge unless kicked” (StrategyWiki). What doesn’t count is a recolour that only adds health. On the left, the red Grunt has more health and speed, and Shoot still answers it. On the right, the red Shield holds its shield on top: the old stomp lands on spikes, and Shoot now works instead.
5. Outgrow the old enemies
When the player gets an upgrade, the tempting move is to scale every old enemy up to match it. Then the upgrade changes nothing. Let upgrades make old types easy, one or two hits, so the player feels the growth, and bring the challenge back with new types and new pairings. On the left of our demo, after the power-up, a Grunt still takes 3 shots, the same as before. On the right, Grunts die in 1 shot, and then a Shield and a Flyer arrive.
Keep the roster small
More enemies is not the goal; more questions is. A few rules the skill follows:
- Cut duplicates. If two enemies share a best answer, change one or remove it. In the grid, the count of shared answers should be 0, and so should the count of moves that answer nothing.
- Test with a one-move bot. A bot that only ever uses one move should get stuck on at least one enemy for every move.
- Don’t go more than about 10 minutes without a new type. And when one arrives, let it appear alone first.
Once each enemy asks its own question, mixing them is how you build fights: see combat encounter design. For how enemies move and decide, see enemy AI, and to make their attacks readable, telegraphed attacks.
Add it to your game
- Copy the skill at the end of this page into your project.
- Ask your agent: “All my enemies feel the same. Give each one its own rule.”
- Play it, then tune in plain words: “The Charger and the Shield both want me to jump, change one.”
Art in the demos: Pixel Platformer and Kenney Fonts by Kenney (CC0).
The skill that made it work
This is the whole skill we gave Claude Code. Copy it into your project and ask your agent to make every enemy ask something different. Every trick sits behind its own switch, and the last step lets a one-move bot check that no move answers everything.
- List the player's verbs (stomp, shoot, block, dodge, aim up, place a wall) and every enemy type, with what beats it now.
- Put every trick behind one named switch in a single settings object, all on by default, so each can be tested on its own.
- one-rule. Give each enemy one rule that changes the answer, shown by its look: shield in front (go around), splits on death (don't fight it in a crowd), flies (aim up), heals others (kill it first), jumps over walls. In Plants vs. Zombies the Pole Vaulting Zombie leaps over a Wall-nut, and the Balloon Zombie floats over plants until a Cactus pops it.
- answer-grid. Make a table of enemies against player verbs. Every enemy needs a different best answer; if two share one, change one or cut it. Every verb should be the best answer to at least one enemy.
- spaced-intros. Bring in one new type at a time, spread across the whole game (a new one every level or few minutes early, slower later), first alone, then paired with one old type.
- variants. Make cheap new enemies by changing one rule of an old one, with a colour swap to signal it. Super Mario Bros.' green Koopa walks off ledges; the red one turns back at them.
- outgrow-old. Don't scale old enemies up to match upgrades. Let upgrades make old types easy (1 or 2 hits) so the player feels the growth, and raise the challenge with new types and pairings instead.
- Measure it. From the answer grid, count enemies that share a best answer (should be 0) and verbs that answer nothing (should be 0). Let a bot that only ever uses one verb play: it should get stuck on at least one enemy for every verb. Log the time between new enemy types (no gap over about 10 minutes).
Save it as .claude/skills/enemy-roster/SKILL.md in your project. Or connect your agent and type /aigamedev: it loads this skill with its reference files and the results from this post.

