<feed xmlns='http://www.w3.org/2005/Atom'>
<title>typerpunk/web/src/counts.js, branch main</title>
<subtitle>Rust + WASM typing game.
</subtitle>
<id>https://srdusr.com/git/typerpunk/atom?h=main</id>
<link rel='self' href='https://srdusr.com/git/typerpunk/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/typerpunk/'/>
<updated>2025-09-13T19:11:00+00:00</updated>
<entry>
<title>Rework the end screen figures, mode picker, corners and race view</title>
<updated>2025-09-13T19:11:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2025-09-13T19:11:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/typerpunk/commit/?id=0d3864bcebcdba1b1743367d0f84389fd53e37e1'/>
<id>urn:sha1:0d3864bcebcdba1b1743367d0f84389fd53e37e1</id>
<content type='text'>
End screen
- Every figure is now a dim label directly over its value, the two centred on
  each other, grouped by what they qualify: RAW and PB under WPM, ERR and
  CONSISTENCY under ACC, KEYSTROKES and CHARACTERS either side of TIME. The
  row is a grid so TIME sits on the graph's exact centre line rather than
  drifting with its neighbours' widths.
- Errors go back onto the wpm line. Their own y axis implied a magnitude a
  mistake does not have; what matters is when one happened.
- Graph hover reads "wpm ... raw ... time" - the figures first, the second
  they happened in as the qualifier.

Mode picker
- Opens from the Single Player button itself, and choosing a mode starts it:
  picking what to type and starting it are one action. The control has now
  been a chevron notched into that button, a caption between the two buttons,
  a pill above them and a chip row below them; as the button's own menu it
  needs no separate real estate at all.

Corners
- Settings and Store move to the bottom-left. The top-left is the wordmark's
  alone.
- The global racer count is gone from the home screen - it is not something
  you can act on there. The Friends control carries "N online" instead, which
  is.
- Presence: users gain a last_seen column, touched at most once a minute per
  active user on any authenticated request, and the friends list reports who
  has been seen inside a five-minute window.

Multiplayer race view
- The standings move to the middle of the screen, the space the end screen's
  graph occupies, and now include your own row rather than opponents only.
  Pinned to the top-left corner they put what you are racing against in your
  peripheral vision and left out the one bar you most need to see.

Programming mode
- Snippets carry an explanation of what the code does. Shown under the passage
  while you type in single player; in multiplayer that space belongs to the
  standings, so it waits for the end screen, where it appears either way.
</content>
</entry>
<entry>
<title>Add multiplayer bots, typing languages, and rework the UI layout</title>
<updated>2025-09-11T19:53:00+00:00</updated>
<author>
<name>srdusr</name>
<email>99972264+srdusr@users.noreply.github.com</email>
</author>
<published>2025-09-11T19:53:00+00:00</published>
<link rel='alternate' type='text/html' href='https://srdusr.com/git/typerpunk/commit/?id=a726d9f5fb56e1fd7983c5ac806d408ad78daa86'/>
<id>urn:sha1:a726d9f5fb56e1fd7983c5ac806d408ad78daa86</id>
<content type='text'>
Multiplayer
- Quick match: POST /api/multiplayer/quickmatch returns whichever room is
  still filling, or opens one. Players never see a room code; joining by
  code stays for racing specific people.
- Bots fill quick-match rooms after a short wait so a new game is never an
  empty lobby. They only ever join quick-match rooms, never a room opened
  by code. One or two per room, drawn from separate ~40 and ~80 WPM tiers so
  two bots are never near each other's pace, and they stall to correct
  mistakes rather than typing a clean straight line.
- Live player count via GET /api/multiplayer/online, shown on the
  Multiplayer control and under the main menu's Multiplayer button.
- Per-racer colours: you are the theme accent, opponents take distinct hues
  that stay the same from lobby to race.
- The countdown no longer holds the room lock for its full three seconds,
  which is what reset clients mid-countdown.

Typing languages
- 16 languages for the generated-word modes, each with its own
  high-frequency vocabulary rather than a translation of the English list.
- Picker in the top-right rail; non-English uses its own list at every
  difficulty tier instead of falling back to English words.

Fix UTF-8 accuracy in the game core
- update_game_state mixed byte and character counts: total_characters_typed
  accumulated byte-length deltas while total_correct_characters compared a
  char index against that byte count. Equal on ASCII, so it went unnoticed;
  a correctly typed Spanish passage scored 6%. The old byte slicing would
  also have panicked if an index landed inside a multi-byte character.
  Rewritten char-based, with regression tests.

Programming mode
- Replaced prose about programming with real code: 26 syntax-highlighted
  snippets across JavaScript, Python, Rust, C/Go/Java and shell. Single-line
  by necessity, since the typing input is a single-line field.

Layout and readability
- One icon rail arrangement on every screen: Settings/Store under the
  wordmark, Language/Theme/Friends/Account top-right, Stats/Leaderboard/
  Multiplayer bottom-right.
- Main menu: mode picker moved out of the Single Player button, which it was
  notching a divider through and pushing the label off-centre.
- Escape returns to the menu, closing any open popover first, and confirms
  before abandoning a live race.
- Split --text-color and --sub-color per theme; they shared one value that
  measured 3.65:1 against the background, below the 4.5:1 body-text floor.
- Semantic colours used in exactly one place each: gold for a personal best,
  amber for the race countdown and the mobile-result badge.
- Passage now sits in the same place on the typing and end screens, and its
  column is a whole number of characters wide so wrapping cannot leave a
  permanent gap on the right.
- End screen: keystrokes and a correct/wrong/extra/missed split, attribution
  carried over from the typing screen, and a graph with a separate error
  axis, axis titles including seconds, and smoothed lines.
</content>
</entry>
</feed>
