Endgate Prototype
Endgate is a focused SECS v2 prototype for authority, deterministic map pressure, SignalR transport, a small browser client, and benchmark coverage. It is intentionally narrower than Valenar: the goal is to keep a truthful, runnable shell for host/session/router behavior, map snapshots, defender commands, and pressure-wave simulation.
Endgate now uses the SECS compiler for schema-owned generated output. Authored .secs content lives under Content/, and Generated/Endgate.Generated.csproj runs secsc to emit the schema/runtime C# consumed by the host, server, tests, and benchmarks. Retained files under Generated/ are explicit non-schema host/catalog helpers.
Subprojects
Content/contains the committed Endgate.secssurfaces, includingrun_state.secs,defender_root.secs,base_objective.secs,wave_settings.secs,wave_script_fields.secs, andwave_scripts.secs(the per-wave script catalog).Generated/builds compiler-owned schema output and retains explicit non-schema catalogs. Wave lookup helpers live inGenerated/WaveScripts.cs; the wave script records and settings defaults are compiler-emitted author types.Host/containsEndgateGameHostand the authority/simulation models that drive runtime state.Server/hosts the ASP.NET Core SignalR surface and the live session/router services.Client/is the React/Vite browser shell that connects through@microsoft/signalr.Benchmarks/contains the BenchmarkDotNet authority benchmarks.
Current Prototype Scope
- Bootstrap wiring: the compiler-owned host schema, retained catalogs, session, router, and server contracts form a buildable shell.
- Deterministic map generation: seeded runs produce stable blocked cells, edge spawn arcs, village parcels, roads, and horde routes.
- Pressure routing: live-state queries, map-snapshot queries, world-space character movement, building/parcel commands, and steady-state ticks run through the host/session/router path.
- Wave loop: win advances
currentWave; loss pays energy, incrementswaveAttempt, and retries the same saved wave definition. - Fatal runtime faults: tick failures mark the session faulted, write a JSON fault report through the shared SECS runtime fault-report projection, and stop the hosted simulation loop.
- Browser shell coverage: the client is a React/Vite tactical map surface for the Endgate SignalR session.
- Benchmark coverage: the authority benchmark suite measures live snapshot queries, map snapshot queries, defender assignment, steady-state ticks, and map regeneration.
These slices are backed by the focused Endgate server contract tests under
tests/Endgate.Server.Tests/, tests/Endgate.Server.Tests/SignalRWireContractTests.cs,
tests/Endgate.Server.Tests/GameSessionRuntimeFailureTests.cs, and
examples/endgate/Benchmarks/EndgateAuthorityBenchmarks.cs.
Active Work Loop
Documentation index: docs/README.md.
| Category | Docs |
|---|---|
| Game systems | docs/systems/ — wave loop, village building, characters, combat, map, progression |
| UX screens | docs/ux/ — shell/panels, tactical viewport, HUD |
| Contracts | architecture.md, secs-contracts.md |
AI / agent testing: use docs/agent-playtest-protocol.md to run
window.__endgateCapture.runPlaytestSuite() against the dev client and read
ranked recommendations for the next core-loop wave.
The target design is the realtime village loop with wave-reset persistent
village. Each system doc under docs/systems/ describes both
shipped baseline and target direction. The shipped prototype still uses manual
wave start and instant build until RTL waves land.
The current shipped loop is the AAA-quality top-down Three.js village-defense shell: win advances to the next wave; loss pays energy and returns to planning so the same wave can be retried after upgrades, repair, expansion, and character repositioning.
Running
Run the server and client in separate terminals from the workspace root.
Server
dotnet run --project examples/endgate/Server
examples/endgate/Server/Program.cs maps the SignalR hub at /gamehub, exposes a /health endpoint, and defaults to http://localhost:5064 when urls / ASPNETCORE_URLS is not set.
Client
cd examples/endgate/Client && npm install && npm run dev
The client is a React 19 + Vite app that uses @microsoft/signalr to connect to the Endgate server. It serves the app on http://localhost:5178/endgate/ and proxies /endgate/gamehub back to the ASP.NET Core server on http://localhost:5064.
For a persistent dev session, use the Zellij session host-endgate (one full-width tab for the server, one for the client — not split panes):
bash scripts/run-endgate-dev.sh start # create session + tabs if needed
bash scripts/run-endgate-dev.sh attach
bash scripts/run-endgate-dev.sh restart # after crashes or old pane layouts
See docs/project/pr-zellij-dev-sessions.md for session names, ports, and Valenar parity.
Tailnet routing is managed from the workspace host manifest. After run-endgate-dev.sh start:
bash scripts/host-tailscale.sh apply
Open https://herki-pc-ubuntu.taila0ab6f.ts.net/ for the project menu, or /endgate/ for Endgate directly. See docs/project/pr-tailscale-host-routing.md.
Tests and Benchmarks
Server-contract coverage:
dotnet test tests/Endgate.Server.Tests/Endgate.Server.Tests.csproj
Generated provenance and wave-script sync guards:
dotnet test tests/SECS.Standalone.Tests/SECS.Standalone.Tests.csproj --filter FullyQualifiedName~EndgateGeneratedProvenanceGuardTests
dotnet test tests/SECS.Standalone.Tests/SECS.Standalone.Tests.csproj --filter FullyQualifiedName~EndgateWaveScriptSourceSyncGuardTests
Authority benchmarks:
dotnet run --project examples/endgate/Benchmarks/Endgate.Benchmarks.csproj -c Release
Content and Generated
Content/*.secs files are the committed authored inputs for Endgate schema rows.
Generated/Endgate.Generated.csproj invokes secsc build --generated-namespace Endgate.Generated, includes the emitted C# from obj/**/SecsGenerated, and
exposes Endgate.Generated.SecsModule.BuildSchema().
Only explicit non-schema host/catalog helpers remain hand-maintained under
Generated/, currently item definition catalogs and wave-script lookup
mappings. Those retained files may reference compiler-emitted IDs, but they must
not construct schema row families or replace SecsModule.BuildSchema().