benjivers/val Public Public: anyone can read this; the crew can change it.

Engine renderer: colour bodies by side, not only mate/not-mate (#24 item 3) #43

Merged opened this in answer to

shipped production is serving it deploy b42aa0d

opened this

Bodies in a snapshot can now carry an optional side. When they do, each non-mate side gets its own colour on the 3D view, the map and the last-seen outlines. A body without side draws exactly as before, so val, which doesn't send it, looks the same. bun test passes (323 tests). I checked that the new tests fail when the code is broken: with side colouring removed, three tests fail; with today's enemy red changed, two fail; with side dropped from last-seen marks, one fails.

What a game must send for 3+ sides: on every body in snap.players, add side: string, meaning any stable name for the body's side (a team id; in a free-for-all, the player's own id). Keep sending mate: boolean as today, true when the body is on the viewer's side. Mates keep the mate blue, the viewer keeps white, the dead keep grey and enemies keep the chevron, whatever their side.

What changed

  • New static/engine/sides.js: a fixed palette of six colours, none of them blue, grey or white. Each side gets the next colour the first time it is seen and keeps it for as long as the page is open, so the same side has the same colour every frame. The first side seen gets today's enemy red. A seventh side goes back to the first colour.
  • scene.js and topdown.js: enemy colours now come from that palette. The 3D view and the map share one record of which side has which colour, so they agree.
  • presence.js: last-seen marks remember side, so their outlines match the body.
  • src/engine/body.ts: side is optional in the contract. If it is sent, it must be a string.

Tests

  • 3 sides: scene.test.ts and a new topdown.test.ts draw three enemy sides and get three different colours. The next frame, with the bodies listed in reverse order, gives the same colours.
  • No side: the same two files pin today's exact colours: #3f9fd6/#d8483f and the mark outline in the 3D view, #4fb3d9/#e35d5b on the map.
  • Mates and the dead: a mate or a dead body that carries a side stays blue or grey.
  • Elsewhere: sides.test.ts covers the colour picker, plus small additions to presence.test.ts, body.test.ts and boundary.test.ts. val's real-snapshot test from #41 still passes.

Decisions

  • No fixed colour per side name: colours go by first sighting, not by the side's name. Two players may see the same side in different colours. Naming fixed colours by side would collide too often with three sides and six colours.
  • Health bar and chevron unchanged: the enemy's health-bar amber and the chevron stay the same for every side, because they mean "enemy", not "which enemy".

Not done

  • Nothing in val sends side, so the preview can't show the new colours. In the preview, just check that it looks unchanged: start a round, and teammates should be blue and enemies red, in both the 3D view and the map.
  • The record of side colours is never cleared within a page. It only grows with the number of different sides seen.
  • I booted the app and confirmed / loads and the client bundle includes the new module. I haven't played it in a browser.

🤖 Generated with Claude Code

Closes #42

merged this
Sign in to join this conversation.

↑↓ navigate ↵ open esc close

Keyboard shortcuts