Commit Graph

50 Commits

Author SHA1 Message Date
e8ac3a8f0a Refactor main.ts to meet coding standards (<100 lines)
All checks were successful
Build / build (push) Successful in 1m7s
- Extract cleanup logic to src/core/cleanup.ts
- Extract XR setup to src/core/xrSetup.ts
- Extract scene/physics/audio setup to src/core/sceneSetup.ts
- Remove unused GameState enum and _gameState field
- main.ts reduced from 192 to 91 lines
- All methods now under 20 lines

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 05:01:28 -06:00
71ec1f162c Remove unused files and replay system
- Delete unused files: testLevel.ts, loginScreen.ts, controllerDebug.ts
- Remove entire replay system (ReplayManager, ReplayPlayer, ReplayCamera, etc.)
- Remove viewReplaysHandler.ts and discordWidget.ts
- Clean up related imports and references

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 04:54:54 -06:00
c0b9f772ee Refactor main.ts: extract handlers and remove dead code
- Extract analytics init to src/analytics/initAnalytics.ts
- Extract level selection handler to src/core/handlers/levelSelectedHandler.ts
- Extract replay handler to src/core/handlers/viewReplaysHandler.ts
- Extract app initialization to src/core/appInitializer.ts
- Remove unused DemoScene and demo.ts
- Remove dead code: DEBUG_CONTROLLERS, webGpu, TestLevel handler
- Add BabylonJS shader pre-bundling to fix Vite dev server issues
- Reduce main.ts from 885 lines to 211 lines

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 04:26:48 -06:00
5e67b796ba Add ESLint and refactor leaderboard to join with users table
- Add ESLint with typescript-eslint for unused code detection
- Fix 33 unused variable/import warnings across codebase
- Remove player_name from leaderboard insert (normalized design)
- Add ensureUserProfile() to upsert user display_name to users table
- Update leaderboard queries to join with users(display_name)
- Add getDisplayName() helper for leaderboard entries

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 03:52:03 -06:00
44c685ac2d Cleanup batch 5: Remove unused exported types
Made 75+ types internal (removed export keyword) across 24 files:
- Analytics event types (kept GameEventMap, GameEventName, GameEventProperties)
- Level config types (QuaternionArray, MaterialConfig, etc.)
- Ship types (SightConfig, InputState, etc.)
- Store state types (AuthState, GameConfigData, etc.)
- Various config interfaces

These types are still used internally but were never imported elsewhere.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 18:11:40 -06:00
a9ae41c7eb Fix WebXR camera setup and pointer selection timing
- Create consolidated setupXRCamera() method in Level1 to handle all XR
  camera initialization in one place
- Use intermediate TransformNode (xrCameraRig) for camera rotation since
  WebXR camera only uses rotationQuaternion which XR frame updates overwrite
- Fix pointer selection feature registration timing - must register after
  XR session starts, not during initialize()
- Move pointer registration to onStateChangedObservable and setupXRCamera()
- Don't stop render loop before entering XR as it may prevent observables
  from firing properly
- Fix audio paths in shipAudio.ts to use correct asset locations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 10:22:59 -06:00
a9070a5d8f Add leaderboard infinite scroll and improve seed script scoring
All checks were successful
Build / build (push) Successful in 1m45s
- Add pagination support to CloudLeaderboardService with offset parameter
- Implement infinite scroll in Leaderboard.svelte using IntersectionObserver
- Update seed script to use actual game scoring formulas (time, accuracy, fuel, hull multipliers)
- Add level-specific asteroid counts and par times to seed data
- Create BUGS.md to track known issues
- Partial work on XR camera orientation (documented in BUGS.md)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 12:51:43 -06:00
3ff1ffeb45 Simplify level system and add asteroid-mania level
All checks were successful
Build / build (push) Successful in 1m29s
- Add new asteroid-mania level to directory and DEFAULT_LEVEL_ORDER
- Remove level caching entirely (always fetch fresh from network)
- Delete legacy router.ts, levelSelector.ts, and levelVersionManager.ts
- Remove unused router handlers from main.ts (~120 lines)
- Fix projectile curving by cloning velocity vector in weaponSystem.ts
- Update LevelSelect.svelte to include asteroid-mania

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 15:34:23 -06:00
3f164df9e8 Add game results leaderboard system
All checks were successful
Build / build (push) Successful in 1m30s
- Create GameResultsService for storing game results in localStorage
- Create gameResultsStore Svelte store for reactive data access
- Add Leaderboard component showing top 20 scores
- Add leaderboard route and navigation link
- Record game results on victory/death/stranded (not manual exits)
- Fix header visibility when exiting game
- Fix camera error by stopping render loop after cleanup
- Clear canvas after cleanup to prevent last frame showing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 12:39:23 -06:00
28c1b2b2aa Fix routing, cleanup, and game restart issues
- Switch from svelte-spa-router to svelte-routing for clean URLs without hashes
- Fix relative asset paths to absolute paths (prevents 404s on nested routes)
- Fix physics engine disposal using scene.disablePhysicsEngine()
- Fix Ship observer cleanup to prevent stale callbacks after level disposal
- Add _gameplayStarted flag to prevent false game-end triggers during init
- Add hasAsteroidsToDestroy check to prevent false victory on restart
- Add RockFactory.reset() to properly reinitialize asteroid mesh between games
- Add null safety checks throughout RockFactory for static properties

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 11:21:05 -06:00
622e0a5259 Fix VR pointer interaction with GUI by removing restrictive picking predicate
All checks were successful
Build / build (push) Successful in 1m34s
Resolved issue where VR laser pointers could not click mission brief buttons. Root cause was scene.pointerMovePredicate filtering out GUI meshes before pointer events could reach AdvancedDynamicTexture.

Changes:
- Commented out restrictive pointerMovePredicate that blocked GUI mesh picking
- Temporarily disabled renderingGroupId=3 on mission brief for VR compatibility
- Adjusted ship physics: reduced angular force multiplier (1.5→0.5) and increased damping (0.5→0.6)

Technical details:
- WebXRControllerPointerSelection uses scene.pointerMovePredicate during pickWithRay()
- If predicate returns false, pickInfo.hit=false and GUI events never fire
- AdvancedDynamicTexture requires pickInfo.pickedMesh === mesh to process events
- Removing predicate allows default behavior (all isPickable meshes are candidates)

TODO: Re-implement predicate using renderingGroupId === 3 check for production

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 17:53:31 -06:00
e31e25f9e5 Fix physics issues: sleep behavior, center of mass, and input scaling
This commit resolves several physics-related issues that were causing
unexpected behavior in ship and asteroid movement:

**Physics Sleep System**
- Fixed abrupt stops by preventing Havok from putting bodies to sleep
- Added PhysicsActivationControl.ALWAYS_ACTIVE for ship and asteroids
- Made ship sleep behavior configurable via shipPhysics.alwaysActive
- Sleep was causing sudden velocity zeroing at low speeds

**Center of Mass Issues**
- Discovered mesh-based physics calculated offset CoM: (0, -0.38, 0.37)
- Override ship center of mass to (0, 0, 0) to prevent thrust torque
- Applying force at offset CoM was creating unwanted pitch rotation
- Added debug logging to track mass properties

**Input Deadzone Improvements**
- Implemented smooth deadzone scaling (0.1-0.15 range)
- Replaced hard threshold cliff with linear interpolation
- Prevents abrupt control cutoff during gentle inputs
- Added VR mode check to disable keyboard fallback in VR

**Configuration System**
- Added DEFAULT_SHIP_PHYSICS constant as single source of truth
- Added tunable parameters: linearDamping, angularDamping, alwaysActive
- Added fuel consumption rates: linearFuelConsumptionRate, angularFuelConsumptionRate
- Tuned for 1 minute linear thrust, 2 minutes angular thrust at 60Hz
- All physics parameters now persist to localStorage

**Other Fixes**
- Changed orbit center to STATIC motion type (was ANIMATED)
- Fixed linear force application point (removed offset)
- Added ship initial velocity support from level config
- Changed physics update from every 10 frames to every physics tick
- Increased linear input threshold from 0.1 to 0.15

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 14:03:32 -06:00
1422c5b926 Add centralized input control management and mission brief improvements
All checks were successful
Build / build (push) Successful in 1m31s
- Create InputControlManager singleton for centralized ship controls and pointer selection management
  - Last-wins behavior for state changes
  - Mutually exclusive ship controls and VR pointer selection
  - Observable events for state changes with requester tracking
  - Enables debugging and prevents conflicts between UI components

- Refactor Ship class to use InputControlManager
  - Remove disableControls() and enableControls() methods
  - Register input systems with InputControlManager on initialization
  - Simplify control state management throughout ship lifecycle

- Update StatusScreen to use InputControlManager
  - Remove manual pointer selection enable/disable methods
  - Delegate control management to InputControlManager
  - Automatic laser pointer enabling when screen shows

- Update Level1 mission brief to use InputControlManager
  - Consistent control management for mission brief display
  - Proper pointer selection during mission brief interaction

- Fix controller input trigger blocking bug
  - Triggers now properly blocked when controls disabled
  - Prevents shooting when status screen or mission brief is visible
  - Only X-button (status screen toggle) allowed when disabled

- Add START MISSION button to mission brief
  - Replace "Pull trigger to start" text with clickable button
  - Green styled button matching StatusScreen design
  - Works with VR laser pointer interaction
  - Trigger pull still works as fallback

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 17:25:11 -06:00
eccf101b73 Implement Svelte-based UI architecture with component system
All checks were successful
Build / build (push) Successful in 1m20s
Major refactoring of the UI layer to use Svelte components:
- Replace inline HTML with modular Svelte components
- Add authentication system with UserProfile component
- Implement navigation store for view management
- Create comprehensive settings and controls screens
- Add level editor with JSON validation
- Implement progression tracking system
- Update level configurations and base station model

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 15:01:17 -06:00
ff8d69b6ec Add VR controller remapping configuration system
All checks were successful
Build / build (push) Successful in 1m32s
Implement comprehensive controller remapping UI that allows users to customize
VR controller button and stick mappings with per-axis granularity and inversion
controls. Configuration persists to localStorage and applies on level start.

## Features
- Full-page controller remapping UI at #/controls
- Per-axis stick mapping (4 dropdowns: leftX, leftY, rightX, rightY)
- Individual axis inversion toggles (8 total invert options)
- Button remapping (6 buttons: trigger, A, B, X, Y, squeeze)
- Available actions: yaw, pitch, roll, forward thrust, camera, status screen
- Configuration validation with warnings for duplicates/missing controls
- Preview/test functionality to review current mapping
- Reset to default option
- localStorage persistence with backward compatibility

## Implementation
- ControllerMappingConfig singleton manages configuration and validation
- ControlsScreen handles UI logic and form manipulation
- ControllerInput applies mapping by translating raw input to actions
- Actions mapped back to virtual stick positions for ShipPhysics
- No changes needed to ShipPhysics - receives correctly mapped values

## User Flow
1. Navigate to Controls via header menu
2. Select action for each stick axis (yaw/pitch/roll/forward/none)
3. Toggle invert checkboxes as needed
4. Assign button actions (fire/camera/status/none)
5. Save configuration
6. Changes apply when starting new level

## Technical Details
- Storage key: 'space-game-controller-mapping'
- Raw stick values stored, mapping applied in getInputState()
- Supports future actions without code changes
- Validation ensures critical controls (fire, forward) are mapped

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 08:11:04 -06:00
e9ddf91b85 Implement trigger-based mission brief dismissal for VR gameplay
All checks were successful
Build / build (push) Successful in 1m33s
Add mission briefing system that displays when entering VR and requires
trigger pull to dismiss before gameplay begins. This prevents accidental
weapon firing and provides clear mission objectives to players.

## Key Features
- Mission brief displays on VR entry with objectives from directory.json
- Ship controls disabled during briefing (movement, rotation, weapons)
- Either controller trigger dismisses brief and starts game timer
- First trigger pull does not fire weapons, only dismisses briefing
- Subsequent trigger pulls fire weapons normally

## Implementation Details
- Added MissionBrief class with mesh-based UI parented to ship
- Ship class gains disableControls()/enableControls() methods
- New mission brief trigger observable bypasses normal shoot handling
- ControllerInput modified to allow triggers through when disabled
- Level1 orchestrates control flow: disable → show brief → enable
- Game timer and physics recording start only after dismissal

## Technical Changes
- controllerInput.ts: Allow trigger events when controls disabled
- ship.ts: Add control state tracking and mission brief observable
- level1.ts: Integrate mission brief into XR initialization flow
- missionBrief.ts: New class for displaying briefing with trigger detection
- Fixed property name mismatch in level selection event dispatch
- Added cache-busting for dev mode level loading
- Exposed LevelRegistry to window for debugging

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 07:44:46 -06:00
fd1a92f7e3 Add analytics abstraction layer with intelligent batching
All checks were successful
Build / build (push) Successful in 2m0s
Implements a flexible, provider-agnostic analytics system with New Relic adapter featuring intelligent event batching for cost optimization.

Features:
- Type-safe event tracking with TypeScript interfaces
- Pluggable adapter architecture for multiple providers
- Intelligent batching (reduces data usage by 70-90%)
- Event sampling for high-volume events
- Zero breaking changes to existing New Relic setup
- Debug mode for development testing

Integration points:
- Session tracking in main.ts
- Level start and WebXR events in level1.ts
- Asteroid destruction and hull damage in ship.ts
- Performance snapshots and session end in gameStats.ts

Events tracked:
- session_start, session_end
- webxr_session_start
- level_start
- asteroid_destroyed (20% sampled)
- hull_damage
- gameplay_snapshot (60s intervals, 50% sampled)

Cost optimization:
- Batching reduces individual events by ~70%
- Sampling reduces high-frequency events by 50-80%
- Combined savings: ~90% data reduction
- Keeps usage safely under New Relic free tier (100GB/month)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-12 16:22:28 -06:00
7e5f7ef1e5 Add New Relic browser monitoring and update base station model
All checks were successful
Build / build (push) Successful in 1m33s
- Integrate New Relic browser agent for performance monitoring and analytics
- Configure distributed tracing, performance metrics, and AJAX monitoring
- Update base.glb model file with latest changes
- Add baked texture for default theme

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-12 11:11:00 -06:00
244a25fff5 Implement hybrid level storage system with JSON-based defaults and configurable orbit constraints
All checks were successful
Build / build (push) Successful in 1m34s
Major changes:
- Add LevelRegistry for managing default (JSON) and custom (localStorage) levels
- Default levels now load from /public/levels/*.json files
- Add 6 default level JSON files (rookie-training through final-challenge)
- Implement version-based automatic cache invalidation
- Add LevelVersionManager for tracking level updates
- Add LevelStatsManager for performance tracking (completion rate, best time, etc.)
- Add legacy migration tool for existing localStorage data
- Update level selector UI with stats display and version badges
- Add configurable orbit constraints per level (useOrbitConstraints flag)
- Hide copy button in level selector UI (TODO: re-enable later)
- Add extensive debug logging for velocity troubleshooting
- Add cloud sync infrastructure interfaces (future-ready)

Technical improvements:
- Hybrid storage: immutable defaults from JSON, editable custom levels in localStorage
- Automatic cache refresh when directory.json version changes
- Cache API for offline support
- Fresh start migration approach with export option
- Level loading now initializes before router starts

Physics configuration:
- Add useOrbitConstraints flag to LevelConfig
- Rookietraining.json uses constraints (velocities will create orbital motion)
- Debug logging added to verify velocity application

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 18:40:01 -06:00
8275c53fe4 Re-enable Discord widget with enhanced error logging for GraphQL debugging
All checks were successful
Build / build (push) Successful in 1m31s
Previously disabled due to GraphQL errors. Now re-enabled with comprehensive
error logging to diagnose the specific issue.

Changes to discordWidget.ts:
- Wrapped initialization in try-catch with detailed error logging
- Added step-by-step console logs through initialization process
- Added error event listener on the widget
- Added window.onerror handler to catch widgetbot/GraphQL errors

Changes to main.ts:
- Uncommented Discord widget initialization
- Added detailed error logging in catch block
- Log error type, message, stack, and GraphQL response if available

Next steps:
- Load the application in browser
- Check console for detailed error messages
- Identify specific GraphQL query/mutation causing issues
- Server ID: 1112846185913401475
- Channel ID: 1437561367908581406

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 17:18:50 -06:00
0dc3c9d68d Restructure codebase into logical subdirectories
All checks were successful
Build / build (push) Successful in 1m20s
## Major Reorganization

Reorganized all 57 TypeScript files from flat src/ directory into logical subdirectories for improved maintainability and discoverability.

## New Directory Structure

```
src/
├── core/ (4 files)
│   └── Foundation modules: defaultScene, gameConfig, debug, router
│
├── ship/ (10 files)
│   ├── Ship coordination and subsystems
│   └── input/ - VR controller and keyboard input
│
├── levels/ (10 files)
│   ├── config/ - Level schema, serialization, deserialization
│   ├── generation/ - Level generator and editor
│   └── ui/ - Level selector
│
├── environment/ (11 files)
│   ├── asteroids/ - Rock factory and explosions
│   ├── celestial/ - Suns, planets, textures
│   ├── stations/ - Star base loading
│   └── background/ - Stars, mirror, radar
│
├── ui/ (9 files)
│   ├── hud/ - Scoreboard and status screen
│   ├── screens/ - Login, settings, preloader
│   └── widgets/ - Discord integration
│
├── replay/ (7 files)
│   ├── Replay system components
│   └── recording/ - Physics recording and storage
│
├── game/ (3 files)
│   └── Game systems: stats, progression, demo
│
├── services/ (2 files)
│   └── External integrations: auth, social
│
└── utils/ (5 files)
    └── Shared utilities and helpers
```

## Changes Made

### File Moves (57 files)
- Core modules: 4 files → core/
- Ship system: 10 files → ship/ + ship/input/
- Level system: 10 files → levels/ (+ 3 subdirs)
- Environment: 11 files → environment/ (+ 4 subdirs)
- UI components: 9 files → ui/ (+ 3 subdirs)
- Replay system: 7 files → replay/ + replay/recording/
- Game systems: 3 files → game/
- Services: 2 files → services/
- Utilities: 5 files → utils/

### Import Path Updates
- Updated ~200 import statements across all files
- Fixed relative paths based on new directory structure
- Fixed case-sensitive import issues (physicsRecorder, physicsStorage)
- Ensured consistent lowercase filenames for imports

## Benefits

1. **Easy Navigation** - Related code grouped together
2. **Clear Boundaries** - Logical separation of concerns
3. **Scalability** - Easy pattern for adding new features
4. **Discoverability** - Find ship code in /ship, levels in /levels, etc.
5. **Maintainability** - Isolated modules easier to update
6. **No Circular Dependencies** - Clean dependency graph maintained

## Testing

- All TypeScript compilation errors resolved
- Build succeeds with new structure
- Import paths verified and corrected
- Case-sensitivity issues fixed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 12:53:18 -06:00
ee90e420d6 Fix mesh rendering and CloudFlare proxy compatibility
All checks were successful
Build / build (push) Successful in 1m21s
## Major Fixes

### 1. Fixed Invisible Meshes Issue
- Root cause: Emissive materials require disableLighting=true without scene lighting
- Added disableLighting=true to all loaded materials in loadAsset.ts
- Scene intentionally uses no dynamic lights (space game with emissive textures)

### 2. Fixed CloudFlare Proxy + Vite Cache Issues
- Updated vite.config.ts to pre-bundle BabylonJS procedural textures
- Added force:false to prevent unnecessary cache invalidation
- Fixed 504 Gateway Timeout errors on shader module dynamic imports
- Separated babylon-procedural chunk for better caching

### 3. Responsive Design Improvements
- Consolidated all CSS into public/styles.css with design tokens
- Removed duplicate styles.css file
- Created semantic header with navigation
- Extracted 300+ lines of inline styles to CSS classes
- Added mobile-first responsive breakpoints (320px, 480px, 768px, 1024px, 1440px)
- Implemented fluid typography with clamp()

### 4. Level Progression System
- Fixed level unlocking logic (tutorial always unlocked, others require auth)
- Updated DEFAULT_LEVEL_ORDER to match actual level names
- Made populateLevelSelector() async to properly await authentication
- Added 3-column carousel layout for level selection
- Visual states: locked, unlocked, current, completed

### 5. Discord Widget Management
- Disabled Discord widget initialization (commented out) to prevent GraphQL errors
- Added hide() call during gameplay
- Can be re-enabled when Discord bot is properly configured

### 6. TypeScript Error Fixes
- Removed unused hasSavedLevels import
- Updated replay callbacks to use appHeader instead of individual link references
- Fixed all TS compilation errors

## Files Modified
- index.html - Semantic header, removed inline styles
- public/styles.css - Consolidated styles with design tokens
- src/gameConfig.ts - Enabled progression by default
- src/levelSelector.ts - Fixed progression logic, async auth check
- src/loginScreen.ts - Removed inline styles
- src/main.ts - Discord handling, header visibility, error suppression
- src/preloader.ts - Removed inline styles
- src/progression.ts - Added isLevelUnlocked() method
- src/utils/loadAsset.ts - Fixed emissive materials (disableLighting=true)
- vite.config.ts - Pre-bundle procedural textures, prevent cache issues
- styles.css - DELETED (consolidated into public/styles.css)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 06:13:48 -06:00
1648364540 Add Discord widget integration with dynamic script loading
All checks were successful
Build / build (push) Successful in 1m24s
- Created TypeScript wrapper for Widgetbot Crate
- Dynamically loads Discord widget from CDN at runtime
- Removed @widgetbot/crate npm package to avoid React dependency (182 packages removed)
- Integrated with VR mode: auto-hides in VR, auto-shows in desktop mode
- Connected to Discord server 1112846185913401475, channel 1437561367908581406

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 17:53:27 -06:00
b31e33350e Add Auth0 authentication, Facebook sharing, and optimized loading
All checks were successful
Build / build (push) Successful in 1m21s
Features added:
- Auth0 authentication with optional login/signup
- Facebook share button on level completion (for FB users)
- Lazy initialization - nothing loads until level selected
- Deferred asset loading - assets load on first level click
- Preloader with progress tracking during level initialization
- User profile display with login/logout buttons

Technical improvements:
- Async router for proper Auth0 callback handling
- Main engine initialization deferred to level selection
- Assets (meshes, audio) load only when needed
- Progress reporting throughout initialization process

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 15:32:36 -06:00
ccc1745ed2 Refactor asteroid scaling and reorganize assets
All checks were successful
Build / build (push) Successful in 1m21s
Major changes:
- Change asteroid config to use single scale number instead of Vector3
- Move planetTextures to public/assets/materials/planetTextures
- Add GLB path configuration for start base
- Fix inspector toggle to work bidirectionally
- Add progression system support

Asteroid Scaling Changes:
- Update AsteroidConfig interface to use 'scale: number' instead of 'scaling: Vector3Array'
- Modify RockFactory.createRock() to accept single scale parameter
- Update level serializer/deserializer to use uniform scale
- Simplify level generation code in levelEditor and levelGenerator
- Update validation to check for positive number instead of 3-element array

Asset Organization:
- Move public/planetTextures → public/assets/materials/planetTextures
- Update all texture path references in planetTextures.ts (210 paths)
- Update default texture paths in createSun.ts and levelSerializer.ts
- Update CLAUDE.md documentation with new asset structure

Start Base Improvements:
- Add baseGlbPath and landingGlbPath to StartBaseConfig
- Update StarBase.buildStarBase() to accept GLB path parameter
- Add position parameter support to StarBase
- Store GLB path in mesh metadata for serialization
- Add UI field in level editor for base GLB path

Inspector Toggle:
- Fix 'i' key to toggle inspector on/off instead of only on
- Use scene.debugLayer.isVisible() for state checking
- Consistent with ReplayManager implementation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 12:19:31 -06:00
dfec655b6c Fix explosion sound by migrating to AudioEngineV2 spatial audio API
All checks were successful
Build / build (push) Successful in 1m20s
Root cause: The old Sound API (new Sound()) is incompatible with
AudioEngineV2 in BabylonJS 8.32.0, causing silent failures where the
explosion.mp3 file was never fetched from the network.

Audio System Fixes:
- Migrate explosion sound from Sound class to AudioEngineV2.createSoundAsync()
- Use StaticSound with spatial property instead of old Sound API
- Configure audio engine with listenerEnabled and listenerAutoUpdate
- Attach audio listener to camera for proper 3D positioning

Spatial Audio Implementation:
- Use spatialEnabled: true with spatial-prefixed properties
- Attach sound to explosion node using sound.spatial.attach()
- Properly detach and cleanup after explosion finishes (850ms)
- Configure exponential distance model with 500 unit max distance

Technical Changes:
- Replace new Sound() with await audioEngine.createSoundAsync()
- Change _explosionSound type from Sound to StaticSound
- Update imports: Sound → StaticSound
- Use sound.spatial.attach(node) instead of attachToMesh()
- Use sound.spatial.detach() for cleanup
- Remove incompatible getVolume() calls

Audio Engine Configuration:
- Add CreateAudioEngineAsync options for spatial audio support
- Attach listener to camera after unlock in both level flows
- Enable listener auto-update for VR camera movement tracking

This fixes the explosion sound loading and enables proper 3D spatial
audio with distance attenuation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 16:05:40 -06:00
56e900d93a Add physics-based collision damage, spatial audio, and synchronized audio loading
All checks were successful
Build / build (push) Successful in 1m17s
Audio Loading Improvements:
- Ensure all sounds load before gameplay starts
- Wrap RockFactory explosion sound in Promise for async/await support
- Move background music loading from play() to initialize() in Level1
- Update loading messages to reflect audio loading progress

Collision and Audio Features:
- Implement energy-based collision damage using reduced mass and kinetic energy
- Add ship velocity property and display on scoreboard HUD
- Add collision sound effect with volume-adjusted playback (0.35) on ship impacts
- Move explosion sound to RockFactory with spatial audio positioning
- Configure explosion sound with exponential rolloff for better audibility

Technical Changes:
- Reorder audio engine initialization to load before RockFactory
- Background music now preloaded and ready when play() is called
- All audio assets guaranteed loaded before ready observable fires

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 11:28:31 -06:00
31b498da7d Add status screen pause functionality with VR controller picking
Some checks failed
Build / build (push) Failing after 24s
Implemented comprehensive status screen system with pause/resume and game-end states:

- Added enable/disable functionality to controller and keyboard input systems
- X button and inspector key always work, even when controls disabled
- Created Resume/Replay/Exit VR buttons in status screen
- Resume button appears on manual pause, Replay appears on game end
- Implemented automatic status screen display on game end conditions:
  * Death: hull < 0.01 outside landing zone
  * Stranded: fuel < 0.01 and velocity < 1 outside landing zone
  * Victory: all asteroids destroyed inside landing zone
- Fixed landing zone detection to use mesh intersection instead of distance
- Implemented dynamic VR pointer selection using attach/detach pattern
- Pointer selection only enabled when status screen is visible
- Ship controls automatically disabled when status screen shows

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 09:55:03 -06:00
d6b1744ce4 Add keyboard roll controls and fix XR camera parenting
All checks were successful
Build / build (push) Successful in 1m41s
Keyboard controls:
- Added Arrow Left/Right keys for ship roll control
- Updated controls documentation in index.html
- Complete keyboard scheme: WASD for movement/yaw, arrows for pitch/roll

XR camera fixes:
- Fixed camera not parenting to ship in VR mode
- Issue: entering XR early broke onInitialXRPoseSetObservable flow
- Solution: manually parent camera after level initialization if already in XR
- Also manually start game timer and physics recorder in this case
- Set XR camera Y position to 1.5 for better cockpit viewing height

TypeScript fixes:
- Use WebXRState.IN_XR enum instead of numeric value
- Change MaterialConfig.albedoColor from Color4Array to Vector3Array
- Remove alpha channel from color arrays (Color3 is RGB only)

Code improvements:
- Added debug logging for XR camera parenting
- Check XR state before manual camera setup
- Graceful handling when ship transformNode not found

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 07:02:26 -06:00
faa5afc604 Add flat camera mode support and fix WebXR user activation
Some checks failed
Build / build (push) Failing after 24s
WebXR-optional gameplay:
- Removed WebXR requirement check, game now works without VR
- Made WebXR initialization optional with graceful fallback
- Flat camera mode automatically activates when XR unavailable
- Keyboard/mouse controls work in flat camera mode
- Camera following works in both XR and flat modes

Fixed WebXR user activation issue:
- Restructured initialization to enter XR immediately after button click
- Moved enterXRAsync() before asset loading to maintain user gesture
- Level1.play() now detects if XR session already active (state === 4)
- Removed setTimeout delays that broke user activation chain
- Falls back to flat mode if XR entry fails at any point

Game initialization improvements:
- Game timer and physics recorder start in both XR and flat modes
- Level1 constructor only sets up XR observables if XR available
- Ship.initialize() activates flat camera when XR not present
- Background stars follow active camera (XR or flat)
- Ready observable calls play() immediately to maintain activation

User experience:
- Game starts immediately in available mode (VR or flat)
- Seamless fallback if VR headset disconnects or unavailable
- Desktop users can now play with keyboard/mouse
- No error messages blocking non-VR users

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 06:30:59 -06:00
343fca4889 Refactor replay system to reuse Level1.initialize() and simplify UI
Major architectural improvements:
- Simplified replay system from ~1,450 lines to ~320 lines (78% reduction)
- Removed scene reconstruction complexity in favor of reusing game logic
- Added isReplayMode parameter to Level1 and Ship constructors
- Level1.initialize() now creates scene for both game and replay modes
- ReplayPlayer simplified to find existing meshes instead of loading assets

Replay system changes:
- ReplayManager now uses Level1.initialize() to populate scene
- Deleted obsolete files: assetCache.ts, ReplayAssetRegistry.ts
- Removed full scene deserialization code from LevelDeserializer
- Fixed keyboard input error when initializing in replay mode
- Physics bodies converted to ANIMATED after Level1 creates them

UI simplification for new users:
- Hidden level editor, settings, test scene, and replay buttons
- Hidden "Create New Level" link
- Filtered level selector to only show recruit and pilot difficulties
- Clean, focused experience for first-time users

Technical improvements:
- PhysicsRecorder now accepts LevelConfig via constructor
- Removed sessionStorage dependency for level state
- Fixed Color3 alpha property error in levelSerializer
- Cleaned up unused imports and dependencies

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 19:20:36 -06:00
2e1c8ad725 Fix inspector 'i' key registration in KeyboardInput
Problem:
- main.ts registered inspector with window.addEventListener
- keyboardInput.ts used document.onkeydown which replaces event handler
- This caused the inspector key binding to be overridden

Solution:
- Moved inspector 'i' key handling into KeyboardInput class
- Removed duplicate setupInspector() method from main.ts
- Inspector now opens correctly when 'i' is pressed

Changes:
- src/keyboardInput.ts: Added 'i' key case to open Babylon Inspector
- src/main.ts: Removed setupInspector() method (no longer needed)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 13:07:15 -06:00
20dfc238f8 Fix level double initialization and refactor ship physics
All checks were successful
Build / build (push) Successful in 1m20s
Major Changes:
- Fix Level1 double initialization by deferring initialize() call
  - Removed initialize() from Level1 constructor
  - Main.ts now explicitly calls initialize() after registering ready observable
  - Added error logging for double initialization detection

- Refactor Ship to use loadAsset utility and new GLB structure
  - Changed from SceneLoader.ImportMeshAsync to loadAsset pattern
  - Ship constructor no longer calls initialize() - must be called explicitly
  - Updated physics to use transformNode from GLB container
  - Adjusted control mappings for yaw/pitch/roll (inverted signs)
  - Reduced force multipliers for better control feel

- Remove MaterialFactory pattern
  - Deleted src/materialFactory.ts
  - LevelDeserializer now creates PBRMaterial directly for planets/sun
  - Removed texture quality settings from gameConfig
  - Cleaned up settings UI to remove texture quality controls

- Fix UI element hiding when entering VR
  - Editor and Settings links now properly hidden on level start

- Update GLB models for new asset structure
  - Updated ship.glb and base.glb models
  - Modified loadAsset to work with container transformNodes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 11:16:50 -06:00
146ffccd3d Add Blender export tooling and refactor asset structure
All checks were successful
Build / build (push) Successful in 1m18s
## Blender Export Utilities
- Add blenderExporter utility with ESM support (tsx)
- Create CLI script for exporting .blend files to GLB
- Add npm scripts: export-blend, export-blend:watch, export-blend:batch
- Support watch mode, batch export, and Draco compression
- Complete documentation in docs/BLENDER_EXPORT.md
- Add loadAsset utility helper

## Asset Structure Reorganization
- Move models to themeable structure: public/assets/themes/default/models/
- Add themes/ directory with source .blend files
- Remove old model files from public/ root
- Consolidate to asteroid.glb, base.glb, ship.glb

## Level Configuration Improvements
- Make startBase optional in LevelConfig interface
- Update LevelGenerator to not generate startBase data by default
- Update LevelDeserializer to handle optional startBase
- Update Level1 to handle null startBase
- Fix levelEditor to remove startBase generation references
- Update validation to treat startBase as optional

## Dependencies
- Add tsx for ESM TypeScript execution
- Add @types/node for Node.js types
- Update package-lock.json

This enables modding support with themeable assets and simplifies
level generation by making base stations optional.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 12:25:34 -06:00
37128d8fbd Update gameplay mechanics, asteroid model, and star base physics
All checks were successful
Build / build (push) Successful in 1m18s
- Switch to asteroid4.glb model with updated material handling
- Adjust difficulty parameters: increased spawn distances (220-450m range), updated force multipliers, varied asteroid sizes
- Fix scoreboard timer display (was showing frames instead of actual seconds)
- Refactor star base to use asset container with mesh merging for better performance
- Change star base physics from STATIC to ANIMATED with collision detection enabled
- Add directional lighting in level deserializer for improved scene lighting
- Clean up commented code and optimize debug logging
- Update base.glb 3D model

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 12:26:25 -06:00
b4608e10d8 Add centralized debug logging system with settings UI control
All checks were successful
Build / build (push) Successful in 1m16s
- Create debugLog wrapper function in src/debug.ts
- Add debug checkbox to settings screen UI
- Replace all console.log statements with debugLog calls (153 replacements)
- Add debug flag to GameConfig with localStorage persistence
- Fix GameConfig to properly load and reset debug setting
- Preserve console.error and console.warn calls unchanged
- Add Developer section to settings screen with debug toggle
- Enable/disable all debug logging via settings UI checkbox

Debug logging can now be controlled from Settings > Developer section,
reducing console noise in production while maintaining full debugging
capability during development.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 14:44:09 -05:00
72bd25b686 Add minimal test level with performance metrics and extensive debug logging
Some checks failed
Build / build (push) Failing after 23s
Added TestLevel class for debugging with progressive box creation and performance tracking. Includes comprehensive debug logging throughout the explosion system to diagnose Meta Quest issues.

Key changes:
- New TestLevel with 1-1000 box spawning (doubling each 5s iteration)
- Performance metrics logging (FPS, triangle count, mesh count)
- Direct triangle computation from mesh geometry
- Extensive explosion system debug logging
- Fixed observable timing issue (initialize after listener registration)
- Material freezing optimization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 16:33:45 -05:00
cb96b4ea6c Refactor sight to crosshair reticle and rename starfield to rockFactory
Some checks failed
Build / build (push) Failing after 19s
Created new Sight class:
- Crosshair design with circle, lines, and center dot
- Configurable radius, line length, thickness, and colors
- Green reticle color (traditional gun sight)
- Center gap and proper rendering group
- Dispose method for cleanup

Refactored Ship class:
- Replaced disc sight with new Sight class
- Changed ammo mesh to IcoSphere for better performance
- Added dispose method to clean up sight resources
- Integrated sight with configuration options

Renamed starfield.ts to rockFactory.ts:
- Better reflects the class purpose (RockFactory)
- Updated all imports across codebase
- Updated CLAUDE.md documentation

Updated asteroid model:
- Changed from asteroid2.glb to asteroid3.glb
- Added new asteroid3.blend and asteroid3.glb assets

Fixed background stars material:
- Added proper material type casting for StandardMaterial
- Fixed emissiveColor setting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 10:21:27 -05:00
9df64b7dd9 Add background starfield and fix scene background color
Some checks failed
Build / build (push) Failing after 19s
Created BackgroundStars class using PointCloudSystem:
- 5000 stars distributed uniformly on sphere surface
- Multiple star colors (white, warm, cool, yellowish, bluish)
- Varied brightness (0.3-1.0) for depth perception
- Follows camera position to maintain infinite distance effect
- Efficient rendering with disabled lighting and depth write

Integrated starfield into Level1:
- Created during level initialization
- Camera follow in render loop
- Proper disposal on level cleanup

Fixed XR background color:
- Set scene clearColor to pure black (was default grey)
- Adjusted ambientColor to black for space environment

Removed GlowLayer from ship and engines:
- Cleaned up unused glow effects
- Prevents unwanted glow on background stars

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 09:37:30 -05:00
db970ecc8a Add settings screen with graphics quality and physics controls
Some checks failed
Build / build (push) Failing after 19s
Created dedicated settings route and screen for game configuration:
- Settings UI with quality level dropdowns for planets, asteroids, and sun
- Physics enable/disable toggle
- Save and reset to defaults functionality
- localStorage persistence with feedback messages

Added settings navigation:
- Blue settings link button in game view header
- Integrated with existing hash-based router
- Back navigation to main menu

Settings features:
- Four texture quality levels: WIREFRAME, SIMPLE_MATERIAL, FULL_TEXTURE, PBR_TEXTURE
- Physics toggle for performance optimization
- Quality level guide with explanations
- Persistent settings across sessions
- Visual feedback on save/reset actions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 09:11:56 -05:00
a9054c2389 Add procedural lightmap system for planets and asteroids
Some checks failed
Build / build (push) Failing after 19s
- Create sphereLightmap.ts for procedural lighting generation
- Update planets to use lightmaps oriented toward sun
- Switch asteroids to PBR material with noise texture
- Use sphere physics shape for asteroids

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 17:30:02 -05:00
12710b9a5c Add JSON-based level editor with localStorage persistence
Some checks failed
Build / build (push) Failing after 22s
- Create comprehensive level editor UI with real-time configuration
- Implement JSON schema validation for level configurations
- Add client-side routing for game/editor views
- Support manual JSON editing with validation feedback
- Auto-generate 4 default levels on first load
- Replace hardcoded difficulty presets with dynamic level system
- Add level serializer/deserializer for import/export workflow
- Enhance responsive design with high-contrast styling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 08:24:55 -05:00
5f3fcf6bc0 Adjust lighting, physics, and visual settings for improved gameplay
All checks were successful
Build / build (push) Successful in 1m19s
Increase asteroid sizes, add ship-specific lighting, enhance sun brightness, adjust physics timesteps, and improve planet/asteroid material appearance. Increase planet count to 12 and move them farther from sun for better spatial layout.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 13:19:01 -05:00
052d972e69 Optimize WebXR performance and add procedural planet generation
Some checks failed
Build / build (push) Failing after 4m43s
Enable multiview rendering in WebXR for improved framerate, remove expensive PhotoDome per-frame updates, and add planet generation system with 76 unique textures across 12 planet types.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 11:50:18 -05:00
57ffe8f689 Migrate to AudioEngineV2 and fix Meta Quest 2 controller detection
- Upgrade audio system from deprecated Sound API to AudioEngineV2
  - Use CreateAudioEngineAsync() for audio engine initialization
  - Replace new Sound() with createSoundAsync() throughout codebase
  - Track sound playing state manually (StaticSound lacks isPlaying)
  - Use volume property instead of setVolume() method
  - Use stop() instead of pause() for proper StaticSound lifecycle

- Fix controller detection for Meta Quest 2
  - Check for already-connected controllers after entering XR mode
  - Fixes issue where Quest 2 controllers only become available after enterXRAsync()
  - Maintains backward compatibility with WebXR emulator

- Improve initialization performance
  - Move RockFactory.init() to main initialization (before level select)
  - Pre-load asteroid meshes and explosion particle systems on startup
  - Level initialization now only creates asteroids, not resources

- Refactor level initialization flow
  - Level creation now happens before entering XR mode
  - Add level ready observable to track initialization completion
  - Show loading messages during asteroid creation
  - Extract loading message logic to separate module

- Add audio unlock on user interaction (button click)
- Make play() methods async to support AudioEngineV2
- Pass AudioEngineV2 instance to Ship and Level1 constructors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 13:59:48 -05:00
d2aec0a87b Add difficulty levels and upgrade BabylonJS
Some checks failed
Build / build (push) Failing after 20s
Implemented a level selection system with 5 difficulty modes (Recruit, Pilot, Captain, Commander, Test), each with different asteroid counts, sizes, speeds, and constraints. Upgraded BabylonJS from 7.13.1 to 8.32.0 and fixed particle system animation compatibility issues.

- Add card-based level selection UI with 5 difficulty options
- Create difficulty configuration system in Level1
- Fix explosion particle animations for mesh emitters (emitter.y → emitter.position.y)
- Implement particle system pooling for improved explosion performance
- Upgrade @babylonjs packages to 8.32.0
- Fix audio engine unlock after Babylon upgrade
- Add test mode with 100 large, slow-moving asteroids
- Add styles.css for level selection cards with hover effects

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 09:05:18 -05:00
c9d03e832d changed game dynamics. 2025-02-20 19:11:46 -06:00
5b7d04bd39 changed game dynamics. 2025-02-17 16:51:06 -06:00
b85d1f5b09 Started cleaning up audio, rendering artifacts. 2025-02-16 16:44:18 -06:00
a105e28333 Initial Commit 2025-02-15 11:19:24 -06:00