mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-10 15:04:36 +00:00
a7f992e9b0
Restructure the single src/ tree into an npm-workspaces monorepo under
packages/, rename core -> engine, extract a types-only core-public layer,
and break the pre-existing engine -> client dependency cycle.
Structure (packages/):
core-public public API/wire schemas + shared enums (clean leaf)
shared framework-agnostic helpers (clean leaf)
engine deterministic simulation (was src/core)
client rendering/UI (was src/client)
server coordination (was src/server)
Dependency DAG: engine -> {core-public, shared}; client -> {core-public,
shared, engine}; server -> {core-public, engine}.
- npm workspaces: root package.json workspaces + per-package package.json;
tsconfig.base.json holds shared options + path aliases
(core-public/* shared/* engine/* client/* server/*) resolved uniformly by
tsc, Vite (resolve.tsconfigPaths), Vitest, and tsx. Lockfile regenerated.
- core-public: moved Schemas/ApiSchemas/CosmeticSchemas/StatsSchemas/
ClanApiSchemas/WorkerSchemas/Base64/PatternDecoder; extracted the enums
(GameTypes), GameEvent type, emoji table, and GraphicsOverrides schema.
Engine re-exports the moved enums/types so existing imports keep working.
- Broke engine -> client cycle:
- renderNumber/renderTroops -> shared/format
- NameBoxCalculator moved into engine
- username validation returns translation key + params; client translates
- applyStateUpdate moved to client (operates on the render-only PlayerState)
- Config/UnitGrid/execution-Util/GameImpl now use structural read
interfaces (engine/game/ReadViews: PlayerLike/UnitLike/GameLike) instead
of importing client view classes; client imports view classes from a new
client/view barrel; deleted the engine/game/GameView re-export shim.
- Build/deploy updated: vite.config, index.html, eslint, Dockerfile
(copies packages/ + tsconfig.base.json before npm ci), .vscode, tests.
Verified: tsc --noEmit clean; 1364 + 65 tests pass; production vite build
succeeds; engine has zero client/server imports; core-public and shared are
dependency leaves.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
42 lines
1.7 KiB
TypeScript
42 lines
1.7 KiB
TypeScript
import { computeAllianceClipPath } from "client/hud/PlayerIcons";
|
|
|
|
describe("PlayerIcons", () => {
|
|
describe("computeAllianceClipPath", () => {
|
|
test("returns full visibility (20% top cut) when alliance time is at 100%", () => {
|
|
const result = computeAllianceClipPath(1.0);
|
|
// topCut = 20 + (1 - 1.0) * 80 * 0.78 = 20 + 0 = 20.00
|
|
expect(result).toBe("inset(20.00% -2px 0 -2px)");
|
|
});
|
|
|
|
test("returns maximum cut (82.40% top cut) when alliance time is at 0%", () => {
|
|
const result = computeAllianceClipPath(0.0);
|
|
// topCut = 20 + (1 - 0.0) * 80 * 0.78 = 20 + 62.4 = 82.40
|
|
expect(result).toBe("inset(82.40% -2px 0 -2px)");
|
|
});
|
|
|
|
test("returns 51.20% top cut when alliance time is at 50%", () => {
|
|
const result = computeAllianceClipPath(0.5);
|
|
// topCut = 20 + (1 - 0.5) * 80 * 0.78 = 20 + 31.2 = 51.20
|
|
expect(result).toBe("inset(51.20% -2px 0 -2px)");
|
|
});
|
|
|
|
test("returns 27.80% top cut when alliance time is at 87.5%", () => {
|
|
const result = computeAllianceClipPath(0.875);
|
|
// topCut = 20 + (1 - 0.875) * 80 * 0.78 = 20 + 7.8 = 27.80
|
|
expect(result).toBe("inset(27.80% -2px 0 -2px)");
|
|
});
|
|
|
|
test("returns 74.60% top cut when alliance time is at 12.5%", () => {
|
|
const result = computeAllianceClipPath(0.125);
|
|
// topCut = 20 + (1 - 0.125) * 80 * 0.78 = 20 + 54.6 = 74.60
|
|
expect(result).toBe("inset(74.60% -2px 0 -2px)");
|
|
});
|
|
|
|
test("includes -2px horizontal overscan to prevent subpixel gaps", () => {
|
|
const result = computeAllianceClipPath(0.5);
|
|
expect(result).toContain("-2px");
|
|
expect(result.match(/-2px/g)).toHaveLength(2); // Should appear twice (left and right)
|
|
});
|
|
});
|
|
});
|