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>
164 lines
6.0 KiB
TypeScript
164 lines
6.0 KiB
TypeScript
import {
|
|
Engine,
|
|
Scene,
|
|
HemisphericLight,
|
|
Vector3,
|
|
MeshBuilder,
|
|
WebXRDefaultExperience,
|
|
Color3
|
|
} from "@babylonjs/core";
|
|
import debugLog from '../core/debug';
|
|
|
|
/**
|
|
* Minimal standalone class to debug WebXR controller detection
|
|
* Usage: import and instantiate in main.ts instead of normal flow
|
|
*/
|
|
export class ControllerDebug {
|
|
private engine: Engine;
|
|
private scene: Scene;
|
|
|
|
constructor() {
|
|
debugLog('🔍 ControllerDebug: Starting minimal test...');
|
|
this.init();
|
|
}
|
|
|
|
private async init() {
|
|
// Get canvas
|
|
const canvas = document.querySelector('#gameCanvas') as HTMLCanvasElement;
|
|
|
|
// Create engine (no antialiasing for Quest compatibility)
|
|
debugLog('🔍 Creating engine...');
|
|
this.engine = new Engine(canvas, false);
|
|
|
|
// Create scene
|
|
debugLog('🔍 Creating scene...');
|
|
this.scene = new Scene(this.engine);
|
|
this.scene.clearColor = new Color3(0.1, 0.1, 0.2).toColor4();
|
|
|
|
// Add light
|
|
//const light = new HemisphericLight("light", new Vector3(0, 1, 0), this.scene);
|
|
|
|
// Add ground for reference
|
|
const ground = MeshBuilder.CreateGround("ground", { width: 10, height: 10 }, this.scene);
|
|
|
|
// Create WebXR
|
|
//consol e.log('🔍 Creating WebXR...');
|
|
//await navigator.xr.offerSession("immersive-vr");
|
|
const xr = await this.scene.createDefaultXRExperienceAsync( {
|
|
disablePointerSelection: true,
|
|
disableTeleportation: true,
|
|
inputOptions: {
|
|
disableOnlineControllerRepository: true
|
|
},
|
|
disableDefaultUI: false, // Enable UI for this test
|
|
disableHandTracking: true
|
|
});
|
|
|
|
debugLog('🔍 WebXR created successfully');
|
|
debugLog('🔍 XR input exists:', !!xr.input);
|
|
debugLog('🔍 XR input controllers:', xr.input.controllers.length);
|
|
|
|
// Set up controller observable
|
|
debugLog('🔍 Setting up onControllerAddedObservable...');
|
|
|
|
|
|
xr.input.onControllerAddedObservable.add((controller) => {
|
|
debugLog('✅ CONTROLLER ADDED! Handedness:', controller.inputSource.handedness);
|
|
debugLog(' - Input source:', controller.inputSource);
|
|
debugLog(' - Has motion controller:', !!controller.motionController);
|
|
|
|
// Wait for motion controller
|
|
controller.onMotionControllerInitObservable.add((motionController) => {
|
|
debugLog('✅ MOTION CONTROLLER INITIALIZED:', motionController.handness);
|
|
debugLog(' - Profile:', motionController.profileId);
|
|
debugLog(' - Components:', Object.keys(motionController.components));
|
|
|
|
// Log when any component changes
|
|
Object.keys(motionController.components).forEach(componentId => {
|
|
const component = motionController.components[componentId];
|
|
|
|
if (component.onAxisValueChangedObservable) {
|
|
component.onAxisValueChangedObservable.add((axes) => {
|
|
debugLog(`📍 ${motionController.handness} ${componentId} axes:`, axes);
|
|
});
|
|
}
|
|
|
|
if (component.onButtonStateChangedObservable) {
|
|
component.onButtonStateChangedObservable.add((state) => {
|
|
debugLog(`🔘 ${motionController.handness} ${componentId} button:`, {
|
|
pressed: state.pressed,
|
|
touched: state.touched,
|
|
value: state.value
|
|
});
|
|
});
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
debugLog('🔍 Observable registered. Waiting for controllers...');
|
|
|
|
// Render loop
|
|
this.engine.runRenderLoop(() => {
|
|
this.scene.render();
|
|
});
|
|
|
|
// Create button to enter VR (requires user gesture)
|
|
this.createEnterVRButton(xr);
|
|
}
|
|
|
|
private createEnterVRButton(xr: WebXRDefaultExperience) {
|
|
const button = document.createElement('button');
|
|
button.textContent = 'Enter VR (Controller Debug)';
|
|
button.style.cssText = `
|
|
position: fixed;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
padding: 20px 40px;
|
|
font-size: 24px;
|
|
background: #4CAF50;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
z-index: 9999;
|
|
`;
|
|
|
|
button.onclick = async () => {
|
|
debugLog('🔍 Button clicked - Entering VR mode...');
|
|
button.remove();
|
|
|
|
try {
|
|
await xr.baseExperience.enterXRAsync('immersive-vr', 'local-floor', undefined, {
|
|
requiredFeatures: ['local-floor'],
|
|
|
|
});
|
|
debugLog(xr.baseExperience.featuresManager.getEnabledFeatures());
|
|
//await xr.baseExperience.exitXRAsync();
|
|
//await xr.baseExperience.enterXRAsync('immersive-vr', 'local-floor');
|
|
debugLog('🔍 ✅ Entered VR mode successfully');
|
|
debugLog('🔍 Controllers after entering VR:', xr.input.controllers.length);
|
|
|
|
// Check again after delays
|
|
setTimeout(() => {
|
|
debugLog('🔍 [+1s after VR] Controller count:', xr.input.controllers.length);
|
|
}, 1000);
|
|
|
|
setTimeout(() => {
|
|
debugLog('🔍 [+3s after VR] Controller count:', xr.input.controllers.length);
|
|
}, 3000);
|
|
|
|
setTimeout(() => {
|
|
debugLog('🔍 [+5s after VR] Controller count:', xr.input.controllers.length);
|
|
}, 5000);
|
|
} catch (error) {
|
|
console.error('🔍 ❌ Failed to enter VR:', error);
|
|
}
|
|
};
|
|
|
|
document.body.appendChild(button);
|
|
debugLog('🔍 Click the button to enter VR mode');
|
|
}
|
|
}
|