- Use getAbsolutePosition() in all config builders for correct world coords
- Add TargetComponent case to meshCollector for target export
- Add shared target body cache in RockFactory (asteroids can share targets)
- Add debug logging throughout export and physics pipelines
- Pass targetId to RockFactory for proper target body sharing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Includes:
- Editor project configuration and cache files
- Sample scene with example meshes and geometries
- Asset files (asteroid, base GLB models, environment map)
- Vite/TypeScript configuration for editor preview
- Editor script components for game objects
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create level_history table storing previous and new state snapshots
- Add trigger that automatically logs meaningful changes to levels
- Track change_type: update, submitted, published, rejected
- RLS policies for user and admin access to history
- Add RPC functions for querying history and entries
- Set user context in save_level_by_token for proper attribution
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Plugin features:
- Token-based authentication (user pastes token from website)
- Browse and load official levels
- Browse, load, and save personal levels
- Export current scene as level config JSON
- Import level config into Editor scene
- Editor script components for game objects (asteroid, ship, planet, etc.)
- Floating UI panel for quick access to tools
- Camera speed controls for editor navigation
Note: Uses public Supabase anon key (same as website client bundle)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add My Levels tab to website level selection for viewing private levels
- Add profile page for generating/managing editor plugin tokens
- Create user_tokens table and RPC functions for token-based auth
- Fix cloudLevelService to use maybeSingle() for admin and level queries
- Fix getLevelById to try authenticated client first for private levels
- Add rotation support to asteroids, base, sun, and planets
- Remove deprecated difficultyConfig from level files
- Add editor script components for BabylonJS Editor integration
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds configurable target positions that asteroids can reference:
- Orbit mode: asteroid maintains fixed distance to target via constraint
- MoveToward mode: asteroid velocity redirected toward target
Includes level editor UI for managing targets and asteroid assignments.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add StarfieldConfig interface (count, radius, brightness, pointSize)
- Add scale property to SunConfig for independent x/y/z scaling
- Update levelDeserializer to apply sun scale and expose starfield config
- Update level1 to pass starfield config to BackgroundStars
- Create SunConfigEditor.svelte for editing sun properties
- Create StarfieldConfigEditor.svelte for editing starfield properties
- Add Sun and Stars tabs to LevelConfigEditor
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Set renderingGroupId=2 for game objects (ship, asteroids, base, sun, planets)
- Set camera maxZ=100000 for FreeCamera and XR camera (distant planets)
- Add static sphere physics bodies to planets
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create LevelEditor.svelte with permission-gated level list
- Create LevelEditForm.svelte for editing level metadata
- Add getAllLevelsForAdmin() and updateLevelAsAdmin() to CloudLevelService
- Add /editor/:levelId route to App.svelte
- Show Level Editor link in header only for admins with canManageOfficial
- Add migration to use internal UUID for admins table
- Fix auth0_sub -> auth0_id column name in supabaseService
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- 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>
- 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>
- Add 'mission_brief_shown' event type to HintEntry interface
- Add triggerMissionBriefShown() method to LevelHintSystem
- Call hint trigger when mission brief is displayed in Level1
- Remove old missionBriefAudio playback from MissionBrief class
This enables database-configurable audio hints (like welcome_rookie)
to play when the mission brief is shown.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace automatic XR entry with user-triggered ENTER XR button
- Display level name, difficulty, and mission brief during loading
- Add VR availability check with "VR not available" error for desktop
- Add deep link protection - redirect locked levels to level select
- Extract XR entry logic to xrEntryHandler.ts for code organization
- Refactor levelSelectedHandler.ts from 206 to 150 lines
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>
- 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>
- 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>
- 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>
Use setTransformationFromNonVRCamera to set XR reference space
to ship cockpit position before entering immersive mode. This
prevents camera jumping on Quest when the 2D preloader disappears.
Also includes:
- Ship physics tuning (reduced force multipliers and fuel consumption)
- Fix reverse thrust direction in shipPhysics.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>
- 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>
- Dispose old scene before creating new one (cleans up physics)
- Stop existing render loop before starting new one
- Dynamically import @babylonjs/inspector on 'i' key press
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Hide #gameCanvas by default in CSS (display: none)
- Show canvas in setupXRCamera() after camera is parented to ship
- Show canvas in flat mode fallback paths
- Fix preloader to append to document.body (was hidden with #levelSelect)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- 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>
- 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>
- 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>
- 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>
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>
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>
- 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>
- 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>
- Add Supabase service and cloud leaderboard service for score submission
- Fix Auth0 JWT by adding audience parameter for Supabase RLS compatibility
- Fix BabylonJS shader loading by adding @babylonjs/materials to Vite pre-bundle
- Update CI workflow with Supabase and Auth0 audience secrets
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Shows a button that uses Meta's Web Launch to send the current URL
to the user's Quest headset. Hidden when already browsing on Quest.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- 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>
- 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>
- 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>