# Salvo Changelog

## v1.2.3 — 2026-09-27

- **Dark mode toggle** (Aaron's request — the bright page hurt his eyes):
  the standalone game now has a manual light/dark theme button next to
  "New game" (shows ☾ Dark in light mode, ☀ Light in dark mode). It
  overrides the phone's system theme and remembers the choice in the
  browser. No saved choice yet? The OS preference applies, exactly as
  before — existing players see no change until they tap the toggle.
- Gameplay untouched: no mechanics changed, so the v1.2.2 balance
  simulation (Easy 95.4 / Normal 50.8 / Hard 47.1) still stands.
- **Tests**: 12 new theme checks (toggle flips and persists, OS fallback
  when nothing is saved, reload restores the saved theme, no-throw in the
  headless harness's fake DOM); all 29 standalone + 27 widget harness
  checks re-run and passing.

- **Licensed for sharing**: CC BY-NC-SA 4.0, copyright Aaron and Nova —
  free to use or modify, not for sale. License notice stamped in both HTML
  files; full text in `LICENSE`.
- **Bug fix**: the Normal AI's checkerboard search order is now reshuffled
  on every **New game**, as v1.2.1 promised — before, it shuffled once per
  page load. (The chat widget was unaffected: one battle per load.)
- **Balance re-measured** (the wagon-trail rule: re-measure after every
  material change): new `tests/salvo-balance-sim.js` drives the real AI
  against random fleets. Computer shots to sink a fleet: Easy 95.4, Normal
  50.8, Hard 47.1 — the difficulty ladder holds. Shuffled vs fixed parity
  order: 51.9 vs 55.1 shots — the v1.2.1 "same search efficiency" claim is
  essentially true (shuffled is ~6% sharper, not duller).
- **Tests**: harnesses updated to v1.2.2; the always-true undo assertion
  replaced with real checks (cell unfired, turns reset, computer reply
  undone, button disabled); new reshuffle-per-game test; corrected the
  old "24 checks" claim to the real counts — 29 (standalone) and 27
  (widget). All pass.

## v1.2.1 — 2026-09-27
- Normal AI's checkerboard sweep is now shuffled every game (and randomly
  picks which parity color to sweep). Same search efficiency, but it no
  longer marches across the board in a visible, robotic pattern.

## v1.2.0 — 2026-09-27

- **Difficulty levels** (suggested by a Groq brainstorm, verified and built
  by Nova): Easy (computer fires randomly), Normal (checkerboard-and-hunt),
  Hard (probability-density targeting). Every level plays fair — revealed
  history only, never your unrevealed ships.
- **Turn counter and best scores**: turns tracked per game; a win records
  your best per difficulty in the browser.
- **Game-over reveal**: the computer's surviving ships are shown when the
  game ends.
- Bug fixes from a Gemini code review (each verified against the code
  before fixing):
  - Undo no longer rewinds from battle back into ship placement.
  - The hunt AI no longer mistakes two separate hits on one row/column
    for a single ship.
  - Stale turn hints cleared on the win/lose screen.
  - Tapping an already-fired cell now says so instead of silently
    ignoring it.
  - Widget state event is null-safe.
- Save key bumped to `salvo-standalone-v2` (old saves orphaned; the game
  is days old).
- Verified: 24 headless gameplay checks pass (full games on all three
  difficulties, undo, save/load round-trip, re-tap feedback, reveal
  accuracy, hint cleanup). Harness: `tests/salvo-harness.js`.
- `salvo-widget.html` (chat widget) synced to the same v1.2.0 feature set:
  difficulty chips, turn counter, per-difficulty bests (kept in widget
  state), game-over reveal, and all five bug fixes. Nova's committed fleet
  unchanged. Harness: `tests/salvo-widget-harness.js`.

## v1.1.1 — 2026-09-25

- Renamed the project from "Battleship" to **Salvo** — "Battleship" is
  Hasbro's trademark for the game title; "Salvo" is the historical public-
  domain name for the paper game. Files renamed: `salvo-widget.html`,
  `salvo-standalone.html`, `salvo-README.md`, `salvo-CHANGELOG.md`,
  `salvo-vs-aaron-2026-09-25.md`. The localStorage save key changed
  accordingly (old saves are orphaned, which is fine — the game was hours
  old). Ship class names (Carrier, Battleship, Cruiser, Submarine,
  Destroyer) are unchanged: those are generic naval terms, not the
  trademarked title.

## v1.1.0 — 2026-09-25 (standalone)

- New file: `salvo-standalone.html` — the game as a complete web page.
  Open in any browser; no server, no chat widget, no AI backend.
- The computer opponent is the same fair targeting from the widget, renamed
  from "Nova" to "Computer".
- Enemy fleet is randomized on every new game (was: one hardcoded committed
  fleet). Every game is replayable.
- New **New game** button: resets the board and deals a fresh random fleet.
- Progress auto-saves to the browser's localStorage; survives tab close.
- Slightly larger tap targets; respects the OS light/dark mode.
- KISS cleanup pass: one shared `allHit` helper replaced three hand-rolled
  hit checks; removed a redundant ship-highlight line and a duplicated
  fairness comment.
- Stack pinned in the file header (vanilla JS + HTML5 + CSS3).
- Verified: syntax check plus 16 headless gameplay tests on both save
  backends (fleet validity, new-game reset, save/load round-trip, full game
  to win, undo, illegal placement rejection, post-game input ignored).

## v1.0.0 — 2026-09-25 (chat widget)

- `salvo-widget.html`: Nova vs Aaron naval strategy game for the Muse chat.
- Fixed committed fleet (Game 2 layout; Game 1 voided over a turn bug that
  revealed the old positions).
- State persisted via the Muse widget bridge (`window.hatchWidget`).
- Nova's automatic targeting: checkerboard-and-hunt using only revealed
  hit/miss history and sunk announcements — never unrevealed ship cells.
- Run history: `salvo-vs-aaron-2026-09-25.md`.
