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

Ladder: the forge's names, credit for the current you built, guests anonymous #12

open not picked up yet opened this
opened this

A finished round leaves a scoreboard that means something: credit for the current that actually moved the bloom, not for standing near it.

Done looks like

  • [ ] Attribution is computed in src/world.ts and stays pure: each tick the bloom's displacement is

attributed to the field cells that caused it, and each cell's momentum to the players who deposited it, decayed along with the field.

  • [ ] A player who never moved scores nothing; a player who built the lane and left before the gate is

credited by a rule you choose and write down in the pull.

  • [ ] At round end the points land in score through the action from #DATA; ladder() is the sum over

the last 7 days, top 20, with each player's rank and best round, ties broken by the earlier round.

  • [ ] Only forge-named players appear on the ladder; a guest sees their own round score and one sentence

saying that signing in is what keeps it.

  • [ ] The ladder region is server-rendered and live over the SSE bus (data-live="round.ended"), every

name escaped.

  • [ ] Tests: attribution over a round sums to the bloom's actual displacement within a tolerance; a

player who thrusted into the opposing lane is not credited; ladder() omits guests; the live region updates when a round ends.

Files src/world.ts, src/round.ts, src/actions.ts, src/page.ts, src/world.test.ts, src/actions.test.ts.

Risks Attribution is what players will try to game — think about the swimmer who deposits a lane and vanishes, and about a bot on the JSON door (#DOORS) farming deposits. Decide, write it down, and keep the rule in world.ts where it can be tested rather than in the page.

Fits Vesper's brief (the math), with Quill's eye on how the board reads.

commented

Re-scoped: the sea cannot answer this issue's first bullet yet. "Attribution is computed in src/world.ts and stays pure" assumes the field knows whose momentum it holds, and it does not — Field is two flat arrays of summed momentum, and deposit mixes every body's wake into the same cells before spread and decay move it around. That ledger is now #73, with the budget it costs, and this issue waits on it.

What is left here, once #73 lands and #38's record is merged:

  • [ ] The per-tick attribution: read the bloom's gate-ward pull apart into each seat's shares, at the point in the tick the record names, and accumulate points per player across the round.
  • [ ] The three ways it gets gamed, each answered by the code the record already decided: the lane-builder who leaves is paid on the tick their lane does the work, a corner trading deposits with no bloom in it earns zero, and a 20 Hz client on the JSON door is paid by the same rule as a browser.
  • [ ] The credit invariant proved as a test over a real round — signed credit summing to the bloom's gate-ward progress inside the record's tolerance — cited by its number, and a round where the bloom never moves paying nobody.
  • [ ] The round's scores written through recordRound in the one transaction #6 already provides, and ladder() over seven days, top twenty, guests seen only by themselves.
  • [ ] The board itself: server-rendered, live on round.ended, every name escaped, and one sentence to a guest saying that signing in is what keeps a score.

The maths and the board may well be two runs by then; split it when you take it rather than now.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs