Skip to content

Conversation

@truevox
Copy link
Owner

@truevox truevox commented Nov 13, 2025

Rebuilt the entire game from scratch with a clean, focused architecture following the design specifications in instructions.html and DESIGN-DOC.md.

Core Features:

  • 480×270 pixel-perfect resolution with proper scaling
  • Dual-mode player system (Sled/Walking with TAB toggle)
  • Full trick system: Rotation, Air Brake, Parachute
  • Combo multiplier system (1.0x + 0.25x per unique trick)
  • Procedural terrain generation with seed support
  • Three terrain types with different physics (Blue/Green/Magenta)
  • Distance-based and trick-based scoring
  • "The Bit Stream" chasing mechanic with visual effects

Visual & Effects:

  • 1-bit Tron wireframe aesthetic with neon colors
  • Parallax starfield background
  • Periodic glitch VFX (RGB split, scanlines, screen shake)
  • Particle effects for tricks and bit stream
  • Smooth camera following with offset

Technical Architecture:

  • Clean src/ structure with logical separation
  • Core systems: Player, TerrainGenerator, TrickSystem, ScoringSystem
  • Visual effects: Starfield, GlitchFX
  • Utilities: Seed generation and seeded random
  • Matter.js physics with ~900 px/s² gravity
  • Phaser 3.90 + Vite build system

The new implementation is significantly cleaner and more maintainable than the previous bloated codebase, with each system in a single focused file.

Rebuilt the entire game from scratch with a clean, focused architecture following the design specifications in instructions.html and DESIGN-DOC.md.

Core Features:
- 480×270 pixel-perfect resolution with proper scaling
- Dual-mode player system (Sled/Walking with TAB toggle)
- Full trick system: Rotation, Air Brake, Parachute
- Combo multiplier system (1.0x + 0.25x per unique trick)
- Procedural terrain generation with seed support
- Three terrain types with different physics (Blue/Green/Magenta)
- Distance-based and trick-based scoring
- "The Bit Stream" chasing mechanic with visual effects

Visual & Effects:
- 1-bit Tron wireframe aesthetic with neon colors
- Parallax starfield background
- Periodic glitch VFX (RGB split, scanlines, screen shake)
- Particle effects for tricks and bit stream
- Smooth camera following with offset

Technical Architecture:
- Clean src/ structure with logical separation
- Core systems: Player, TerrainGenerator, TrickSystem, ScoringSystem
- Visual effects: Starfield, GlitchFX
- Utilities: Seed generation and seeded random
- Matter.js physics with ~900 px/s² gravity
- Phaser 3.90 + Vite build system

The new implementation is significantly cleaner and more maintainable than the previous bloated codebase, with each system in a single focused file.
@netlify
Copy link

netlify bot commented Nov 13, 2025

Deploy Preview for bitstream-bluffs ready!

Name Link
🔨 Latest commit 4bb3ac1
🔍 Latest deploy log https://app.netlify.com/projects/bitstream-bluffs/deploys/691693cbe9d41a000866815e
😎 Deploy Preview https://deploy-preview-14--bitstream-bluffs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @truevox, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request represents a complete rewrite of the 'Bitstream Bluffs' game, moving from a 'bloated codebase' to a significantly cleaner and more maintainable architecture. The primary goal was to align the implementation with detailed design specifications, resulting in a game with enhanced core mechanics, a distinct visual style, and a well-organized technical foundation.

Highlights

  • Complete Game Rebuild: The entire 'Bitstream Bluffs' game has been rebuilt from scratch, focusing on a clean, modular architecture to replace a previous bloated codebase.
  • Core Gameplay Features: Implemented a 480x270 pixel-perfect resolution, a dual-mode player system (Sled/Walking), a full trick system with combo multipliers, procedural terrain generation with varied physics, distance and trick-based scoring, and 'The Bit Stream' chasing mechanic.
  • Visual & Effects Overhaul: Features a distinct 1-bit Tron wireframe aesthetic with neon colors, a parallax starfield background, periodic glitch visual effects (RGB split, scanlines, screen shake), and particle effects for tricks and the bit stream.
  • Modular Technical Architecture: The codebase is structured with logical separation into 'core', 'effects', and 'utils' modules, utilizing Phaser 3.90, Matter.js physics (with ~900 px/s² gravity), and Vite for the build system.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is an excellent and comprehensive rebuild of the game with a much cleaner, modular architecture. The code is well-structured and follows modern JavaScript practices. I've found a few critical issues related to performance and core mechanics, as well as some opportunities for improvement in code structure and gameplay design. My main concerns are a memory leak in the starfield effect, a fragile ground detection system for the player, and an encapsulation issue in the trick system. Addressing these will significantly improve the game's stability and maintainability. Great work on this major refactoring!

Comment on lines +50 to +57
for (let star of this.stars) {
const screenY = star.graphic.y - cameraY * star.graphic.scrollFactorY;

// If star is way above camera, move it below
if (screenY < cameraY - 500) {
star.graphic.y = cameraY + 500 + Math.random() * 1000;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The star recycling logic in the update method is incorrect. The condition screenY < cameraY - 500 compares a screen-space-like coordinate (screenY) with a world-space coordinate (cameraY), which will not work as intended. This will prevent stars from being recycled correctly as the player moves down the screen, leading to an accumulation of game objects over time. This will cause significant performance degradation and memory leaks in a long play session.

The condition should compare the star's rendered screen position with the screen boundaries to determine if it's out of view.

        for (let star of this.stars) {
            const displayY = star.graphic.y - cameraY * star.graphic.scrollFactorY;

            // If star is above the camera's view, move it below
            if (displayY < -20) { // -20 is a buffer
                star.graphic.y = cameraY + this.scene.cameras.main.height + Math.random() * 500;
                star.graphic.x = Math.random() * 480; // Also randomize x to prevent patterns
            }
        }

Comment on lines +108 to +121
updateGroundCheck(deltaSeconds) {
// Simple ground check based on vertical velocity
const velocity = this.sprite.body.velocity;
const angularVelocity = Math.abs(this.sprite.body.angularVelocity);

// Consider grounded if moving slowly vertically and not spinning much
const wasOnGround = this.onGround;
this.onGround = Math.abs(velocity.y) < 2 && angularVelocity < 0.5;

// Detect landing (transition from air to ground)
if (!wasOnGround && this.onGround) {
this.onLanded();
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The current ground detection mechanism in updateGroundCheck is based on vertical velocity and angular velocity. This approach can be unreliable on steep slopes or during minor bumps, potentially causing the player to be incorrectly considered airborne. This can negatively impact core gameplay mechanics like jumping and landing tricks.

A more robust solution would be to use Matter.js's collision events. The handleCollision method is already set up for this purpose but is currently empty. By implementing collision detection, you can more accurately determine when the player is on the ground.

Comment on lines +37 to +42
if (player.isRotating) {
const previousRotation = player.totalRotation;
const currentAngle = player.sprite.rotation;
const angleDiff = Phaser.Math.Angle.Wrap(currentAngle - player.rotationStartAngle);

player.totalRotation = angleDiff;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The update method in TrickSystem directly modifies player.totalRotation. This violates encapsulation, as one system is directly changing the internal state of another. The Player class should be responsible for managing its own state, including its rotation.

This logic should be moved into the Player.update method to improve code structure and maintainability.

            // This logic should be moved to the Player class.
            // The TrickSystem should not modify the player's state directly.

Comment on lines +66 to +70
this.bitStream = {
y: -200,
speed: 0.5,
active: true
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The "Bit Stream" chasing mechanic currently moves at a constant speed (this.bitStream.speed: 0.5). This might not provide a consistent challenge, as it could be too easy to outrun on fast sections or impossible to escape on slow sections. Consider making the Bit Stream's speed dynamic. For example, its speed could gradually increase over time, or it could adjust to maintain a certain distance from the player, making it a more relentless and fair threat.

…bility

Fixed particle emitter creation to use Phaser 3.60+ API syntax.

Changes:
- Updated Player.js: Changed from particles.createEmitter() to add.particles()
- Updated GameScene.js: Same fix for bit stream particles
- Used 'emitting: false' instead of calling .stop() on initialization

The old ParticleEmitterManager.createEmitter() was removed in Phaser 3.60.
New syntax: scene.add.particles(x, y, texture, config)
…bility, correcting syntax and control methods

Fixed particle emitter control methods to use Phaser 3.60+ API.

Changes in Player.js updateVisuals():
- Changed .start() to .emitting = true
- Changed .stop() to .emitting = false
- Changed .setFrequency() to .frequency = value (direct property assignment)
- Changed .setTint() to .setParticleTint() (new method name)

The Phaser 3.60+ particle system uses properties and new method names instead of the old emitter methods.
Major improvements to terrain generation and camera system:

Terrain Changes:
- Replaced flat rectangular platforms with actual angled slopes (10-45°)
- Each slope segment is a rotated Matter.js rectangle with proper physics
- Terrain flows downhill naturally with horizontal variation
- Slopes have varying lengths (80-180 units) for dynamic gameplay
- Maintains three terrain types (blue/green/magenta) with friction properties

Camera Changes:
- Adjusted lerp factors for smoother X and Y following (0.08, 0.2)
- Increased follow offset to -60 for better view ahead
- Camera now properly tracks player movement in both directions

Physics:
- Angled terrain bodies provide realistic downhill sledding
- Horizontal variation creates natural left/right movement
- Proper friction values maintained per terrain type

Visual:
- Slopes drawn with proper geometry (parallelograms)
- Wireframe borders and center lines for Tron aesthetic
- Terrain redraws efficiently as player progresses

This creates proper downhill sledding gameplay with slopes instead of flat platforms.
- Widened starting platform from 200 to 400 units (x=40 to x=440)
- Player spawns at (240, 100) which is now centered on the platform
- Increased starting platform thickness from 15 to 20 for better visibility
- Slopes now begin from the end of starting platform (x=440) for smooth transition

This prevents the player from spawning over void and falling before reaching slopes.
The terrain platform center was at y=100 with thickness 20, meaning:
- Top edge at y=90
- Bottom edge at y=110

Player spawning at y=100 was inside the terrain body.

Fixed by moving platform center to y=110:
- Top edge now at y=100 (player sits on surface)
- Bottom edge at y=120
- Slopes now start from y=110 to connect properly

Player now spawns correctly on top of the starting platform.
Implemented dynamic camera leading that anticipates player movement:

Camera Leading System:
- Leads by up to 4 player widths (~96 units) when at full speed
- Centered on player when stopped
- Smoothly interpolates based on current velocity
- Follows direction of movement (not just horizontal)

Technical Details:
- Max lead at 15 units/second velocity (good clip speed)
- Lerp factor of 0.05 for smooth camera transitions
- Less vertical leading (30%) to keep player visible
- Directional leading based on velocity angle

This creates the industry-standard 'look-ahead' camera that shows where you're going, making it easier to react to upcoming terrain and obstacles.

The camera now:
- Shows more terrain ahead when moving fast
- Stays centered when stationary
- Anticipates turns and slopes
- Feels more responsive and professional
The camera was locked to 480 units wide (screen width), preventing any left/right following.

Changed camera bounds from:
- Old: (0, 0, 480, 100000) - no horizontal scrolling possible
- New: (-2000, 0, 4000, 100000) - 4000 units wide for horizontal movement

This allows:
- Camera to follow player left/right as terrain varies
- Velocity-based leading to work horizontally
- Player to move across the horizontal game space

The terrain already generates with horizontal variation, now the camera can actually follow it.
Fixed two critical camera issues:

1. Camera Leading Inverted:
   - Camera offset was backwards - showing behind instead of ahead
   - Phaser's followOffset is inverted: negative offset = look ahead
   - Changed to: targetLeadX = -cos(angle) × maxLead (negative!)
   - Changed to: targetLeadY = -sin(angle) × maxLead (negative!)
   - Increased vertical leading from 0.3 to 0.5 for better downhill view

2. Expanded Camera Bounds:
   - Increased from 4000 to 20000 units wide (x: -10000 to +10000)
   - Prevents camera from hitting bounds and stopping

3. Bit Stream Visual Fixed:
   - Now follows camera position (camX) instead of fixed x=0
   - Spans across camera width dynamically
   - Particles centered on camera view

4. Increased camera lerp speed from 0.05 to 0.08 for more responsive following

The camera now properly leads ahead in the direction of movement!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants