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

forked from trevato/cs

The map you played has a name you can keep: the seed on the menu, in the URL, and a link that plays it again #148

shipped production is serving it opened this has it
opened this

A generated map is carved from the match id, so a map you liked is gone the moment the match ends — you cannot play it again, and you cannot hand it to anyone.

generateLevel(seedFrom(matchId)) makes a new layout per match and nameOf already gives it a short name (gen_14u5j6g, base36 of the seed). The name is shown once the match starts and never anywhere you could use it. A seeded generator whose seed is unreachable is a slot machine; one you can name is a map pool.

Done looks like

  • [ ] The menu's Map control takes a name as well as the two choices it has: de_forge, generated — a new one every match, or a seed a person typed, validated at the boundary — gen_ and base36 only, anything else falls back to de_forge the way every unknown value here does.
  • [ ] The name of the map about to be played is shown before Play, not after, and the generated-every-match option shows the name it just drew so a player can write it down.
  • [ ] / accepts ?map=gen_14u5j6g and preselects it: the server validates the parameter, escapes it where it is rendered, and never passes an unvalidated string to the client. An invalid or absurd value renders the default with no error page.
  • [ ] A copy-this-map control next to the name puts the full URL on the clipboard, and is a link a keyboard can reach and a thumb can hit (44px), not a JavaScript-only affordance: it is an <a href> that works when clicked normally.
  • [ ] The same seed gives the same map on every machine, and a test says so: generate from a name, render the level's cells to a digest through the engine's digest door, and pin it.
  • [ ] Nothing about the match id changes: the id still seeds a match that asked for a new map, and a named map overrides it.

Files I expect to change

src/client/generate.ts (a seedOf(name) beside nameOf), src/client/main.ts, src/pages/game.ts, src/server.ts (reading and validating the query), src/client/generate.test.ts, src/server.test.ts, static/app.<hash>.js.

Risks

  • A query parameter that reaches the page is an input: validate it on the server, escape it in the markup, and let the client validate it again from the field. Two checks, neither trusting the other.
  • Keep the shooter's own ?map= out of the other two games' pages; it is this game's parameter, not the app's.

Suggested: Torque — a state you can reproduce from a URL is the brief.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs