PhysicsSystem had 940 lines. The step logic shares its state with the engine handles of parts and bodies, so a separate class would need almost the whole system as its interface. That part stays. Two pieces without own state move out instead. Behaviour is unchanged. - passesOneWay in oneWay.ts is the one-way rule as a pure function. It can now be tested without Rapier. - bodyGeometry.ts holds the collider shapes and the pose maths. - PhysicsSystem is down to 820 lines. Tests: - ./check.sh: 146 files, 2199 tests, CHECK EXIT 0 - 5 new unit tests for the one-way rule without an engine. - New tests/core/body-geometry.test.ts: a capsule turned by 90 degrees went unnoticed before. Both tests fail against that bend. - Counter-checks on landing hold and teleport detection fail in 3 to 6 tests each. - e2e 1-28,31,36,39-43 on the final state: ALL PASSED, 1060 checks - Each of the four #215 commits was checked green on its own in a scratch worktree: 2190, 2192, 2192, 2199 tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
21 lines
1.1 KiB
TypeScript
21 lines
1.1 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { piecesInBody } from '../../src/runtime/physics/bodyGeometry';
|
|
|
|
describe('a collider as the engine builds it', () => {
|
|
const origin = { x: 100, y: 50, angle: 0 };
|
|
const capsule = (a: { x: number; y: number }, b: { x: number; y: number }) =>
|
|
({ kind: 'capsule', x: (a.x + b.x) / 2, y: (a.y + b.y) / 2, angle: 0, a, b, r: 5 }) as const;
|
|
|
|
it('a standing capsule is the engine capsule unturned, since that one lies along its y axis', () => {
|
|
const [piece] = piecesInBody(origin, capsule({ x: 100, y: 30 }, { x: 100, y: 70 }));
|
|
expect(piece).toMatchObject({ kind: 'capsule', x: 0, y: 0, half: 20, r: 5 });
|
|
expect(piece?.kind === 'capsule' && Math.abs(Math.sin(piece.angle))).toBeCloseTo(0);
|
|
});
|
|
|
|
it('a lying capsule is turned a quarter, in the frame of the body it hangs on', () => {
|
|
const [piece] = piecesInBody(origin, capsule({ x: 90, y: 60 }, { x: 130, y: 60 }));
|
|
expect(piece).toMatchObject({ kind: 'capsule', x: 10, y: 10, half: 20 });
|
|
expect(piece?.kind === 'capsule' && Math.abs(Math.cos(piece.angle))).toBeCloseTo(0);
|
|
});
|
|
});
|