feat: v0.9.2 — power-of-two time scale: slider steps through the 1/2/4/8/16/32/64 ladder, POST /api/sim clamp widened to [1,64]

This commit is contained in:
2026-09-17 19:15:15 +00:00
parent 62f9929b51
commit 03653fc50e
12 changed files with 80 additions and 51 deletions
+9 -4
View File
@@ -31,15 +31,20 @@ describe('POST /api/sim', () => {
expect(body.paused).toBe(false);
});
it('sets and clamps timeScale into [1, 60]', async () => {
it('sets and clamps timeScale into [1, 64]', async () => {
const hi = await post({ timeScale: 500 });
expect(hi.status).toBe(200);
expect(((await hi.json()) as { timeScale: number }).timeScale).toBe(60);
expect(((await hi.json()) as { timeScale: number }).timeScale).toBe(64);
const lo = await post({ timeScale: 0.1 });
expect(lo.status).toBe(200);
expect(((await lo.json()) as { timeScale: number }).timeScale).toBe(1);
// The top of the power-of-two ladder passes through unclamped (v0.9.2).
const max = await post({ timeScale: 64 });
expect(max.status).toBe(200);
expect(((await max.json()) as { timeScale: number }).timeScale).toBe(64);
const mid = await post({ timeScale: 37 });
expect(mid.status).toBe(200);
expect(((await mid.json()) as { timeScale: number }).timeScale).toBe(37);
@@ -66,10 +71,10 @@ describe('POST /api/sim', () => {
});
it('applies both fields in one call', async () => {
const res = await post({ timeScale: 60, paused: true });
const res = await post({ timeScale: 64, paused: true });
expect(res.status).toBe(200);
const body = (await res.json()) as { timeScale: number; paused: boolean };
expect(body.timeScale).toBe(60);
expect(body.timeScale).toBe(64);
expect(body.paused).toBe(true);
await post({ timeScale: 1, paused: false }); // restore
});
+2 -2
View File
@@ -1,6 +1,6 @@
import { applyTimeControls } from '@/lib/sim/engine';
// POST /api/sim — set sim time controls (v0.7.0). Body: { timeScale?: 1–60, paused?: boolean }.
// POST /api/sim — set sim time controls (v0.7.0). Body: { timeScale?: 1–64, paused?: boolean }.
// Ticks the clock first (so the response reflects current game time), then applies
// and persists the new controls. Returns the updated simState.
@@ -23,7 +23,7 @@ export async function POST(req: Request) {
}
}
if (input.timeScale !== undefined && (typeof input.timeScale !== 'number' || !Number.isFinite(input.timeScale))) {
return Response.json({ error: 'timeScale must be a finite number (1–60)' }, { status: 400 });
return Response.json({ error: 'timeScale must be a finite number (1–64)' }, { status: 400 });
}
if (input.paused !== undefined && typeof input.paused !== 'boolean') {
return Response.json({ error: 'paused must be a boolean' }, { status: 400 });