Roguelike balance: every number I set by feel was wrong

Soul Strip pixel art: a card heroine between a fiery card-level aura and a pink Bond aura

Every number in Soul Strip’s progression that I set by feel turned out wrong. Not slightly wrong: one system missed by a factor of five, another by fifteen. I know that before release only because the game can play itself a thousand times while I make coffee.

Soul Strip is a roguelike deckbuilder. You take a deck of character cards through a map of nodes across three acts, and a boss waits at the end of each one. Dying sends you back to the start, and the only thing that carries between runs is the levels your cards have earned. A run is about 70 player turns, roughly 23 minutes.

The simulator that plays the game itself

Answering a progression question with real players costs weeks per question, so the game carries its own simulator. It plays full three-act runs through the real battle code rather than a simplified model, and it never draws a scene. One run costs it 0.3 seconds. A thousand runs take five minutes on one core and under a minute spread across all of them. It starts from an empty save every time and never touches mine.

Pixel art: one heroine in the middle of the hall and dozens of ghost copies of her fanning out along branching paths

One rule cost me more than any single number below: a percentage without an interval is not a measurement. Every win rate the simulator prints carries its 95% Wilson interval, because at five runs a “100%” cell is really 34 to 100, and two cells whose intervals overlap aren’t different however far apart the percentages sit.

“A fresh account wins 0 to 5%” sat in my notes as an open question for weeks. It came from five runs. A hundred runs on each of the four play styles, from random button presses up to the most careful play I can model, closed it at 0 to 2% on every one of them, interval under seven percentage points. Two hundred runs per style added the depth behind that flat number: act 1 falls in 45% of runs under random play and 59% under careful play, act 2 in 6% and 9%. Skill on a starter collection buys depth and no wins at all. That’s the intent, and it’s why the axis here is how far a run gets rather than whether it ends in a victory.

Card level and Bond

A card has a level from 1 to 5. That single number used to move the card’s damage and block, unlock its bonus effects, and decide which of its five illustrations had appeared in the Gallery, the screen where all the art you’ve unlocked is collected. Three jobs with three different pressures behind them. Raw numbers have to stay capped or the difficulty ladder tips over. Bonus effects are the interesting part, so they should cost a decision. Art is a collectible and shouldn’t fall out of grinding fights.

So the level split in two.

Card level moves the numbers: damage, block, everything the card does in a fight. It grows by one point every time you play the card, banks at the end of the run, and doubles for the Waifu of the run, the card that did the most in it. Thresholds are 40, 80, 160 and 320 XP. Every value it raises already has a ceiling in the code, which is what makes card level safe to hand out for playing.

Bond unlocks the bonus effects and the new illustrations. Those effects have no ceiling at all, so Bond is paid for with decisions instead of repetitions: a Date at the Hot Springs instead of a heal, a promise kept, a boss brought down. The last two only count for the card you picked before the run started. Thresholds are 3, 5, 6 and 7. One card’s whole climb to Bond 5 costs 21 XP, so all 60 cards come to 1,260.

Twenty one points of Bond against six hundred points of card level, if you add all its thresholds up. That looks absurd until you see the sources: card level collects XP by the dozen in every fight, and Bond collects it two or three times in a run.

Promises and where their targets came from

Bond needed a source that pays for a decision. So before a run you wish for one waifu, which is the game’s word for the girls on the cards, and take one promise about her: one condition to meet during the run.

My first list was seven counters: “deal 320 damage with her card”, “play her card 40 times”, six variations of one shape. I wrote all seven, wired them up, and then read them back. That isn’t a promise, it’s a toll. The player does exactly what they were going to do anyway, only for longer.

The list is fifteen conditions now, and not one of them counts repetitions. Each asks for a single strong turn, a particular deck, or a particular way the run ends. The wording below is what the screen shows, with the number set by the promise’s difficulty.

  • One turn. “Deal N damage with the chosen card in one turn”. “Play the chosen card ×N in one turn”. “Stack one status ×N with the chosen card”. “End a turn with Block ×N”. Playing longer doesn’t help here: either the turn comes together or it doesn’t.
  • A particular deck. “Win a battle with the chosen card alone”. “A deck of N cards or fewer”. “A deck with no Cursed cards”. “A deck of the chosen card’s element only”. This changes how the run is played, not how long it lasts.
  • How the run ends. “Beat a boss without losing HP”. “Kill a boss by turn N”. “Make the chosen card the Waifu of the run”. Checked once, at the end, and failed attempts inside the run add up to nothing.

Then the targets, and this is where the simulator did the real work. It played 240 runs under a style that never steers for a promise, and recorded the peaks anyway:

counter p50 p75 p90 max never happened
damage in one turn 20 25 36 64 0%
tallest a status got 13 20 29 87 0%
synergies in one fight 13 19 33 81 0%
block held at end of turn 43 54 72 128 0%
turns taken to kill a boss 8 11 16 43 30%
deck size at the end 22 25 28 38 0%

Easy sits at p75, medium at p90, hard above p90 but inside the observed maximum. p75 is the value one run in four reaches without trying for it. Conditions with no number in them take the difficulty their passive rate lands in: 23% of runs beat a boss without losing HP, so that one is a medium, and 2% win a fight playing nothing but a single card, so that one is a hard.

My earlier targets were guesses, and the table shows how far off. Turn damage was set at 40/70/120 against an observed maximum of 64. Synergies, the bonus for playing several cards of one element in a turn, were at 3/5/8 when the median run already fires 13. Half the list would have been impossible and half of it free.

Two caveats travel with that sample. The five girls it rotates through are starter commons at card level 2 to 2.6, so a full collection led by an Epic clears the scaling conditions more easily. And the simulator never removes a card at a shop, so its decks end up bigger than a real player’s, which makes deck size the one row that’s understated rather than measured.

Three passes at the price of a gift

Bond XP raises the level, but something had to bind the pace, or Bond would be a function of hours played, which is exactly what card level already is. Gifts do the binding, and they’re bought with souls: the currency a run leaves behind, one per ordinary fight, three per elite, seven or eight per boss.

At first the shop sold Bond XP. Gifts at 15, 30, 45 and 70 souls, cheaper if you let the game choose who received one. Then I measured soul income over six campaigns of 40 runs each from an empty save: a median of 15 to 28 souls a run, 17 to 29 across the first third and 24 to 32 across the last. At those prices one girl costs 160 souls and all 60 cost 9,600, which is about 384 runs. 147 hours to fill the collection, against a target of at least 30.

Then I cut the prices to a third, down to 5, 10, 15 and 25. A girl costs 55, the whole collection 3,300, about 132 runs and 51 hours. Closer. But Bond has two locks on it: the gift raises the ceiling, the XP raises the level, and the level opens on whichever of the two is slower. The price cut only opened the soul lock. Souls now emptied every run, while dates and promises together paid 1.5 to 3.1 Bond XP a run, which left a full collection 400 to 850 runs away, three times further out than the souls. Average Bond stayed at 1.2 to 1.3, with 40 to 50 cards out of 60 still sitting at level 1.

In the end the gift stopped selling XP. It raises the ceiling on one girl’s Bond by exactly one level, and the four of them go in order. The Simple Gift opens Bond 2, the Fine Gift 3, the Costly Gift 4, the Special Gift 5. Random gifting is gone, so you always pick who gets it.

bond_level = min(level_from_xp, 1 + gifts_given)

A price only turns into a number of runs by way of income, and income is what I measured wrong twice. At thresholds of 6/10/16/24 the collection cost 3,360 XP against an income near 3 a run: fifteen times too slow. I cut them to 2/3/4/5 against an assumed 9 a run, then measured 17.5, and one campaign had 50 of its 58 owned cards at Bond 5 by run 40. The thresholds that stuck are 3, 5, 6 and 7.

A ceiling doesn’t convert into any income at all. It moves by exactly one level, it can’t skip one and it can’t be farmed, so it has no number in it to get wrong. XP a card already earned isn’t lost either: the gift counts it immediately, so a level can open the same second the gift arrives.

Pixel art: four gifts from plain to jewelled, above them a staircase of two lit hearts and three locked padlocks

The last piece was a third source of Bond XP, because dates and promises were too thin on their own. The waifu you wished for now earns 3 Bond XP for every boss she brings down. Income went to 3.1 to 7.1 a run, mean 5.8, and a full collection moved from 400–850 runs to 178–406, typically around 200. The soul side locks at 132 runs and the XP side at about 200: the same order of magnitude instead of a threefold gap, and both above the 30-hour target, at roughly 51 and 77 hours.

That boss count isn’t a counter. It’s read off the act you reached, because advancing an act is the only way past a boss. A separate tally would be a second copy of the same fact, and two copies can disagree.

One thing the third source didn’t even out. Bond stays clumpy: 41 to 46 cards out of 57 sit at level 1 while 2 to 6 sit straight at 5. That’s what paying XP to the girl you wished for does, and I left it alone, because the clumping is the point of the track.

Still open: depth, not difficulty

Careless play beats careful play. Not inside the error bars, just beats it: 69% of runs against 68% on a half-built collection. The style that mashes the first legal card takes 53% of the same runs.

Between the best play and random play there are fifteen points. Between the best play and careless play the gap is minus one.

Switch off the between-run advantages one at a time and you can see where that comes from. Card level is worth 47 percentage points of wins, more than anything else an account can gain. The collection wins the run, not the decisions inside the fight.

The fix is a redesign of the cards themselves rather than a difficulty slider, and there are no numbers from after it yet.

Every figure in this article started as a guess that looked obvious. All the simulator really does is make a guess like that cost five minutes instead of a month of real runs.

Soul Strip is at version 0.9.93 and release is close. The Steam page takes wishlists.

Soul Strip: Waifu Card Battler

A deckbuilding roguelike where every card is a waifu with her own element and personality. Battle through dark fantasy, craft combos, collect and level up your favorites.

Wishlist on Steam