Commit Graph

16 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
1528f54472 Add ENTER XR button to preloader with level info display
- 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>
2025-12-01 11:51:33 -06:00
5cdbf22e67 Pre-position XR camera at cockpit before VR entry
All checks were successful
Build / build (push) Successful in 1m42s
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>
2025-11-29 14:46:13 -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
cf3a74ff0b Fix scene doubling on reload and add dynamic inspector import
All checks were successful
Build / build (push) Successful in 1m45s
- 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>
2025-11-29 06:06:39 -06:00
dfa46c85a6 Hide canvas until XR camera positioned in ship cockpit
All checks were successful
Build / build (push) Successful in 1m0s
- 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>
2025-11-29 05:42:53 -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
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
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
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
fa15fce4ef Fixed some physics problems. 2025-11-24 17:03:41 -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
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
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