fuzzyworld

nordic-skating / local-littlejs / files / CONVERSION_PLAN.md

Branch local-littlejs · default branch · all branches

CONVERSION_PLAN.md

Blame: the commit that last changed each line · file · history

39d08b63 2026-10-20 Pavel Safronov1# Nordic Skating to LittleJS Conversion Plan
2
3## Overview
4This document outlines the strategy for converting the Nordic Skating project from Three.js to LittleJS.
5
6## Current Project Analysis
7
8### Key Components Using Three.js:
91. **Main Render Loop** (`src/main.ts`)
10 - WebGLRenderer setup
11 - Scene and camera management
12 - Animation loop
13
142. **Render Components**
15 - `ice.ts`: Ice surface with textures and materials
16 - `sky.ts`: Sky dome with custom shader (322 lines of GLSL)
17 - `marks.ts`: Skating trail marks with line geometry
18 - `drifts.ts`: Drift effects
19 - `snow.ts`: Particle system with custom shader
20 - `shores.ts`: Shore elements
21
22### Three.js Features Used:
23- WebGLRenderer
24- Scene, PerspectiveCamera
25- Mesh, Geometry (PlaneGeometry, SphereGeometry, BufferGeometry)
26- Materials (MeshLambertMaterial, LineBasicMaterial, ShaderMaterial)
27- Textures and texture loading
28- Custom GLSL shaders for sky and snow effects
29- Points system for particles
30
31## LittleJS Capabilities Analysis
32
33### Key Features Available in LittleJS:
341. **2D/3D Hybrid Rendering**: WebGL2 + Canvas2D
352. **3D Support**:
36 - Built-in 3D renderer that shares canvas with 2D
37 - Shape builders, OBJ and glTF model loading
38 - Shadow maps, lights, cameras
393. **Shaders**: Shadertoy-style shaders for post-processing or object-level effects
404. **Particles**: Robust particle effect system
415. **Physics**: Arcade physics and Box2D integration
426. **Textures**: Runtime texture loading and atlas support
437. **Audio**: Sound and music support with spatial audio
448. **Input**: Comprehensive input handling (mouse, keyboard, touch)
45
46### Compatibility Notes:
47- LittleJS has its own 3D renderer, but also supports Three.js as a plugin
48- Custom shaders can be adapted to LittleJS's shader system
49- Particle systems need conversion from THREE.Points to LittleJS particles
50- Material system is different but conceptually similar
51
52## Conversion Strategy
53
54### Phase 1: Setup and Prototyping (Week 1)
55
56**Tasks:**
571. Install LittleJS alongside Three.js
582. Create minimal prototype showing basic scene
593. Test shader compatibility
604. Verify performance characteristics
61
62**Implementation:**
63```bash
64npm install littlejsengine --save
65```
66
67### Phase 2: Core Infrastructure Migration (Week 2-3)
68
69**Tasks:**
701. Replace Three.js renderer with LittleJS
712. Migrate scene management
723. Convert camera system
734. Set up animation loop compatibility
74
75**Key Changes:**
76- Replace `THREE.WebGLRenderer` with `engineInit()` pattern
77- Adapt `gameUpdate()` and `gameRender()` callbacks
78- Convert coordinate systems (LittleJS uses different conventions)
79
80### Phase 3: Component-by-Component Migration (Week 4-6)
81
82**Order of Migration:**
831. **Sky System** (`sky.ts`)
84 - Highest priority due to complex shader
85 - Test shader compatibility first
86
872. **Ice Surface** (`ice.ts`)
88 - Plane geometry conversion
89 - Material adaptation
90
913. **Snow Particles** (`snow.ts`)
92 - Convert THREE.Points to LittleJS particles
93 - Adapt custom shader
94
954. **Skating Marks** (`marks.ts`)
96 - Line geometry to LittleJS equivalent
97
985. **Drifts and Shores**
99 - Final render components
100
101### Phase 4: Integration and Testing (Week 7-8)
102
103**Tasks:**
1041. Verify all components work together
1052. Test performance characteristics
1063. Optimize shaders and rendering
1074. Ensure mobile compatibility
1085. Test on various devices/browsers
109
110## Technical Challenges and Solutions
111
112### 1. Custom Shaders Conversion
113**Challenge**: Sky and snow use complex GLSL shaders with custom uniforms.
114
115**Solution**:
116- Adapt shaders to LittleJS's shader system
117- Map Three.js uniforms to LittleJS equivalents
118- Test shader performance in LittleJS context
119
120### 2. Coordinate System Differences
121**Challenge**: LittleJS may use different coordinate conventions.
122
123**Solution**:
124- Create conversion utilities for positions/rotations
125- Test thoroughly with existing lake geometries
126
127### 3. Particle System Migration
128**Challenge**: THREE.Points with custom shader to LittleJS particles.
129
130**Solution**:
131- Use LittleJS's particle system API
132- Adapt vertex/fragment shaders to LittleJS format
133- Maintain same visual appearance and performance
134
135### 4. Material System Differences
136**Challenge**: Different material property names and capabilities.
137
138**Solution**:
139- Create material conversion utilities
140- Test all material combinations (transparent, emissive, etc.)
141
142## Implementation Plan
143
144### Step 1: Setup Dual Environment
145```typescript
146// In main.ts
147import * as THREE from 'three'
148import { engineInit } from 'littlejsengine'
149
150// Keep Three.js for now, add LittleJS alongside
151function gameInit() {
152 // Initialize both systems
153}
154
155function gameUpdate() {
156 // Update both systems in parallel during transition
157}
158
159function gameRender() {
160 // Render with both, compare results
161}
162
163engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost)
164```
165
166### Step 2: Create Adapter Utilities
167```typescript
168// src/adapters/littlejs-adapter.ts
169
170export class LittleJSAdapter {
171 static convertColor(threeColor: THREE.Color): number {
172 // Convert Three.js Color to LittleJS format
173 }
174
175 static convertVector3(vec: THREE.Vector3): [number, number, number] {
176 // Convert Three.js Vector3 to tuple
177 }
178
179 static createMaterial(options: {
180 color?: THREE.Color,
181 transparent?: boolean,
182 emissive?: THREE.Color
183 }): any {
184 // Create LittleJS material equivalent
185 }
186}
187```
188
189### Step 3: Migrate Sky Component First
190```typescript
191// New sky-littlejs.ts
192import { engine, createShaderMaterial } from 'littlejsengine'
193
194export class SkyLittleJS {
195 private mesh: any
196
197 constructor() {
198 // Create LittleJS equivalent of sky dome
199 this.mesh = engine.createMesh({
200 geometry: engine.createSphereGeometry(1000, 32, 16),
201 material: createShaderMaterial({
202 vertex: adaptedVertexShader,
203 fragment: adaptedFragmentShader,
204 uniforms: this.setupUniforms()
205 })
206 })
207 }
208
209 private setupUniforms() {
210 // Map Three.js uniforms to LittleJS format
211 }
212}
213```
214
215## Testing Strategy
216
2171. **Unit Tests**: Test each component in isolation
2182. **Visual Regression**: Compare screenshots before/after
2193. **Performance Benchmarks**: Measure FPS and memory usage
2204. **Cross-Browser Testing**: Ensure compatibility across browsers
2215. **Mobile Testing**: Verify touch controls and performance
222
223## Rollback Plan
224
225If conversion proves problematic:
2261. Maintain Three.js as primary renderer
2272. Use LittleJS for specific optimized components only
2283. Keep both renderers with feature flags
2294. Gradual migration path remains open
230
231## Success Criteria
232
2331. All visual elements maintain same appearance
2342. Performance meets or exceeds current implementation
2353. Mobile compatibility improved
2364. Bundle size reduced (target: < 50KB gzipped)
2375. No regression in functionality
2386. Easier to maintain and extend
239
240## Timeline Estimate
241
242- **Total Duration**: 8 weeks
243- **Critical Path**: Shader conversion and particle system migration
244- **Risk Areas**: Complex shaders, coordinate system differences
245
246## Resources
247
248- LittleJS Documentation: https://github.com/KilledByAPixel/LittleJS
249- Three.js to LittleJS Migration Guide (to be created)
250- Test cases for visual regression
251- Performance benchmarks