Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# Bitstream Bluffs 🎿⚡

A neon-soaked, downhill sledding game with a 1-bit Tron-wireframe aesthetic. Ride procedurally generated mountains, perform tricks, and stay ahead of **The Bit Stream**!

## 🎮 How to Play

### Controls

#### Sled Mode (Default)
- **TAB**: Toggle between Sled and Walking modes
- **W/S**: Rotate counterclockwise/clockwise (perform rotation tricks in air)
- **A**: Drag to slow down (ground) / Air Brake trick (air)
- **D**: Tuck to accelerate (ground) / Parachute trick (air)
- **SPACE**: Jump
- **SHIFT**: Restart game
- **ESC**: Pause

#### Walking Mode
- **A/D**: Move left/right
- **SPACE**: Small jump
- **W/S**: No effect in walking mode

### Tricks & Scoring

**Tricks** (perform in mid-air):
- **Rotation**: 200 points × rotations (W/S keys)
- **Air Brake**: 150 points (A key)
- **Parachute**: 200 points (D key)

**Combo System**:
- Chain multiple tricks in one jump for bonus multipliers
- Multiplier increases by 0.25× for each unique trick
- Resets when you land

**Scoring**:
- Distance: +1 point per meter traveled
- Tricks: Base points × combo multiplier
- Blue Terrain: Bonus points while riding

### Terrain Types

- **Blue** (0x0088ff): Awards bonus points while riding
- **Green** (0x00ff44): Low friction - go faster!
- **Magenta** (0xff00aa): High friction - slows you down

### The Bit Stream

A relentless glitch wall chases you down the mountain. Keep moving or get consumed!

## 🛠️ Technical Details

### Stack
- **Phaser 3.90**: Game framework
- **Matter.js**: Physics engine
- **Vite**: Build tool and dev server
- **ES6 Modules**: Clean, modern JavaScript

### Architecture

Clean, focused implementation with minimal dependencies:

```
src/
├── main.js # Entry point & Phaser config
├── scenes/
│ ├── BootScene.js # Initial boot
│ ├── PreloadScene.js # Asset loading
│ └── GameScene.js # Main gameplay
├── core/
│ ├── Player.js # Player physics & controls
│ ├── TerrainGenerator.js # Procedural terrain
│ ├── TrickSystem.js # Trick tracking & combos
│ └── ScoringSystem.js # Score calculation
├── effects/
│ ├── Starfield.js # Parallax background
│ └── GlitchFX.js # Periodic glitch effects
└── utils/
└── seedUtils.js # Seeded random generation
```

### Features

✅ **480×270 pixel-perfect resolution** with scaling
✅ **Procedural terrain generation** with seed sharing
✅ **Three terrain types** with different physics properties
✅ **Full trick system** with combos and multipliers
✅ **The Bit Stream** chasing mechanic
✅ **1-bit Tron wireframe aesthetic** with neon colors
✅ **Parallax starfield** background
✅ **Periodic glitch VFX** (RGB split, scanlines, screen shake)
✅ **Sled/Walking mode toggle**
✅ **Seed-based random generation** for shareable runs

## 🚀 Development

### Setup
```bash
npm install
```

### Run Dev Server
```bash
npm run dev
```
Opens at `http://localhost:5173`

### Build for Production
```bash
npm run build
```

### Preview Production Build
```bash
npm run preview
```

## 🎨 Design Philosophy

This rebuild follows the principle of **simplicity over complexity**:

- **Single-file systems**: Each core system is self-contained
- **Minimal abstraction**: Direct, readable code over complex architecture
- **Performance-first**: Efficient rendering and physics
- **Quick iteration**: Clean structure for easy modifications

Built from the ground up following:
- `/public/docs/instructions.html` (game mechanics)
- `/docs/DESIGN-DOC.md` (technical specifications)

## 📋 Game Specifications

- **Resolution**: 480×270 (virtual), scaled to fit
- **Physics**: Matter.js at ~900 px/s² gravity
- **Target FPS**: 60 (PC), 30-60 (mobile)
- **Retry Loop**: < 10 seconds
- **Visual Style**: 1-bit Tron wireframe with neon palette

## 🎯 Future Enhancements

- Leaderboard system with 3-character initials (IndexedDB)
- Additional hazards and power-ups
- Mobile touch controls
- Music and sound effects
- More terrain variety
- Perfect landing detection
- Replay system

## 📝 Version

**2.0.0** - Complete rebuild with clean, focused architecture

---

Built with ⚡ by Claude Code
106 changes: 17 additions & 89 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,111 +3,39 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>BitstreamBluffs</title>
<!-- Load Phaser from CDN -->
<script src="https://cdn.jsdelivr.net/npm/phaser@3.80.1/dist/phaser.min.js"></script>

<!-- Load retro game fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=VT323&display=swap" rel="stylesheet">

<!-- Font preloader script to ensure fonts are loaded before game starts -->
<script>
// Store a reference to when fonts are ready
window.fontsLoaded = false;

// Function to check if fonts are loaded
function checkFontsLoaded() {
if (document.fonts && document.fonts.check) {
// Modern browsers - use Font Loading API
const isPressStartLoaded = document.fonts.check('1em "Press Start 2P"');
const isVT323Loaded = document.fonts.check('1em "VT323"');

window.fontsLoaded = isPressStartLoaded && isVT323Loaded;

if (!window.fontsLoaded) {
// Try again in 100ms
setTimeout(checkFontsLoaded, 100);
}
} else {
// Fallback for browsers without Font Loading API
// Set a timeout to allow fonts to load
setTimeout(function() {
window.fontsLoaded = true;
}, 1000); // Give fonts 1 second to load
}
}

// Start checking fonts
checkFontsLoaded();

// Start computing the game seed early
// This will trigger the SHA-256 computation in the background
window.earlySeedGeneration = true;

// Preload fonts with invisible elements
document.addEventListener('DOMContentLoaded', function() {
// Create and add elements with our custom fonts
const pressStartPreloader = document.createElement('div');
pressStartPreloader.style.fontFamily = '"Press Start 2P"';
pressStartPreloader.style.position = 'absolute';
pressStartPreloader.style.visibility = 'hidden';
pressStartPreloader.textContent = 'BITSTREAM BLUFFS';
document.body.appendChild(pressStartPreloader);

const vt323Preloader = document.createElement('div');
vt323Preloader.style.fontFamily = 'VT323';
vt323Preloader.style.position = 'absolute';
vt323Preloader.style.visibility = 'hidden';
vt323Preloader.textContent = 'SEED';
document.body.appendChild(vt323Preloader);

// Additionally trigger a check after DOM is loaded
checkFontsLoaded();
});
</script>

<!-- Load our game modules -->
<script type="module">
// Import our main game script which will handle loading all other modules
import './js/main.js';
</script>
<title>Bitstream Bluffs</title>
<style>
html, body {
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

html, body {
width: 100%;
height: 100%;
background-color: #000000; /* Black background for the page */
overflow: hidden; /* Prevent scrollbars on the page itself */
touch-action: none; /* Prevent default touch behaviors like pinch zoom */
background: #000;
overflow: hidden;
font-family: 'Courier New', monospace;
}
#game-container {

#game {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}

canvas {
display: block; /* Removes default inline spacing */
width: 100%;
height: 100%;
object-fit: contain; /* Maintains aspect ratio */
}

/* Hide address bar on mobile devices when possible */
@media screen and (max-width: 768px) {
html {
height: calc(100% + 60px);
}
display: block;
image-rendering: pixelated;
image-rendering: crisp-edges;
}
</style>
</head>
<body>
<div id="game-container"></div>
<div id="game"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading