Files
feuerwerk/tests/core/body-geometry.test.ts
adminandClaude Opus 5.5 f9d5e8bca5
game-maker / gate (push) Successful in 2m48s
game-maker / suite (push) Successful in 8m46s
Move the one-way rule and collider geometry out of physics (#215)
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>
2026-09-23 10:20:07 +02:00

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);
});
});