maniator / maniator/verticopolis

[Bug]: [P3] The editor panel's gutted-unit warning ships a raw glyph that can tofu

Open Beginner friendly
#794 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
5
Forks
1
PR merge metrics
No merged PRs in 30d

Description

Found by the Edge Case Hunter while reviewing the #782 guard widening. Pre-existing, and it sits in the blind spot of both icon guards.

The defect

src/ui/templates/editor.ts:136:

rows.push(kv("⚠", "Gutted: bulldoze and rebuild."));

That is a bare U+26A0 with no variation selector. Two things follow, and both are needed for the bug:

  1. The guards cannot see it. EMOJI_SCAN matches \p{Emoji_Presentation} or \p{Emoji}\uFE0F. Probed: /\p{Emoji}/u.test("⚠") is true but /\p{Emoji_Presentation}/u.test("⚠") is false, and there is no VS16 here, so neither branch matches. The coverage guard (#721) and the message-leading guard (#743) both walk straight past it.
  2. The mapper never runs on it anyway. kv renders its label as a plain lit text binding. The only callers of messageWithIcons/appendMessageWithIcons are src/ui/uiStatus.ts and src/ui/templates/eventChoice.ts, so the editor panel's key column is not an icon-swapping surface at all.

So the glyph reaches the DOM raw. On a system with no symbol coverage for U+26A0 (a bare Linux container, a stripped WSL image) the player sees tofu in the gutted-unit card. The identical warning written WITH the VS16 in src/game/appBoot.ts and src/game/desktopSaveHydrate.ts is swapped for the pixel warning icon correctly, which is what makes this inconsistent rather than merely unmapped.

Fix shape

Either render the icon directly (kv(iconTemplate("warning"), ...), matching how other non-message surfaces do it) or add the VS16 and route that row through the mapper. The first is preferable: the editor panel is not a message rail, and making it one to fix a glyph would be the larger change.

Worth considering alongside it

The guards' scan definition is the deeper gap. They are built around emoji-presentation characters, so any text-default symbol written without a VS16 is invisible to them by construction, and that is exactly the shape that tofus. Widening EMOJI_SCAN to catch bare \p{Emoji} would surface this class, at the cost of matching a lot of legitimate punctuation (©, , , the digits). Not obviously worth it, but the tradeoff should be a decision rather than an accident.

Related: #721 (the mapping requirement), #743 (the message-leading requirement), #782 (the scope widening that surfaced this).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at src/ui/templates/editor.ts:136 and compare the row with the warning-icon rendering used by other non-message surfaces. Keep the editor panel out of the message mapper, and make the gutted-unit warning render without a raw glyph. Treat widening EMOJI_SCAN as a separate decision, since the issue identifies it as a broader tradeoff rather than a required part of this fix.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.