Cornerstone

Designing Balanced Sword Combat

The design problems behind a combat system that stays fair, and how each one was solved here.

This guide is written from the design side. It covers the problems a sword combat system has to solve to stay interesting for more than about ninety seconds, and how each one is handled in the system this site runs on. It is useful whether you are building something similar or simply want to understand why these games behave the way they do.

The first problem: making an attack cost something

If attacking is free and instant, there is no game. Every defensive option becomes pointless, because there is no window in which defending could be better than attacking, and the optimal strategy collapses to holding the button down.

The classic solution, borrowed from fighting games, is to divide an attack into startup, active and recovery phases. Only the active phase connects; the other two are periods during which the attacker cannot respond to anything.

The numbers matter enormously. A recovery that is too short makes attacking nearly free again. Too long, and attacking feels like a punishment. The values used here - 160 milliseconds for a light attack, 340 for a heavy - were tuned until a whiffed light was survivable and a whiffed heavy was reliably fatal against a competent opponent.

The second problem: every option needs a situation where it is wrong

An option that is always at least as good as the alternatives is not a choice, it is a default. A well-designed system makes each option correct sometimes and actively bad other times.

The dodge row is the subtlest. Making invulnerability front-loaded rather than centred means an early dodge is worse than a late one, which is counter-intuitive and creates a genuine skill in a mechanic that would otherwise be a free escape.

OptionWhen it is rightWhen it is wrong
Light attackPunishing a short recoveryAgainst a shielded enemy's front
Heavy attackStaggered enemy, or a formed lineAs an opener - the recovery is fatal
BlockAn expected blockable attackAgainst red telegraphs, or when you could walk away
ParryAn attack whose timing you can readAn attack you cannot yet read - the stamina still goes
DodgeUnblockable attacks, and repositioningThrown early - invulnerability is at the start
RetreatAlmost always, and it is freeWhen the objective is behind you

The third problem: turtling

If holding a guard is free, the optimal strategy against any opponent is to hold it until they commit and then punish. That is technically correct play and it is extremely boring.

The solution used here is two-layered. Blocking costs stamina, so a guard cannot be held indefinitely against sustained pressure. And when stamina reaches zero, the guard breaks and leaves the defender exposed for most of a second - which is worse than the hits they were blocking.

That converts turtling from a strategy into a resource with a failure state. It also means an aggressive opponent has a real answer to a defensive one, which is what stops the defensive AI in Sword Duel Arena from being unbeatable.

The fourth problem: making the crowd different from the duel

A combat system tuned for one opponent usually falls apart against eight. The options that work in a duel - blocking, parrying, careful spacing - are all directional, and directional defence is useless when you are surrounded.

Rather than adding a separate system, the approach here is to change which options are viable by changing the situation. In a crowd, blocking covers one direction of four, parrying requires reading one attack among several, and spacing is impossible - so movement and area attacks become the answers instead.

The heavy attack's wider arc is doing the work here. In a duel it is a bad trade; in a crowd it hits three enemies and becomes the best action available. Same move, same numbers, completely different value.

The fifth problem: legibility

An arcade run lasts a few minutes and a player cannot be expected to study frame data. Everything the system does has to be readable from the screen, immediately, at a glance.

The tools used here are all visual and all consistent. Attack phases are shown by pose. Telegraphs are drawn as the actual area an attack will cover, growing as the wind-up progresses. Colour distinguishes blockable from unblockable in exactly one way, everywhere. Enemy types differ in silhouette rather than only in colour.

The test applied is whether a player can name what killed them within two seconds of dying. If not, the failure is the game's rather than theirs, and something needs to be drawn more clearly.

The sixth problem: difficulty that ends fairly

An endless game needs a difficulty ramp, and a ramp without a ceiling eventually produces a game where every run ends at the same point regardless of skill.

The approach here is a smoothstep curve that flattens near the top, plus hard floors on the values that would otherwise become inhuman - the gap between obstacles in a runner, the interval between spawns in a timing game.

The design goal is stated simply: a run should end because the player made a mistake, not because the numbers left the range a human can respond to. That sentence decides a surprising number of tuning arguments.

Knowing when a system is finished

Combat systems can be tuned indefinitely, and the hard part is deciding when to stop. The test used here was whether a specific player complaint had a specific answer inside the system.

If a player says an enemy is unfair, there should be an answer that is not simply 'be faster'. Armoured enemies have the heavy attack and the flank. Unblockable attacks have distance and the dodge. Crowds have the spin and the lateral movement that turns a circle into a line. Casters have target priority. Wherever a complaint had no answer other than raw speed, the enemy needed changing rather than the player.

Balance here does not mean every option is equally good. It means no option is good everywhere, which is a much easier property to verify and a considerably more interesting one to play against.

The seventh problem: making a hit feel like a hit

A combat system can be perfectly balanced and still feel like arithmetic. The difference between a hit that reads as impact and one that reads as a number changing is mostly in three effects that have no mechanical consequence at all.

Hit-stop freezes the simulation for 35 to 90 milliseconds while rendering continues, holding the frame the blade connected on. Screen shake displaces the play area contents briefly, scaled to the weight of the blow. Particles throw a cone of sparks back along the direction of the strike.

All three are disabled for visitors whose system requests reduced motion, and gameplay is completely unaffected by that - which is the correct relationship between feel and function.

The eighth problem: making a tutorial unnecessary

A browser game has no install and no captive audience, which means it cannot spend its first two minutes explaining itself. Anything that has to be taught before the game becomes enjoyable is a design problem rather than a documentation one.

The approach taken here is to make the opening a demonstration rather than a lesson. The start of every difficulty curve is deliberately gentle, so early enemies telegraph slowly enough that the structure of an attack is visible without being described. One game explains itself in words - Retro Sword Duel names the attack phases on screen as they happen - and it exists precisely so the other twenty-nine do not have to.

The measurable version of the goal is that a player who presses nothing should still learn something in their first run. Watching an enemy wind up, attack and recover while doing nothing teaches the core loop, and every game here is tuned so that run survives long enough for it to happen.

The ninth problem: thirty games that are not the same game

A shared engine and a shared combat system make a library coherent, and they make it very easy to ship thirty variations of one game. Avoiding that was a continuous constraint rather than a single decision.

The method was to give each game one mechanic no other game has and let the shared systems handle everything else. Neon Blade replaces the standing attack with a dash that is also the cut. Sword Storm removes movement entirely and makes facing the only input. Sword Breaker replaces the button with a drawn gesture. Crystal Blade makes you bank a curve you committed to earlier. Sword Maze takes away your vision.

The test applied was whether a player who is competent at one game would be measurably bad at another for a reason that is interesting. If the answer was that they would simply be good at it immediately, the game did not yet have a reason to exist. That is a harsher standard than asking whether something is fun, and it is the one that keeps a large library from collapsing into a menu of reskins.

The tenth problem: the cost of trying again

A score-chase game lives or dies on what happens in the two seconds after a run ends, and the deciding factor is not how the run went but how expensive the next one is.

A retry that takes a second or two keeps the player inside the loop: the decision to try again gets made before the frustration of the last failure resolves into a decision to stop. A retry that takes ten seconds - a results screen to dismiss, an animation to sit through, a menu to navigate - inserts exactly enough time to reconsider. This is why results screens here are brief and restart is always one input away.

The same reasoning rules out several things that would otherwise be reasonable. No run here requires replaying content you have already mastered to reach the part you are working on, because that raises the cost of every attempt. And nothing carries over between runs, because progress that accumulates would make an early run and a late run incomparable - which is the same argument as the fixed difficulty curve, arriving from a different direction.

Key takeaways

  • An attack must cost something, and the three-phase structure is how - only the active window connects.
  • Every option needs a situation where it is actively wrong, or it is a default rather than a choice.
  • Blocking costs stamina and a broken guard is worse than the hits it absorbed. That is what stops turtling.
  • The same heavy attack is a bad trade in a duel and the best move in a crowd. Situation changes value, not numbers.
  • The legibility test: can a player name what killed them within two seconds?
  • Feel effects - hit-stop, shake, particles - must have no mechanical consequence, so they can be switched off safely.

Frequently asked questions

Why do attacks need a recovery phase?

Without one, attacking is nearly free and every defensive option becomes pointless. The recovery is the window in which defending, spacing or punishing can be better than attacking.

How do you stop players from just blocking everything?

Make blocking cost a resource and make running out of that resource worse than the hits being blocked. Here, each block costs stamina and a broken guard leaves you exposed for most of a second.

Why is dodge invulnerability at the start of the dodge?

So that dodging early is worse than dodging late. Centring it would make the timing forgiving in both directions and remove the skill from the mechanic.

How do you make one combat system work for duels and crowds?

Change the situation rather than the system. A heavy attack's wide arc is a bad trade against one opponent and the best move against three - same numbers, different value.

What is the test for whether a game is legible enough?

Whether a player can name what killed them within two seconds of dying. If not, the failure belongs to the game, not the player.