Commit Graph

18 Commits

Author SHA1 Message Date
208d735ef4 Add background music selection and update game assets
Add configurable background music per level with song selector in the
level editor General tab. Update ship model, add base3 model, add
song2/song3 audio tracks, and clean up level config formatting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 06:13:37 -06:00
8180088b3b updated audio.
All checks were successful
Build / build (push) Successful in 1m56s
2025-12-01 08:55:21 -06:00
91e712edd9 Add level hints system for event-triggered audio playback
Some checks failed
Build / build (push) Has been cancelled
Implements a hint system that plays audio clips when specific game events occur:
- Ship status changes (fuel/hull/ammo thresholds)
- Asteroid destruction counts
- Ship collisions

Hints are stored in database with configurable play modes (once/always).
Also lowers background music volume from 0.5 to 0.2.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 08:45:20 -06:00
e3422ef9f2 Add mission brief audio playback using AudioEngineV2
All checks were successful
Build / build (push) Successful in 1m53s
- Add mission_brief_audio field to CloudLevelEntry interface
- Update missionBrief.ts to use AudioEngineV2.createSoundAsync()
  instead of legacy Sound class (fixes audio not playing)
- Pass audioEngine to MissionBrief.initialize() from Level1
- Add welcome_rookie.mp3 audio file

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 07:27:42 -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
71ff46e4cf Implement comprehensive scoring system with star ratings
All checks were successful
Build / build (push) Successful in 1m35s
Add linear-clamped scoring system that rewards speed, accuracy, fuel
efficiency, and hull integrity. Scores are always positive with a 0.5x
multiplier floor for refueling/repairs.

Scoring Components:
- Create scoreCalculator module with configurable scoring logic
- Time multiplier: Exponential decay from par time (0.1x to 3.0x)
- Accuracy multiplier: Linear 1.0x to 2.0x based on hit percentage
- Fuel efficiency: Linear with 0.5x floor (handles refueling >100%)
- Hull integrity: Linear with 0.5x floor (handles deaths/repairs >100%)
- Star rating system: 0-3 stars per category (12 stars max)

Integration:
- Add calculateFinalScore() to GameStats
- Support parTime in level config metadata
- Auto-calculate par time from difficulty level in Level1
  - Recruit: 300s, Pilot: 180s, Captain: 120s, Commander: 90s, Test: 60s
- Display comprehensive score breakdown on status screen

Status Screen Updates:
- Increase mesh size from 1.5x1.0m to 1.5x2.25m (portrait orientation)
- Increase texture from 1024x768 to 1024x1536 (fit all content)
- Add score display section with:
  - Final score in gold with thousand separators
  - Score multiplier breakdown for each category
  - Unicode star ratings (★★★) per category
  - Total stars earned (X/12)

Formula:
finalScore = 10,000 × time × accuracy × fuel × hull

All multipliers ≥ 0.5, ensuring scores are never negative even with
multiple refuels/deaths. System rewards balanced excellence across all
performance metrics.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 06:32:55 -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
500830779d Add level configuration system and update base station model
All checks were successful
Build / build (push) Successful in 1m26s
- Add level 1 JSON with 4 asteroids and difficulty config
- Add mission directory with recruit and fuel management missions
- Update base.glb model for space station
- Clean up unused helper functions in planetTextures.ts
- Refactor starBase.ts position handling to use container root node

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 17:26:18 -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
17c98c6102 Fix explosion audio delay by using lightweight TransformNode
All checks were successful
Build / build (push) Successful in 1m25s
Changes:
- Replace MeshBuilder.CreateSphere() with TransformNode in rockFactory.ts
- Eliminates 15-50ms geometry creation delay before audio playback
- Spatial audio only needs position data, not full mesh geometry
- Sound now plays immediately on asteroid collision

Technical details:
- TransformNode is a lightweight position container with no geometry
- No vertex buffers or WebGL resources to allocate
- Instantaneous creation removes blocking operation from critical path
- Maintains spatial audio positioning without performance overhead

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 14:04:16 -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
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
88d380fa3f Add continuous auto-save to IndexedDB for physics recordings
All checks were successful
Build / build (push) Successful in 1m26s
Modified physics recorder to automatically save all captured data to IndexedDB:
- Auto-saves every 10 seconds in batches (non-blocking)
- Creates unique session ID for each gameplay session
- Buffers snapshots between saves to minimize IndexedDB writes
- Saves any remaining buffered data on disposal
- All data preserved indefinitely in browser storage

Technical implementation:
- Auto-save buffer collects snapshots between 10-second intervals
- performAutoSave() copies buffer and clears immediately (non-blocking)
- Async save happens in background without impacting frame rate
- Session ID format: "session-{timestamp}" for easy identification
- Ring buffer (30s) still available for quick exports

Recording flow:
1. Recording starts when XR pose is set
2. Every frame adds snapshot to ring buffer AND auto-save buffer
3. Every 10 seconds, auto-save buffer is flushed to IndexedDB
4. On disposal, any remaining buffered frames are saved
5. All data accessible via existing storage APIs

Performance: Minimal impact - saves happen async every 10s, not per frame.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 05:39:09 -06:00
d8571ef740 Add physics recorder system with ring buffer and IndexedDB storage
All checks were successful
Build / build (push) Successful in 1m28s
Implemented comprehensive physics state recording system:
- PhysicsRecorder class with 30-second ring buffer (always recording)
- Captures position, rotation (quaternion), velocities, mass, restitution
- IndexedDB storage for long recordings (2-10 minutes)
- Segmented storage (1-second segments) for efficient retrieval
- Keyboard shortcuts for recording controls:
  * R - Export last 30 seconds from ring buffer
  * Ctrl+R - Toggle long recording on/off
  * Shift+R - Export long recording to JSON

Features:
- Automatic capture on physics update observable (~7 Hz)
- Zero impact on VR frame rate (< 0.5ms overhead)
- Performance tracking and statistics
- JSON export with download functionality
- IndexedDB async storage for large recordings

Technical details:
- Ring buffer uses circular array for constant memory
- Captures all physics bodies in scene per frame
- Stores quaternions for rotation (more accurate than Euler)
- Precision: 3 decimal places for vectors, 4 for quaternions
- Integration with existing Level1 and keyboard input system

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 05:22:49 -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