Commit Graph

23 Commits

Author SHA1 Message Date
18a9ae9978 Refactor loading into 3-phase system to mask XR camera repositioning
Phase 1: Prefetch assets (ship.glb, asteroid.glb, base.glb, audio)
Phase 2: Create level meshes hidden (before XR entry)
Phase 3: Enter XR, init physics, show meshes, unlock audio

Key changes:
- Split Ship.initialize() into addToScene() + initializePhysics()
- Split RockFactory.createRock() into createRockMesh() + initPhysics()
- Split StarBase.buildStarBase() into addToScene() + initializePhysics()
- Add deserializeMeshes() + initializePhysics() to LevelDeserializer
- Update Level1 to orchestrate new phased flow
- Fix XR camera parenting (use getTransformNodeByName not getMeshById)
- Fix asteroid visibility (show meshes before clearing _createdRocks map)
- Add audioPrefetch utility for prefetching audio files

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 12:43:24 -06:00
6655abeeec Add non-linear controller input curve and fix auth token error
- Replace linear controller scaling with power curve (exp 2.5) for
  smoother VR controls - less sensitive at low deflections, full
  power at 90% stick travel
- Fix Missing Refresh Token error by clearing stale auth state
  automatically instead of leaving users in broken state
- Fix build errors: use ScoreEvent type in weaponSystem, remove
  unused parTime parameter from buildResult

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 19:24:57 -06:00
749cc18211 Refactor scoring system to additive model starting at 0
- Replace multiplier-based scoring with additive system
- Score builds from asteroid destruction based on size and timing
- Small asteroids (<10 scale): 1000 pts, Medium (10-20): 500 pts, Large (>20): 250 pts
- Timing multiplier: 3x in first 1/3 of par time, 2x in middle, 1x in last third
- End-game bonuses only applied at game end (hull, fuel, accuracy)
- Add scale property to ScoreEvent for point calculation
- Update status screen to show "CURRENT SCORE" during play, "FINAL SCORE" at end
- Refactor star ratings display into individual columns
- Fix button clipping on hover with clipChildren = false
- Add reusable button hover effects utility

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 16:39:27 -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
c87b85de40 Fix ship physics init order and Supabase RLS user sync
All checks were successful
Build / build (push) Successful in 1m47s
- Pass initial position to ship.initialize() to set position BEFORE
  creating physics body, preventing collision race condition on reload
- Use get_or_create_user_id RPC (security definer) to bypass RLS
  for user profile sync in both authService and cloudLeaderboardService
- Sync user to Supabase on Auth0 login to ensure profile exists
- Add Supabase schema.sql and policies.sql for documentation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 07:00:24 -06:00
d3d6175360 Fix mission brief trigger by using InputControlManager state
All checks were successful
Build / build (push) Successful in 1m45s
- Use InputControlManager.shipControlsEnabled instead of local flag
- Remove unused _controlsEnabled field from Ship class
- Fixes trigger press not dismissing mission brief screen

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 05:31:16 -06:00
5ce26c64ff Refactor weapon system to shape casting and parent status screen to ship
All checks were successful
Build / build (push) Successful in 1m47s
- Replace physics-based projectiles with shape cast collision detection
- Add ignoreBody to shape cast to prevent projectiles hitting ship mesh
- Parent StatusScreen to ship TransformNode instead of XR camera
- Add velocity check to victory condition (must be < 5 m/s)
- Adjust projectile spawn offset and velocity

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 16:03:27 -06:00
226ec5f51a Fix bullet trajectory when ship is rotating
All checks were successful
Build / build (push) Successful in 1m48s
Calculate velocity at bullet spawn point (8.4 units from center) instead
of ship center. Accounts for tangential velocity from angular rotation
using cross product: velocity_at_spawn = linear + (angular × offset).

This fixes bullets appearing to drift when ship is moving and rotating.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 08:17:14 -06:00
b46f44e32d Performance fixes and debug features
All checks were successful
Build / build (push) Successful in 1m45s
- Fix duplicate render loops causing 50% FPS drop (70→40)
  - Add stopRenderLoop() before runRenderLoop() in level1.ts and levelSelectedHandler.ts
- Add ?loglevel=debug|info|warn|error query parameter
- Add Y button to toggle inspector in XR
- Throttle scoreboard updates to every 10 frames
- Throttle game-end condition checks to every 30 frames
- Remove per-frame logging from explosion animations
- Reduce background stars from 5000 to 2500
- Freeze asteroid material after loading
- Reduce physics substeps from 5 to 2
- Disable autoClear for Quest 2 performance

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 07:58:15 -06:00
123b341ed7 Replace debugLog and console.* with loglevel logger
- Create centralized logger module (src/core/logger.ts)
- Replace all debugLog() calls with log.debug()
- Replace console.log() with log.info()
- Replace console.warn() with log.warn()
- Replace console.error() with log.error()
- Delete deprecated src/core/debug.ts
- Configure log levels: debug for dev, warn for production
- Add localStorage override for production debugging

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 05:24:18 -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
b4baa2beba Migrate to cloud-only level system using Supabase
All checks were successful
Build / build (push) Successful in 1m44s
Remove all local level storage concepts and load levels exclusively from
Supabase cloud. Simplifies LevelRegistry from 380+ lines to ~50 lines.
Uses CloudLevelEntry directly throughout the codebase instead of wrapper
types like LevelDirectoryEntry.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 17:26:24 -06:00
c9d7b0f3a5 Update ship positions 2025-11-28 10:46:39 -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
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
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
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
415496b3a2 Add voice audio system for cockpit computer announcements
All checks were successful
Build / build (push) Successful in 1m21s
Implemented VoiceAudioSystem class that loads voice clips and plays them sequentially in response to game events (fuel/hull/ammo warnings).

Changes:
- VoiceAudioSystem: New class for managing voice audio
  - Loads 13 voice MP3 files (warning, danger, fuel, hull, ammo, etc.)
  - Priority queue system (HIGH, NORMAL, LOW)
  - Sequential playback with state polling
  - One-shot warning tracking to prevent spam
  - Non-spatial audio (cockpit computer voice)

- Ship: Integrated VoiceAudioSystem
  - Initialize voice system after ShipAudio
  - Subscribe to ShipStatus.onStatusChanged events
  - Call update() in render loop for sequential playback

Features:
- Event-driven warnings trigger on status thresholds
  - Fuel/hull/ammo < 30%: "warning" → resource name
  - Fuel/hull/ammo < 10%: "danger" → resource name
  - Resource = 0: resource name → "empty"
- Comprehensive debug logging for troubleshooting
- State machine handles queue and playback sequencing

Note: Current implementation has a bug in getMaxValue() calculation that prevents warnings from triggering correctly. Will be fixed in next commit.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 15:18:41 -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