neon-sprawl/server
VinPropane 3882b0e2c6 NS-16: MoveCommand → server PositionState, Godot sync, tests
Implement E1.M1 intent → authority: POST /game/players/{id}/move with v1 JSON
MoveCommandRequest (snap + sequence), extend in-memory store and
PositionStateApi. Godot client splits ground_pick and position_authority_client
with thin main.gd; snap_to_server on player.

Tests live under NeonSprawl.Server.Tests/Game/PositionState/ with AAA layout
and MethodName_ShouldExpectedOutcome_WhenScenario naming. Debug builds use
UseAppHost=false so Linux IDEs resolve .NET 10 from a user-local SDK.

Add NS-16 implementation plan, code review doc, godot-client-script-organization
rule, csharp test layout/naming rules, and refresh E1.M1 / alignment docs.
Server and client README updates include move API, prerequisites, and Rider
notes.

Made-with: Cursor
2026-03-30 19:54:17 -04:00
..
NeonSprawl.Server NS-16: MoveCommand → server PositionState, Godot sync, tests 2026-03-30 19:54:17 -04:00
NeonSprawl.Server.Tests NS-16: MoveCommand → server PositionState, Godot sync, tests 2026-03-30 19:54:17 -04:00
README.md NS-16: MoveCommand → server PositionState, Godot sync, tests 2026-03-30 19:54:17 -04:00

README.md

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

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):

curl -s http://localhost:5253/game/players/dev-local-1/position

Sample response:

{"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):

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 schemaVersion1.
  • 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 (GET shape) and NS-16 implementation plan (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 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 <UseAppHost>false</UseAppHost> 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 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).