refactor: separate React views, Redux snapshots and Three.js runtime

This commit is contained in:
2026-10-28 12:26:40 +03:30
parent 6bd9b17173
commit d0da416923
77 changed files with 4941 additions and 3723 deletions
+3 -3
View File
@@ -6,15 +6,15 @@ import {
priceAt,
canAffordAnything,
formatClock,
} from '../src/game-state.js';
} from '../src/game/economy/gameState.js';
import {
createPayment,
beginPayment,
readyPayment,
swipePayment,
cancelPayment,
} from '../src/payment.js';
import { machineById, machines } from '../src/locations.js';
} from '../src/game/economy/payment.js';
import { machineById, machines } from '../src/constants/locations.js';
const park = machineById('mellat-park'),
school = machineById('school-rahil'),
+7 -2
View File
@@ -1,6 +1,11 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { smoothFix, arrivalRadius, insideWorld, createStabilizer } from '../src/realworld.js';
import {
smoothFix,
arrivalRadius,
insideWorld,
createStabilizer,
} from '../src/game/device/realworld.js';
test('GPS fixes blend by accuracy and a stale estimate is replaced', () => {
const first = smoothFix(null, { x: 0, z: 0, accuracy: 10, time: 0 });
@@ -47,7 +52,7 @@ test('Stable mode holds still through jitter, drops jumps and follows real walki
test('AR camera faces north/west with the phone held upright, and the FOV fits the screen', async () => {
const { Quaternion, Vector3 } = await import('three');
const { orientationQuaternion, coverFov } = await import('../src/ar.js');
const { orientationQuaternion, coverFov } = await import('../src/game/device/ar.js');
const look = (alpha, beta = 90, gamma = 0, angle = 0) =>
new Vector3(0, 0, -1).applyQuaternion(
orientationQuaternion(new Quaternion(), alpha, beta, gamma, angle),
+3 -3
View File
@@ -7,9 +7,9 @@ import {
activeMission,
POINTS,
RANKS,
} from '../src/scoring.js';
import { createState, purchase } from '../src/game-state.js';
import { machineById } from '../src/locations.js';
} from '../src/game/economy/scoring.js';
import { createState, purchase } from '../src/game/economy/gameState.js';
import { machineById } from '../src/constants/locations.js';
const total = (awards) => awards.reduce((s, a) => s + a.points, 0);
+18 -8
View File
@@ -1,13 +1,23 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { toLocal, toLatLon, bearing, ORIGIN } from '../src/geo.js';
import { createCollisionWorld, resolveCircle, blocked, clearFraction } from '../src/collision.js';
import { buildGraph, routeBetween, nearestSegment, buildSegmentIndex } from '../src/routing.js';
import { createCar, stepCar } from '../src/vehicle.js';
import { createTraffic } from '../src/traffic.js';
import { toLocal, toLatLon, bearing, ORIGIN } from '../src/utils/geo.js';
import {
createCollisionWorld,
resolveCircle,
blocked,
clearFraction,
} from '../src/game/world/collision.js';
import {
buildGraph,
routeBetween,
nearestSegment,
buildSegmentIndex,
} from '../src/game/world/routing.js';
import { createCar, stepCar } from '../src/game/systems/vehicle.js';
import { createTraffic } from '../src/game/systems/traffic.js';
import { Scene } from 'three';
import { machines, machineById, FACTORY } from '../src/locations.js';
import { machines, machineById, FACTORY } from '../src/constants/locations.js';
const data = JSON.parse(readFileSync(new URL('../src/data/mellat.json', import.meta.url)));
@@ -80,7 +90,7 @@ test('Traffic drives with the flow on one-way carriageways and stays inside them
});
test('Microsoft buildings decode into the world, stay clear of the factory and leave machines reachable', async () => {
const { decodeBuildings } = await import('../src/buildings-data.js');
const { decodeBuildings } = await import('../src/game/world/buildingsData.js');
const file = readFileSync(new URL('../public/data/buildings.bin', import.meta.url));
const buildings = decodeBuildings(
file.buffer.slice(file.byteOffset, file.byteOffset + file.byteLength),
@@ -106,7 +116,7 @@ test('Microsoft buildings decode into the world, stay clear of the factory and l
});
test('Satellite tiles land where the map is: a tile over Park Mellat covers the park', async () => {
const { tileCorners } = await import('../src/imagery.js');
const { tileCorners } = await import('../src/game/world/imagery.js');
const index = JSON.parse(readFileSync(new URL('../public/imagery/index.json', import.meta.url)));
assert.ok(index[17].length > 100 && index[15].length > 100);
const park = toLocal(36.32092, 59.53744),