Repository navigation
Repository layout
What's in the repository today: the files at its root, every project and what it depends on, the tests and the CI workflow. The server core itself isn't built yet; its design is on Server core design, and the codec, its first piece, is on Codec design.
| File | Holds |
|---|---|
global.json |
The SDK pin, 10.0.400 with rollForward: latestPatch, and Microsoft Testing Platform as the test runner |
Directory.Build.props |
Nullable reference types on for every project; every warning an error; code-style rules run in the build; the analysis level pinned to 10-recommended
|
Directory.Build.targets |
The hot-path switch: a project that sets <HotPath>true</HotPath> gets the banned-API list and the hot-path rules as errors |
Directory.Packages.props |
Every package version, pinned exactly (central package management) |
nuget.config |
nuget.org as the only package source, mapped for every package |
.editorconfig |
Formatting, style and naming rules, and every suppression with its reason |
.gitattributes |
* text=auto eol=crlf: text stored with LF, checked out with CRLF on every system |
.git-blame-ignore-revs |
Mechanical commits git blame skips: the line-ending normalization, the formatting pass and the renames |
README.md, CONTRIBUTING.md, SECURITY.md, LICENSE
|
The front door, the contributor rules, how to report a security problem, the AGPL-3.0 |
| Folder | Holds |
|---|---|
Source/ |
Every project, and the solution Source/NexusTomorrow.slnx
|
Tests/ |
One test project per project under test |
Tools/ |
One-off tools that work on the code itself; today the model converter, deleted when the codec step ends |
Build/HotPath/ |
The hot-path ban list (BannedSymbols.txt) and the rules it raises to errors (HotPath.globalconfig) |
.github/workflows/ |
The Tests workflow |
Every library targets net10.0, except the generator, which targets netstandard2.0 because the compiler loads it.
| Project | Holds | References | Nullable |
|---|---|---|---|
NexusTomorrow.Shared |
Factories, configuration binding, the update timer, shared extensions | On | |
NexusTomorrow.Cryptography |
SRP6 login maths, the packet cipher, password and random helpers | On | |
NexusTomorrow.IO |
Readers for the client's area files; reader and writer for the server's map format, .nfmap
|
On | |
NexusTomorrow.Game.Static |
The game's enums and flags, one folder per system | On | |
NexusTomorrow.GameTable |
Typed loading of the client's game tables (.tbl) and text tables |
Game.Static, Shared
|
On |
NexusTomorrow.Network.Codec |
The bit reader and writer, the declaration attributes, the layout types, and the client facts table. Hot path | On | |
NexusTomorrow.Network.Codec.Generator |
The source generator that writes each declared type's reader, writer and layout, and its diagnostics NTC001 to NTC013
|
On | |
NexusTomorrow.Network |
The old bit-level reader and writer, message framing, the opcode list, and the [WireMessage] attribute beside it |
Cryptography, Network.Codec, Shared
|
On |
NexusTomorrow.Network.Sts |
Message models for the STS login protocol, in XML | On | |
NexusTomorrow.Network.Auth |
Message declarations for the auth server; the generated reader and writer are their only code |
Game.Static, Network; the generator |
Off |
NexusTomorrow.Network.World |
Message declarations for the world server; the generated reader and writer are their only code |
Game.Static, Network; the generator |
Off |
The two projects with nullable reference types off are the ones the codec's conversion replaces; they're converted as part of it. Every project builds with every warning as an error; those two also switch their analysers off until then. Network, Network.Auth and Network.World run the generator, which writes each model's reader, writer and size, and one WireMessages registry per assembly with a factory per direction keyed by opcode. The old bit reader and writer still sit in Network until stage 3 deletes them; only the legacy snapshot uses them now.
| Project | Does | References |
|---|---|---|
NexusTomorrow.MapGenerator |
Extracts the game tables and localization files from your client, and generates .nfmap map files from its area files |
GameTable, IO, Shared
|
NexusTomorrow.ClientConnector |
Starts your client with a server's address on its command line. Windows only | Shared |
NexusTomorrow.ModelConverter, in Tools/
|
Converts the old message models into codec declarations, in place, and reports every type it leaves alone. One-off |
Game.Static, Network
|
How to run the first two is in the repository's README.md. Their output is built from your client and never goes in the repository. The converter reads only our own source.
| Package | Used by |
|---|---|
Microsoft.Extensions.* (configuration, dependency injection, logging, options) |
Shared, Network, GameTable, MapGenerator, the tests |
Microsoft.CodeAnalysis.CSharp, Microsoft.CodeAnalysis.Analyzers
|
The generator and its tests; the converter and its tests |
Microsoft.CodeAnalysis.BannedApiAnalyzers |
Every hot-path project, added by Directory.Build.targets
|
NLog |
Shared |
Newtonsoft.Json |
GameTable, ClientConnector
|
CommandLineParser |
MapGenerator |
Nexus.Archive |
MapGenerator, to read the client's archives |
xunit.v3.mtp-v2, Microsoft.Testing.Extensions.TrxReport
|
The tests |
| Project | Tests |
|---|---|
NexusTomorrow.Network.Codec.Tests |
The bit reader and writer against hand-derived bytes and against the old reader and writer; strings and packed floats; generated code on test messages of every member shape; the facts check over every message Network, Network.Auth and Network.World declare, with each disagreement pinned |
NexusTomorrow.Network.Codec.Generator.Tests |
Every diagnostic, and the source the generator emits |
NexusTomorrow.ModelConverter.Tests |
Each conversion pattern, on models compiled against the real old reader and writer |
NexusTomorrow.Network.Equivalence.Tests |
That every converted type writes and reads the same bytes as its old twin in the legacy snapshot, and that the harness catches the mistakes it's built to catch. Temporary, deleted with the snapshot |
NexusTomorrow.Cryptography.Tests |
The SRP6 session key is always 64 bytes |
NexusTomorrow.GameTable.Tests |
A missing or empty GameTablePath fails options validation, and a bound one passes |
NexusTomorrow.ClientConnector.Tests |
Reading the configuration throws, naming the key, when the host name or language is missing or empty, and returns both when they're set |
268 tests in all, in seven xUnit v3 test applications on Microsoft Testing Platform: 146 in the codec's, 64 in the generator's, 30 in the equivalence harness's, 21 in the converter's, and 7 in the other three. One of the equivalence tests covers every converted type.
Tests/NexusTomorrow.Network.Legacy holds no tests. It's an unchanged copy of the old message models from Network.World, Network.Auth and Network, compiled against the old reader and writer, so the conversion can be proven to produce the same bytes as the code it replaces. It's temporary: the codec's third stage deletes it along with the old primitives.
.github/workflows/test.yml, named Tests:
| Step | Does |
|---|---|
| Trigger |
workflow_dispatch only, with an optional args input passed to the test applications |
| Runner | ubuntu-24.04 |
| Permissions | contents: read |
| Checkout | Full history, so the commit check can see every commit since main; the token isn't kept in the checkout |
| Commit messages | Every commit in origin/main..HEAD: a blank second line, a headline of 72 characters or fewer, no full stop at its end |
| Em dashes | Fails on any em dash in a .cs or .md file, and lists where |
| Set up .NET | Installs the SDK global.json asks for: the latest 10.0.4xx patch |
| Restore, build | Against Source/NexusTomorrow.slnx, in Debug |
| Format |
dotnet format Source/NexusTomorrow.slnx --verify-no-changes, after the build, because it loads the codec's generator from the build output |
| Test | Every test application, with a .trx report |
| Upload results | The test-results artifact, uploaded even when tests fail |
Every action is pinned to a full commit. Running the tests shows how to dispatch it.
-
NexusTomorrow.Network.AuthandNexusTomorrow.Network.Worldstill opt out of nullable reference types, switch their analysers off, and suppress the generator'sNTC003andNTC006with<NoWarn>, until the codec's third stage settles each width from the client facts and brings them under the analysers. Their model classes keep their old names until then too, soServerPathInitialisethe class answers toServerPathInitializethe opcode. - The facts check pins 55 disagreements with the client facts, each with its reason, until the codec's third stage fixes them.
- The legacy snapshot is a second copy of every old model, about 1,180 files, until stage 3 deletes it. Its copies shadow the originals it references, on purpose: they're the ones it compares.
-
GameMessageOpcode.csstill names one opcode by its number,Server_0x178_SoundTrigger. The duplicate value it used to declare is settled. -
MapGeneratorandClientConnectorhaven't been run against a real client since the nullable work changed how they read their settings. - The old server's login front door, permissions and GM command definitions aren't here yet. They were part of the trunk that was deleted, and come back lifted from the old code when the core is ready for them.
| Piece | Path |
|---|---|
| The solution | Source/NexusTomorrow.slnx |
| Projects | Source/NexusTomorrow.*/ |
| The codec | Source/NexusTomorrow.Network.Codec/ |
| The generator | Source/NexusTomorrow.Network.Codec.Generator/ |
| The converter | Tools/NexusTomorrow.ModelConverter/ |
| The client facts table | Source/NexusTomorrow.Network.Codec/Facts/wire-facts-16042.jsonl |
| The hot-path switch and list |
Directory.Build.targets, Build/HotPath/
|
| Tests | Tests/NexusTomorrow.*.Tests/ |
| Package versions | Directory.Packages.props |
| The workflow | .github/workflows/test.yml |
Start here
How the server works
- Server core design
- Host
- Gateway
- Owners
- Persistence
- Command layer
- Harness
- Map scheduler design
- Timer wheel design
The protocol
Working on it