<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle">
  <channel>
    <title>Tetris Redux</title>
    <link>https://tetris-leaderboard.jimmys.dev/appcast.xml</link>
    <description>Auto-updates for Tetris Redux</description>
    <language>en</language>
    <item>
      <title>Version 0.1.3</title>
      <pubDate>Mon, 25 May 2026 04:41:02 +0000</pubDate>
      <sparkle:version>1779684051</sparkle:version>
      <sparkle:shortVersionString>0.1.3</sparkle:shortVersionString>
      <sparkle:minimumSystemVersion>13.0</sparkle:minimumSystemVersion>
      <description><![CDATA[
<style>
  body { font-family: -apple-system, sans-serif; padding: 8px 16px; line-height: 1.45; }
  h2 { color: #5a5fa8; margin: 16px 0 4px; font-size: 16px; }
  h3 { color: #94402f; margin: 14px 0 4px; font-size: 14px; border-bottom: 1px solid #ddd; padding-bottom: 2px; }
  ul { margin: 4px 0 8px 0; padding-left: 22px; }
  li { margin: 2px 0; }
  p  { margin: 6px 0; color: #444; font-size: 12px; }
</style>
<h2>Tetris Redux — Changelog</h2>
<h3>Unreleased</h3>
<h3>0.1.3 - 2026-05-25</h3>
<ul>
<li>Title screen now shows your <strong>local top-5</strong> instead of the global panel.</li>
</ul>
<p>  The global leaderboard moved into the pause menu under a "GLOBAL TOP 10"</p>
<p>  item — accessible but not in your face every time you open the app.</p>
<ul>
<li><strong>Fixed level progression when starting above 0.</strong> Previously level was</li>
</ul>
<p>  `max(startingLevel, totalLines/10)`, which meant starting at L4 required</p>
<p>  *50* line clears before reaching L5. Now level advances every 10 lines</p>
<p>  *relative to the chosen starting level* — L4 → L5 after 10 lines, etc.</p>
<ul>
<li>Pause menu: new `GLOBAL TOP 10` row opens a full sub-view of the global</li>
</ul>
<p>  leaderboard. ESC (or Enter) returns to the menu, then ESC again resumes</p>
<p>  the game as before.</p>
<h3>0.1.2 - 2026-05-25</h3>
<ul>
<li>Default starting level is now <strong>4</strong> (was 0). It's the first level with</li>
</ul>
<p>  painted artwork and the music's baseline tempo, so a fresh game lands on</p>
<p>  meaningful difficulty immediately. Settings still lets you pick 0–19.</p>
<ul>
<li>Background-art cycle anchored to level 4 → `back0`. Level 5 → `back1`,</li>
</ul>
<p>  etc., wrapping mod 10. Levels below 4 (only reachable via the setting)</p>
<p>  wrap to the later scenes rather than skipping the artwork.</p>
<ul>
<li>Music tempo: level 4 is now 1.0× (baseline). Each level above adds 4%</li>
</ul>
<p>  (clearly audible by level 6 — 1.08×), reaches the 2.0× cap at level 29.</p>
<p>  Levels below 4 dip below 1.0× (down to 0.75×) — "easy mode" feel.</p>
<ul>
<li><strong>Global leaderboard now visible inside the app</strong>: top-5 panel on the</li>
</ul>
<p>  title screen and in the pause overlay. Replaces the local-only HIGH</p>
<p>  SCORE line. Shows LOADING… / NO SCORES YET / LEADERBOARD OFFLINE</p>
<p>  gracefully depending on network state.</p>
<h3>0.1.1 - 2026-05-25</h3>
<ul>
<li>Leaderboard: submit every non-zero score, not just new local PBs.</li>
</ul>
<p>  Previously the global submit was gated on the new score being the local</p>
<p>  top, which suppressed submissions any time the player didn't beat their</p>
<p>  own existing local PB — even when the score would have been a global</p>
<p>  top-10. Worker already dedupes/sorts/trims, so unconditional submit is</p>
<p>  safe and gets new entries onto the global board as soon as you play.</p>
<ul>
<li>Log a one-line success/failure trace per submission so future leaderboard</li>
</ul>
<p>  issues are diagnosable from Console.app.</p>
<h3>0.1.0 - 2026-05-25</h3>
<ul>
<li>First versioned release.</li>
<li>Native Swift / SpriteKit reimplementation, fully replaces the abandoned</li>
</ul>
<p>  NullpoMino-on-Apple-Silicon attempt.</p>
<ul>
<li>Real-time chiptune music rendered directly from the original Game Boy</li>
</ul>
<p>  Tetris GBS file via a bundled `gbsplay` emulator — no recordings, no</p>
<p>  audio file, no loop seam.</p>
<ul>
<li>Pitch-preserving per-level tempo scaling (`AVAudioUnitTimePitch`),</li>
</ul>
<p>  flat through level 4, ramps to 2.0× by L37.</p>
<ul>
<li>Tetris Classic 1992 Pushkin background art for the 10 levels, decoded</li>
</ul>
<p>  from the original game's LZEXE-packed/PKWARE-DCL-compressed assets.</p>
<p>  Native 320×200 PNGs scaled nearest-neighbour at render time — no blur.</p>
<ul>
<li>Per-level playfield-border colour, sampled from each scene's painted</li>
</ul>
<p>  alcove so the drawn border merges with the artwork.</p>
<ul>
<li>Block sprites lifted from the Tetris Classic 1992 VGA tile set.</li>
<li>File-backed, versioned high-score store at</li>
</ul>
<p>  `~/Library/Application Support/Tetris/highscores.json`, with rolling</p>
<p>  per-save backups. Top 20 retained.</p>
<ul>
<li>Configurable starting level (0–19) and slide time (lock-delay</li>
</ul>
<p>  duration). All QOL toggles bypassable via the "1989 Mode" master</p>
<p>  switch.</p>
<ul>
<li>Press Start 2P (SIL OFL) for all UI text.</li>
<li>Volume meter drawn as cells (Press Start 2P doesn't ship block glyphs).</li>
<li>40 unit tests covering gravity, scoring, randomisers, board mechanics,</li>
</ul>
<p>  starting level, pause/spawn lifecycle — run on every build.</p>
<ul>
<li>Auto-update via Sparkle 2.x, appcast served at</li>
</ul>
<p>  https://tetris-leaderboard.jimmys.dev/appcast.xml</p>
<ul>
<li>Global top-10 leaderboard at the same domain (Cloudflare Worker + KV).</li>
</ul>
]]></description>
      <enclosure
        url="https://f003.backblazeb2.com/file/jimmys-pinball/Tetris-0.1.3.zip"
        type="application/octet-stream"
        sparkle:edSignature="y/AgZ6s0in4v/4V/IILaQONiGlLBVvhkIGzjyc3vezVuoqyEdI/R9KzczPOEFK7hrwer1bhyaIucAUPOGqUWDw==" length="7118554" />
    </item>
  </channel>
</rss>
