# Game server (`NeonSprawl.Server`) ASP.NET Core **.NET 10** host for authoritative simulation (prototype: HTTP + health + in-memory position read API). ## Prerequisites - **.NET 10 SDK** (matches `TargetFramework` in `NeonSprawl.Server.csproj`). Check with `dotnet --list-sdks`. ## Run ```bash cd server/NeonSprawl.Server dotnet run ``` - Default URL is printed by Kestrel (see `Properties/launchSettings.json`, typically `http://localhost:5253`). - Check `GET /health` for a JSON heartbeat. ## Position state (NS-15) Authoritative player position is held **in memory** (no database yet). The HTTP JSON shape is versioned with top-level `schemaVersion` (see XML docs on `PositionStateResponse` in the server project). Path `{id}` is **trimmed** and matched **case-insensitively** against stored players; `playerId` in the JSON body echoes the path segment from the request. Example (dev player id defaults to `dev-local-1` in `appsettings.json`): ```bash curl -s http://localhost:5253/game/players/dev-local-1/position ``` Sample response: ```json {"schemaVersion":1,"playerId":"dev-local-1","position":{"x":0,"y":0,"z":0},"sequence":0} ``` Unknown player ids return **404**. This endpoint is a **spike** until durable persistence and full sync exist. ## Move command (NS-16) **`POST /game/players/{id}/move`** with JSON body applies a v1 **MoveCommand**: authoritative position **snaps** to `target` immediately; `sequence` in responses increases by one per successful apply. Request body (example): ```bash curl -s -X POST http://localhost:5253/game/players/dev-local-1/move \ -H "Content-Type: application/json" \ -d '{"schemaVersion":1,"target":{"x":1.5,"y":0,"z":-2}}' ``` - **200** — body matches **`PositionStateResponse`** (same shape as `GET` … `/position`). - **400** — missing/invalid body or `schemaVersion` ≠ `1`. - **404** — unknown player id. See XML on `MoveCommandRequest` and `PositionStateResponse` in the server project. For a **PR/Jira-ready** contract blurb (formatted JSON + field table), see the [NS-15 implementation plan — Pull request description](../../docs/plans/NS-15-implementation-plan.md#pull-request-description-jira-ac) (GET shape) and [NS-16 implementation plan](../../docs/plans/NS-16-implementation-plan.md#pull-request-description-jira-ac--draft-for-merge) (MoveCommand + sequence semantics). ## Solution From repo root: `dotnet build NeonSprawl.sln` and `dotnet test NeonSprawl.sln`. ## CI Pull requests targeting `main` run build and tests via [`.github/workflows/dotnet.yml`](../.github/workflows/dotnet.yml) on GitHub Actions (`ubuntu-latest` runner, **Release** configuration). ## Linux + Rider: “only 8.x in /usr/share/dotnet” If the debugger prints **`.NET location: /usr/share/dotnet`** and **cannot find `Microsoft.NETCore.App` 10.x** while you have .NET 10 under **`~/.dotnet`**: - **`launchSettings.json` `environmentVariables`** (e.g. `DOTNET_ROOT`) often do **not** apply to the **native apphost** Rider launches first; the host probes `/usr/share/dotnet` before your app starts. - This repo sets **`false`** for **Debug** builds so the IDE runs **`dotnet …/NeonSprawl.Server.dll`** using the **.NET CLI** you configured in the toolchain (**`/home/don/.dotnet/dotnet`**), which then loads the 10.x shared runtime from the same install. - Alternatives: install [.NET 10 into the default location](https://learn.microsoft.com/en-us/dotnet/core/install/linux) so `/usr/share/dotnet` has 10.x, or add **`DOTNET_ROOT=/home/don/.dotnet`** in **Run → Edit Configurations → Environment variables** (IDE-level, not only `launchSettings.json`).