
Dungeon Division is a mobile dungeon management game where you hold off invading adventurer parties with monsters. You collect and train monsters, assign them to floors, and the battle plays out on its own. That makes the battle screen the one players stare at the most. And up to Part 4, the battles had correct numbers and nothing to look at. A hit didn't feel like a hit.
September 22 and 23 came to 37 commits. On the morning of the 22nd I grew the roster to 180 species, and from that afternoon to the morning of the 23rd I was stuck on game feel. That's this post. As before, every image here comes from commits made in those two days.
From 50 monsters to 180
On the last night covered in Part 4 I'd taken the roster to 50. The next morning at 11:44 I added 130 more in one commit that touched 2,046 files.
The new 130 were designed as grade ladders from the start. The same creature shows up at four steps: Apprentice, Elite, Radiant and Mythic. There's an Apprentice Moss Boar, an Elite Moss Boar, a Mythic Moss Boar, and so on. The result split evenly: 45 species in each grade (Common, Rare, Epic, Legendary) and 36 in each element (Fire, Water, Nature, Light, Dark). With the numbers lined up like that, you never end up with gaps like "this element has no Legendary".

The art came from PixelLab, an AI pixel art tool. Every species got its own English prompt, with one shared line tacked on: "no human face, no adventurer armor or clothing, non-human body." That line keeps the monsters from looking like the adventurers they fight. I also put the role into the silhouette. Tanks are wide and heavy, melee attackers lean forward into a lunge, ranged ones are thin with a bow or staff in view.
Then at 9:33 that night I redid one. The Apprentice Moss Boar had no visible face and a big shield plate on its head, so next to the other Common monsters it looked like it came from somewhere else. This time I gave an image generator the existing Bark Boar portrait as the style reference and asked for a bigger face, visible tusks and no shield plate.

In the same commit I also regenerated the battle art for the four story bosses (Naia, Ignis, Elderroot and Morgana), bigger and flashier than before.

Dev notesHow 130 species went in at once
The species list is a single JSON file: ID, name, element, grade, role and PixelLab prompt for each. An import script reads it and writes the species CSV and the game tables. Stats aren't typed in by hand. They come from a role × grade table of defaults. The script only touches content and never the save data.
The art runs on a separate track. Once a reviewed PixelLab image exists for a species, a packing script turns it into a battle sheet (4 idle, 6 attack, 2 hit and 5 death frames), a motion strip and a 64-pixel portrait. The source cell size changes by grade, 64, 72, 92 and 108 pixels, so higher grades are physically bigger. To be honest, the motion frames at this point were one still image with simple pose tweaks filling the cells, which isn't real animation. I came back to that much later.
The same commit fixed screen-switching performance too. Every time you moved between screens or the secretary said something, the game recalculated the same battle power estimate several times over. So I keyed the battle inputs and added a cache that remembers the last 32 results. Save data and lineup objects themselves are never cached, because edits from outside would get tangled. The checks confirm that a battle with staging off and a battle with staging on produce the same result, and that cached values don't change when something outside is edited.
Battles with no punch
Game feel work starts with the 3:46 p.m. commit on the 22nd. The design doc notes what I was referencing. I'd watched battle footage from another game, and what I took from it wasn't the art but the "weight of the moment": the screen dipping dark so only the characters remain when a skill goes off, a flash on impact, the target getting shoved back.
I set one rule first. Battle math and event order stay exactly as they are, and the visual staging sits on top. Game feel must never change who wins.
Here's what went in that day:
- Camera focus: while a skill winds up, the view pulls in slightly between caster and target and only the background dims. Common grade gets no zoom and a 14% dim; Legendary gets an 8% zoom and a 50% dim.
- Screen flash: the arena flashes once on Rare-or-higher skill hits, Ultimates, boss kills and crits, tinted 30% with the element color.
- Knockback: the target slides away from the attacker and back, up to 26 pixels depending on grade, crits and skills. Past 14 pixels, dust kicks up at their feet.
- Target marker: before a skill fires, a diamond in the element color settles under the target.
- Numbers: each unit has 3 number slots, so a flurry of hits doesn't paint over the previous number.
- Speech bubbles: short lines per job, role and boss. Skipped at 3× speed.
I made the units bigger too, from 76 to 88 pixels up to 100 to 112, and 176 for bosses. Standing in the same row, they covered each other's faces, so I staggered the front and back rows by half a slot in a zigzag.
Hit stop, and one thing at a time
When I looked again on the morning of the 23rd it was way too noisy. The screen shook on every basic attack, so the crits and skills I actually wanted to land didn't stand out.
At 10:24 I took screen shake off basic attacks. Instead, only the attacker and the target freeze for a moment in the contact pose. That's hit stop. The wind-up went from 3/12 to 4/12 of a second, the recovery after an attack was set to 6/12, and the hit pose holds for 4/12. Knockback went from 0.24 to 0.3 seconds. On paper that's nothing, but those few frames are what make "I hit it" readable. I also limited speech bubbles to one on screen at a time.
At 11:10 I added a spotlight. When an Epic-or-higher skill, a kill, a boss power or an Ultimate happens, every other unit goes dark, their hit sprites and numbers shrink, and no bubbles appear. One star is left on stage.
Sixteen minutes later I worked on the ending. The final blow that wipes out one side plays at 0.3× slow motion, and the result banner waits for it to finish. When a boss enters phase 2 the screen edges pulse red, and if the defenders drop under 30% HP on the last boss floor, the whole floor throbs red. The name of the last adventurer still standing shows up too.
At 11:43 I layered in information. A favorable element matchup shows a callout label, an unfavorable one shows "Resist". Active floor combos appear as chips in the top right, and a star follows the monster who would be MVP if the battle ended right now.
Making game sound effects in layers
Sound got torn down in the same two days. The old hit sound was one swept sine wave with white noise mixed in, and, as the commit message put it, it sounded like "a test tone instead of an impact".
In the 2:45 p.m. commit on the 22nd I resynthesized hits in three layers: a dry attack transient, a body that drops sharply in pitch, and band-limited texture noise. The doc says it plainly: without the pitch drop, a synthesized hit reads as a beep, not an impact.
Two more layers sit on top of that.
| Layer | What it adds |
|---|---|
| Element color | Fire crackles with sparks, Water gets drips and bubbles, Nature knocks on wood, Light rings a bell, Dark hums low |
| Grade flourish | Rare gets one bell note, Epic a rising two-note figure, Legendary a chord with a low boom and a long tail |
I made a cry for every species as well. They're split into ten families (slimes, insects, beasts, birds, undead and so on) with different vocal qualities. The element sets the timbre and the grade sets the body size, so higher grades sound lower and longer: 0.32 seconds for Common, 0.53 for Legendary. Pitch comes from the species ID, so the same species always makes the same sound. The sound side also reuses the exact rule the battle screen uses to decide a unit's grade. If the grade you see and the grade you hear disagree, it feels off.
On the morning of the 23rd I gave sound a priority order too. When a big moment happens, basic attack sounds duck, and basic attacks can only play twice per 0.15 seconds. Cries on basic attacks are capped per voice. The idea is that whatever the screen spotlights also leads in the mix.
Two battle themes
At 10:43 I added battle music: two tracks built on the "clocking in" melody from the lobby theme. Regular floors run at 132 BPM in D minor; the boss floor runs at 144 BPM with one note of the lobby melody dropped a half step to make it ominous. No outside tracks and no music generation service, just synthesis from scripts. Sound effects own the midrange, so the music sits low, and I set a floor on the lowest note so the bass still comes through a phone speaker. During Ultimate cut-ins the music drops to half volume.
Dev notesHow I checked game feel
You have to watch staging to judge it, but playing battles in real time in the editor gives uneven frames, so before-and-after comparisons were useless. I built a fixed-step recorder. It advances the clock 1/30 of a second at a time, records 12 seconds of battle, and swaps the clock the staging uses for the recorder's clock. The same battle comes out as the same frames every time.
Later I had the recorder log every sound effect fired in that window too. A separate script mixes the frames and audio into a video with sound. Sound priority was only something I could judge by listening like that.
Knockback, focus zoom, the 3 number slots and the line table went into the battle motion checks. Whether knockback goes the right way, returns to place, and whether the zoom releases are all checked automatically. But as the doc admits, I hadn't yet listened on a real Android phone speaker at this point.
Calling the monsters "staff"
At 4:18 p.m. on the 22nd I replaced every on-screen "monster" with "staff" (직원 in Korean). The counter word changed from the one Korean uses for animals to the one for people. Netherworld Inc. is a company, so the office language I'd only used in dialogue spread to buttons and system messages. Names inside the code stayed as they were. On the night of the 23rd, "free defense" became "Repel" as well.
Other things from those two days:
- I implemented the weekly raid, where you hold off three parties back to back, with a new lineup each week. It unlocks after clearing story Chapter 2.
- The tutorial's first free hire now guarantees a Rare staff member. From the second hire on it's the normal rates.
- I spread the per-grade stat multipliers from 1.0/1.15/1.35/1.6 to 1.0/1.3/2.0/3.0. More on that below.
- Losing a Repel shows why on the result screen, for example that low scouting meant a hidden trait was missed.
- I added a coupon field to Settings and hid an easter egg behind it. It gives the twin boss Idnian, who can't be obtained any other way. The code is a secret.
- I added 10 more cutscenes to story Chapters 1 to 3 with 20 new illustrations. The story side gets the next post.
That night I also shrank Idnian in battle.

Game balance: spreading out the grade multipliers
A bit more on those grade multipliers. At 10:26 p.m. on the 22nd I set staff HP, attack and defense to 1.3× for Rare, 2× for Epic and 3× for Legendary, and set the level-up gold multipliers to 1.0/1.2/2.0/3.5.
After the change I ran the story simulator and stage 1-7 looked wrong. The growth needed to get past the 1-6 wall dropped from six steps to three, so Common staff arrived at 1-7 at level 10 to 11 instead of 13 to 14. The boss Naia got stronger while the regular floors got weaker. At the recommended Power of 1,470, wins over 30 runs fell from 28 to 8. At the Power players actually had on arrival it still won 30 out of 30, so nobody would get stuck, but the recommended number no longer matched the real difficulty.
So I dropped the enemy level in 1-7 from 16 to 15 and confirmed 28/30 at recommended Power and 0/30 at 80% of it. I ran all 34 stages of Chapters 1 to 3 the same way and fixed only the 12 that missed the bar. The bar: at recommended Power you win at least 85% of the time, and at 80% of it you win 40% or less. I don't use enemies that scale to the player's Power. Every stage's enemies are fixed.
Key commits, Sep 22-23, 2026
- Lineup balance, situational Power estimates
- 180 monster species, screen-switching performance
- New boss battle art
- Battle SFX layered by element and grade
- Weekly raid, finished hiring
- Battle stage direction, wider arena
- Monster → staff
- Redrew the Apprentice Moss Boar
- Grade multipliers, story recalibration
- Coupon field and easter egg
- Hit stop, longer follow-through, one bubble at a time
- Regular and boss floor battle music
- Spotlight, SFX priority
- Slow-motion final blow, boss phases
- Matchup labels, combo chips, live MVP
- Free defense → Repel
What's in the game now
The released game still has 180 staff species. Both battle themes are still in, and the matchup callout still pops up on a favorable hit. In mid-October I replaced a lot of the staff cries and hit sounds with sounds made in ElevenLabs, but the structure of stacking element color and grade flourishes in layers is the one from these two days. The staff art got redrawn several more times after this too, which comes up in later posts.
Looking back, what changed the battles was a handful of numbers: a short freeze on contact, up to 26 pixels of push, a wind-up 1/12 of a second longer, a final blow at 0.3× speed. Over those two days I spent more commits on how existing moments look and sound than on new features.
The next post covers September 24 to 29, when I wrote the story from Chapter 4 through to the ending. If you're curious about the game itself, the game page (Korean) has more.

NOW AVAILABLE
Dungeon Division
Heroes are intruders, monsters are staff. Save Dungeon No. 7 from being shut down.
Available on the Korean App Store (iPhone/iPad), with English in Settings. Android is not out yet.