Crit System

Status: planned / stubbed. The renderer can display crit damage numbers and a crit_flash effect is registered in the theme, but no roll, chance field, multiplier, or caller currently exists in the damage pipeline. As of the verified commit, every hit resolves at base damage.

What a crit would be

Conceptually, a crit is a per-hit roll:

  • Crit chance — probability the hit upgrades to a crit.
  • Crit damage multiplier — factor applied to the rolled damage when a crit triggers.

Anticipated stat sources (none implemented yet):

  • ship.critChance / ship.critMult — ship-wide chance and multiplier.
  • Weapon-specific overrides — per-weapon crit chance or multiplier on the weapon data row.
  • Global meta-progression buff — data/planet-progression.ts already declares a Global Crit Boost buff for the Speed Event (planet 31), confirming crit is intended to interact with the planet-buff system.

What exists today

The visual layer is wired; the gameplay layer is not.

Renderer support — implemented

engine/vfx/particles.ts DmgNumbers.add(x, y, val, col?, isCrit = false, overrideSz?) accepts an isCrit boolean. When isCrit is true:

  • Color is forced to #ffcc44 (yellow).
  • Base size is multiplied by 1.3 (slightly larger floater).

Code comment at the call site in engine/combat/damage.ts documents the intent: “White by default, yellow (#ffcc44) for crits, 1.4s lifetime, 22px/s float.” The render guide in engine/rendering/draw.ts also notes “Enemy default: ffffff, crit: ffcc44.”

Theme effect — registered

data/theme.ts registers a crit_flash effect descriptor: { type: 'flash', duration: 0.08, color: '#ffffff' }. No caller fires it.

Damage pipeline — no roll

In engine/combat/damage.ts, the hit resolution applies raw weapon damage with no crit step:

  • No Math.random() < critChance check.
  • No multiplier applied to rawDmg.
  • The single DmgNumbers.add(enemy.x, enemy.y, rawDmg) call passes only three arguments — isCrit defaults to false.

The non-crit damage-floater color ladder (white < 100, yellow 100-399, orange 400-999, red 1000+) happens to use the same #ffcc44 yellow at the 100-399 tier, so heavy hits already look crit-colored even though no crit ever fires.

No stats fields

Repo-wide search for critChance, critMult, critDamage, isCrit, ship.crit* returns zero hits outside the renderer stub. data/weapons/_types.ts declares no crit fields. No ship, passive, mod, artifact, or affix references crit stats today.

Open design questions

If the system is implemented, the design needs to choose:

  • Whether crit is a flat ship stat, a per-weapon stat, or both (stacked or overridden).
  • Default chance and multiplier values.
  • Whether crit can interact with damage-tag effects (life steal, on-hit triggers, status durations).
  • Whether the Global Crit Boost planet-31 buff adds chance, multiplier, or both.
  • Whether the crit_flash theme effect plays on the enemy hit, the projectile, or the muzzle.
  • data/planet-progression.ts — declares Global Crit Boost as planet 31’s biome buff.
  • engine/vfx/particles.tsDmgNumbers.add accepts the unused isCrit flag.
  • engine/combat/damage.ts — current damage resolution; the place a crit roll would slot in.
  • data/theme.tscrit_flash effect descriptor, currently never fired.