A nostalgic late 1990s website featuring a PHP-driven sliding puzzle game compatible with Netscape Navigator 4.04 and Internet Explorer 3.0.
- Netscape Navigator 4.04
- Internet Explorer 3.0
No modern JavaScript, CSS3, or HTML5. Intentionally retro HTML with <table> layouts, <font> tags, and deprecated attributes.
Pure PHP, no JavaScript for game logic. All interactions via page reloads with session state in URL parameters.
- Session Management: URL-based
sidparameter (no cookies) - Template Pattern: Output buffering (
ob_start/ob_get_clean) with master layout - MVC-like Views: Puzzle render functions use separate template files (
puzzle/views/) - Image Processing: PHP GD library with MD5-based hierarchical cache
- Visitor Counter: Classic 90s digit-based counter (landing page only)
- Encoding: ISO-8859-1 (not UTF-8)
- 8 Levels: Progressive difficulty from 3x3 to 6x6 grids, with/without tile numbers
- Two Resolution Modes: Small (240px, centered) and Large (420px) puzzle sizes
- Scoring System: Move penalties with time bonuses (complete under 2 minutes)
- High Scores: Top 5 persistent leaderboard with file-based storage (default AI models: Claude, Gemini, ChatGPT, Grok, goph-R)
- Dedicated High Scores Page: View leaderboard separately from game start screen
- Reset Confirmation: Confirmation page before resetting game progress
- Solvable Puzzles: Guaranteed solvable via reverse-moves shuffle algorithm
- Multi-Tile Sliding: Proper 15-puzzle mechanics (click any tile in same row/column as empty space)
Flat array, row-major order: grid[position] = tile_number, where 0 = empty space.
generateSlice($src, $n, $size, $text, $small) dynamically generates tile images with:
- Blurred text shadows (4-pass Gaussian blur)
- 1px white borders
- Cache path:
puzzle/images/cache/{hash[0]}/{hash[1]}/{hash}.jpg
start -> playing -> won -> (next level or finish) -> finished -> start
All state transitions via GET parameters: action=start|next|finish|reset_confirm|highscores, move=N
Classic 90s-style counter with individual digit images:
- File-based storage in
counter.txt(incremented only on landing page) - 6-digit display with leading zeros (e.g.,
000119) getCounterDigits($number)function converts number to<img>tags- Uses digit0-9.gif images with horizontal spacing
config.php # Session setup, makeLink() helper, visitor counter function
layout.php # Master template (620px fixed width)
counter.txt # Visitor counter value (runtime, not in git)
index.php # Landing page with visitor counter
puzzle.php # Root puzzle page (bootstrap)
puzzle/
puzzle.php # Game logic, rendering, controller
img-slice.php # Image slicing functions (generateSlice, generatePreview)
highscores.dat # Serialized PHP array (runtime)
views/ # HTML templates for game screens
start.php # Start screen with play buttons
game.php # Active game grid and controls
win.php # Level completion screen
finish.php # All levels complete screen
reset-confirm.php # Game reset confirmation
highscores.php # High scores table
images/
*.jpg # Source puzzle images
cache/ # Generated tile images
start-small.jpg # UI button
start-large.jpg # UI button
next.jpg # UI button
finish.jpg # UI button
images/
digit0-9.gif # Visitor counter digit images
- Install XAMPP with PHP 7.4+ (ensure GD extension enabled in
php.ini) - Place in
C:\xampp\htdocs\retro.dynart.net\ - Start Apache
- Visit
http://localhost/retro.dynart.net/
- No
onclickon<img>tags (use<a href="...">wrappers) - No
new Image()ordocument.imagesin IE 3.0 - Netscape 4.04 drops images when loading 15+ simultaneously (solved with pre-generated cache)
- Forms use
method="GET"with hiddensidfield (most compatible)
Retro educational project - no external dependencies or frameworks.
