Skip to content

Update puzzle block game - #809

Merged
epompeii merged 3 commits into
develfrom
u/ep/tetris
Apr 24, 2026
Merged

Update puzzle block game#809
epompeii merged 3 commits into
develfrom
u/ep/tetris

Conversation

@epompeii

Copy link
Copy Markdown
Member

This changeset updates the easter egg puzzle block game.

@github-actions

github-actions Bot commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

🤖 Claude Code Review

PR: #809
Base: devel
Head: u/ep/tetris
Commit: 13cc76017d5121682e4acc1176defb9dbff2f17d


Here's my review:


PR Review: Tetris.astro Rewrite

Scope: Complete rewrite of the Tetris easter egg — from ~366 lines to ~1546 lines. Adds hold piece, next-piece preview queue, SRS wall kicks, particle effects, Web Audio sound, mobile-responsive layout with touch controls, DAS/ARR auto-repeat, pause, mute, high score persistence, and ghost piece.

Issues

1. Attribution removed (line 1)
The original file had a comment crediting the source gist: <!-- https://gist.github.com/straker/3c98304f8a6a9174efd8292800891ea1-->. The rewrite drops it entirely. If any of the original logic remains (piece definitions, basic collision), the attribution should be preserved.

2. localStorage usage without feature-detection guard (lines 1419, 1452-1456, 1469, 1533-1536)
The try/catch blocks around localStorage calls are fine for environments where it throws (private browsing), but localStorage is accessed in multiple spots with slightly inconsistent error handling. The toggleMute function at line 1419 has its own try/catch, but if localStorage.setItem throws due to quota, the mute state will still be toggled in memory — this is probably fine but worth noting.

3. Duplicate initialization code (lines 1451-1457 vs 1532-1539)
S.muted and S.highScore are loaded from localStorage in two places: once in startGame() (line 1452-1456) and once at module init (line 1533-1536). The module-init load runs at page load (before first game), and startGame() re-reads them. The duplicate read in startGame() is harmless but unnecessary — highScore is already updated in gameOver() and muted is updated in toggleMute().

4. Touch event handler uses Date.now() for timing (line 1338)
The touchStart object stores Date.now() for gesture velocity detection. This works but is inconsistent with the rest of the game which uses requestAnimationFrame timestamps. Not a bug, just a minor inconsistency.

5. No cleanup on component unmount
Event listeners are added to window and document (lines 1249, 1257, 1316) but never removed. If this component is ever dynamically mounted/unmounted in SolidJS routing, these will leak. For a static Astro page this is acceptable, but rAF and intervals would also continue running.

6. btnRepeatTimer mixed setTimeout/setInterval with single variable (lines 1378-1405)
The bindBtn function stores both a setTimeout return and a setInterval return in the same btnRepeatTimer variable. The stop handler calls both clearTimeout and clearInterval on it, which works in practice since the timer IDs come from the same pool in browsers, but it's fragile and non-obvious.

7. Global scope pollution (line 344-1546)
The entire game is in a bare try { } block in a <script> tag. All identifiers (S, COLS, ROWS, canvas, etc.) are module-scoped in Astro's default script processing, so this should be fine. The try/catch at the top level (line 345 / 1543) silently swallows all errors with just a console.error — any runtime bug during gameplay would crash silently.

8. Particle array management (lines 1026, 1045)
Particles are capped at 100 via splice(0, length - 100) which removes the oldest. This is fine for performance, but during a Tetris clear + immediate hard drop, both spawnImpactParticles and spawnLineClearParticles run the cap independently, meaning the effective cap could briefly reach ~200 before the next render trims it.

Minor / Style Notes

  • No Biome formatting verified — Console CLAUDE.md requires Biome formatting. The file uses tabs consistently which is good, but should be verified with npx biome format --check services/console/src/components/site/Tetris.astro.
  • CSS uses scoped custom properties — Clean approach with --t-* variables in .tetris-game. The styles don't conflict with Bulma. The old version used Bulma classes (columns, is-centered, button); the new version is fully self-contained, which is better.
  • Accessibility — Good: aria-label attributes on canvas and mobile buttons. The keyboard handling properly calls preventDefault() to avoid scroll interference.
  • webkitAudioContext fallback (line 1066) — Good for older Safari compatibility.
  • CLAUDE.md compliance — No set:html usage (good). No manually edited generated types. The component is pure Astro + vanilla JS, not SolidJS, which is appropriate for a self-contained game.

Summary

This is a solid rewrite that transforms a basic Tetris into a polished, mobile-friendly game with proper SRS rotation, DAS, particles, and sound. The main actionable items are: (1) restore the original attribution comment, (2) deduplicate the localStorage init, and (3) run Biome to verify formatting. The rest are minor observations, not blockers.


Model: claude-opus-4-6

@epompeii epompeii changed the title tetris Update puzzle block game Apr 23, 2026
@epompeii
epompeii force-pushed the u/ep/tetris branch 2 times, most recently from 950040d to 3f4500e Compare April 23, 2026 04:00
@epompeii
epompeii merged commit 1cb2b59 into devel Apr 24, 2026
40 checks passed
@epompeii
epompeii deleted the u/ep/tetris branch April 24, 2026 01:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant