Files
h-school/README.md
T

3.8 KiB
Raw Blame History

h-school

Base for a multiplayer browser game: an authoritative .NET server simulating the world with an ECS, a PixiJS client that renders snapshots, and .NET Aspire tying them together for local runs and integration tests.

There is no game here yet — there is a world with a few obstacles, players that can walk around it, and every piece of plumbing needed to build a game on top.

Stack

Layer Choice
Server .NET 10, ASP.NET Core
Simulation Arch ECS, fixed 20 Hz tick
Transport raw WebSocket, custom binary protocol
Client TypeScript, PixiJS 8, Vite
Orchestration .NET Aspire 13
Tests xUnit v3, Vitest, Aspire.Hosting.Testing

Prerequisites

  • .NET SDK 10 (global.json pins the 10.0.1xx band)
  • Node.js 22.12 or newer
  • Optional: the Aspire CLI (dotnet tool install -g aspire.cli) if you prefer aspire run

Run everything

dotnet run --project src/HSchool.AppHost

On Windows run-aspire.cmd does the same and can be double-clicked; it checks that the .NET SDK and Node are on PATH first and passes any arguments through (run-aspire.cmd --launch-profile http).

The Aspire dashboard opens with two resources: server (ASP.NET Core) and client (Vite dev server). Aspire assigns the client a random port on every run, so take its URL from the dashboard rather than guessing. Open it and use WASD or the arrow keys to move — the HUD shows connection state, server tick, round-trip time and entity count.

Open the same URL in a second tab to see another player: both are simulated by the one server.

Run the pieces separately

dotnet run --project src/HSchool.Server
npm --prefix src/HSchool.Client run dev

Without Aspire the client falls back to http://localhost:5180 for its /api and /ws proxy, which matches the server's launch profile.

Tests

dotnet test
  • tests/HSchool.Protocol.Tests — wire-format round-trips and byte layouts.
  • tests/HSchool.Simulation.Tests — ECS behaviour against GameWorld, no host involved.
  • tests/HSchool.AppHost.Tests — boots the real Aspire graph, connects a WebSocket, plays a few ticks. Runs headless (--HSchool:Headless=true), so no Node install is needed.
npm --prefix src/HSchool.Client test

Vitest covers the client codec and snapshot interpolation.

Layout

src/
  HSchool.Protocol/        binary wire format (shared contract with the client)
  HSchool.Simulation/      Arch ECS world, components, systems
  HSchool.Server/          ASP.NET Core host, WebSocket endpoint, game loop
  HSchool.ServiceDefaults/ Aspire telemetry, health checks, resilience
  HSchool.AppHost/         Aspire orchestration
  HSchool.Client/          Vite + TypeScript + PixiJS renderer
tests/
docs/
  architecture.md          how the pieces fit together
  protocol.md              the wire format, byte by byte
AGENTS.md                  working agreements for humans and coding agents

Configuration

Simulation tunables live under the Simulation section of src/HSchool.Server/appsettings.json:

Key Default Meaning
TickRate 20 fixed simulation steps per second
WorldWidth / WorldHeight 1600 × 900 field size in simulation units
PlayerSpeed 260 units per second
PlayerRadius 18 player body radius

What is deliberately missing

No authentication, no persistence, no client-side prediction, no delta compression, no rooms or matchmaking. Each of these has a natural seam described in docs/architecture.md.