Make campaign heroes readable next to their own troops - #152
Merged
Conversation
Heroes alias a rank-and-file rig through UnitDef.sprite, and in the HD art pack a hero and his militia are literally the same frames, so William Wallace was indistinguishable from the soldiers he leads — in chapters that are lost the moment he dies. Mark heroes in @bf/data with `hero` plus a master-palette accent ramp, and give the renderer a hero treatment driven off that flag, so every existing and future hero in every campaign gets it: - palette-swap the rig's cloth AND metal ramps to the hero ramp (which of the two a rig uses depends on its tier: militia are cloth, champions and knights are all harness, so aiming at one family only would miss half the roster); - multiply the sprite by the ramp's light tone lifted to a fixed peak, which is what carries the accent on the pre-rendered HD art where no palette colour survives an exact-match swap; - draw hero art at 1.15x, keep a permanent gilded ring at the feet, and add a gold pip on the minimap. The player-colour band keeps its own ramp throughout, so a hero still shows whose side he is on, and dying heroes keep their accent through the corpse animation instead of popping back to rank-and-file art. Tests cover the data flag and ramp constraints (palette-legal, saturated enough to tint, distinct within each scenario's cast), the single-pass recolour, the hero helpers, and — against the shipped atlas — that each hero rig really does get a visible share of its pixels repainted. Refs #110 Signed-off-by: Claude <knorcedger@gmail.com>
Follow-up on the hero treatment after seeing it in play: - The gold ring read as "yet another amber ellipse": #E6C04A already marks gather targets, rally flags, garrison badges, conversion beams and impact flashes. Heroes now get their own shape instead — a four-pointed compass star squashed onto the floor plane at the feet, plus a five-pointed star floating above the health bar so the marker survives a crowd that hides the ground. Both are drawn in the hero's own accent colour over a dark rim with a pale core, so a dark or green hero still separates from grass. - Tint deepened: the ramp's light tone keeps its lifted peak, but the two non-dominant channels are pushed down by a saturation exponent, so the hue is much stronger without dimming the sprite into a smudge. - Hero draw scale 1.15x -> 1.3x. - Hero health bars anchor to the sprite's visible top instead of the fixed unit offset, which the larger art crossed at chest height. Refs #110 Signed-off-by: Claude <knorcedger@gmail.com>
Four points read as too plain a marker. starPoly gains a minorRatio so every second point can be shortened, and the ground marker uses it for four long cardinals plus four short diagonals: uniform eight points at marker size just fill in as a circle, which is the shape the hero marker exists to avoid. Refs #110 Signed-off-by: Claude <knorcedger@gmail.com>
Eight points of one length, as asked. A deeper inner radius (0.28) keeps them spiky at marker size instead of closing into a disc, so the alternating-length compass rose is no longer needed: starPoly loses the minorRatio parameter it added and goes back to a plain star generator. Refs #110 Signed-off-by: Claude <knorcedger@gmail.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…-differentiation-nv9yvs Signed-off-by: Claude <knorcedger@gmail.com> # Conflicts: # CHANGELOG.md # packages/game/src/frames.test.ts # packages/game/src/world.test.ts # packages/game/src/world.ts
…-differentiation-nv9yvs Signed-off-by: Claude <knorcedger@gmail.com>
Knorcedger
force-pushed
the
claude/wallace-outfit-differentiation-nv9yvs
branch
from
August 23, 2026 09:30
4a7cc3c to
45d4beb
Compare
…-differentiation-nv9yvs Signed-off-by: Claude <knorcedger@gmail.com>
…-differentiation-nv9yvs Signed-off-by: Claude <knorcedger@gmail.com>
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed?
Campaign heroes were indistinguishable from the soldiers they lead. Worse than "similar": heroes alias a rank-and-file rig through
UnitDef.sprite(heroWallace→champion), and in the HD art pack that loads by defaultunit/champion/*andunit/militia/*are the same frames — so William Wallace was the militia sprite, in chapters that are lost the moment he dies.Heroes are now marked in
@bf/datawith aheroflag plus a master-palette accent ramp (heroCloth), and the renderer keys a hero treatment off that flag, so every existing and future hero in every campaign gets it:highlightcore. The minimap adds a matching gold pip.Player colours are untouched throughout, so a hero still shows whose side he is on, and heroes keep their accent through the corpse animation instead of popping back to rank-and-file art.
Related issue
Refs #110
Partial delivery on purpose: this is the render-time treatment. Bespoke hero rigs in
tools/assetgen— real distinct silhouettes — remain open on the issue, as do hero HUD portraits (a hero still shows his base unit's icon).Why this approach?
#E6C04Aalready marks worksite highlights, rally flags, garrison badges, conversion beams and impact flashes, so a gold ellipse read as generic UI. Heroes get their own shape and their own per-hero colour.packages/sim— it is render-only, keyed off render-only data fields alongside the existingspriteandicon.Merge with main
mainmoved while this was open (#116/#134 centralised art scale and the frame resolver, #142 renamed the gather highlight to the worksite highlight, and the unit art was regenerated). Resolved by folding the hero work into the shared helpers rather than keeping a parallel path: the hero draw scale is now a case insideartScaleForFrame, so the live sprite, fog ghost and placement preview keep sharing one rule, and the accent flows throughresolveCandidates/buildingArtKey. The standaloneartScaleForthis branch had added is gone.Verification
npm run typechecknpm test— 1410 passing, 11 skipped (post-merge; the branch's own suite was 1047 before main was merged in)npm run buildandnpm run bundle:checkScreenshots were taken and reviewed during development but could not be attached from this environment. Visual verification: Wallace chapter 1 driven in a headless browser (
wallace-1via the nav hint) at 1280×800 @2×, in the default HD art mode and in the pixel-atlas mode, unselected and selected, checking the accent, both stars, the health-bar stack and the minimap pip — and re-run after the merge with main, since main regenerated the unit art. No console errors. Ownership was checked per cast: each hero tint over its player's colour band (red stays red, green stays green, yellow stays warm).New tests:
packages/data/src/data.test.ts— hero flag coverage; ramps are palette-legal (validated againsttools/assetgen's master palette), saturated, not equal to the cloth or metal ramps, and distinct within each scenario cast.packages/game/src/heroArt.test.ts— measures the shipped atlas: every hero rig gets 8–17% of its opaque pixels repainted. This is the check that catches an accent aimed at a ramp its rig does not use.packages/game/src/recolor.test.ts— the combined single-pass palette application, including that the accent cannot consume pixels the player swap just wrote.packages/game/src/frames.test.ts,world.test.ts— hero helpers, tint derivation and bounds, star geometry, hero health-bar offset.Provenance and AI assistance
Written by Claude Code (Anthropic) working from the issue and in-session review by the maintainer: it wrote the data, renderer and test changes, measured the atlases to pick the accent targets, and drove the headless browser for visual checks. No generated art assets — no atlas, sprite or texture file is added or modified by this branch; the accent is computed at runtime from existing frames. All commits signed off under the DCO.
Contributor checklist
CONTRIBUTING.mdand followed the deterministic simulation rulesgit commit -s)