Repository navigation
Roadmap
The order we build the server core in, and where it stands. What each step builds is on Server core design; this page is about sequence and progress.
We build the core in six steps, and each one ends green in public CI and, where it has one, passes its check in game. The first goal anyone can see is milestone one: log in, create a character, enter the world, walk, see another player move, and /say. Each step gets its own plan once the step before it is done, so every plan starts from code that exists rather than code we assume.
The order follows what each step needs to be tested at all.
- The codec comes before anything that sends a message, because nothing that talks to a client can be tested until messages can be declared. The codec's converter also needs the leaves split out of the old code first, so steps 1 and 2 share one plan.
- The message audit comes before the core skeleton, because every system after it talks to the client through those messages, and a message the client misreads fails silently, far from its cause.
- The core skeleton comes before milestone one, because the milestone's checks run in the test harness, and the harness drives the server through the command layer the skeleton builds.
- The console follows milestone one straight away, since by then there's a server worth administering.
- Systems go in dependency order. Content first, because nothing happens in an empty world. Events and the read model before quests and achievements, because those consume them. Combat last, because it needs the geometry bake.
| Step | Delivers | Done when | Status |
|---|---|---|---|
| 1. Repository | The seeded repository, cut to the leaves that carry over, renamed, with nullable reference types on, tests and CI | Builds green with the leaves alone | Done on bootstrap, two checks owed |
| 2. Codec | The declaration format, the source generator, a converter from the old message models, the client-facts table and its check | Every message declared; the facts check passes after fixing what it reports | Stage 3 of 3, paused for the message audit: all 1,119 of the client's messages declared, and 1,022 agree with the client's full layouts, 152 disagreements pinned; the first area, pregame, checked, with 40 of its 42 messages verified to their fields |
| 3. Core skeleton | Owners and their message queues, the map scheduler, the timer wheel, the gateway and transport, the write-behind queue, the command layer and CLI, the test harness | Harness scenarios for routing, the owner protocols, saves and the allocation gate pass | Planned |
| 4. Milestone one | Pregame on the lifted login front door; character list, create and select; world entry; movement relay; seeing others; /say
|
The milestone scenarios pass, and an in-game pass shows no add-on errors | Planned |
| 5. Console | The web admin console and the player portal | Every command is refused without its permission and audited; the origin and second-factor rules hold | Planned |
| 6. Systems | The content pipeline and the world database conversion first; then events and the read model, quests and achievements, economy and social; the combat track with the geometry bake later | Each system's tests and in-game check | Planned |
The pregame conversation that leads up to it, from logging in to selecting a character, is on Client protocol. World entry takes these server messages and no more, sent in this order:
| Opcode | What it does | Note |
|---|---|---|
0x00AD EnterWorld
|
Moves the client into a world, with a point for the world to load around. The character's own position comes later, from the world | First. The client accepts it only once a character is selected |
0x0262 |
Creates the player's own unit | |
0x019B |
Binds that unit as the player | Fails if the unit doesn't exist yet |
0x00F1 |
The instance's settings, among them the update interval | Sent on every world entry |
0x0636 |
Grants the player control of the unit | The only way to grant it; without it the player can't move |
0x025E |
The character's own data: money, inventory, experience and the like | A stub at this stage |
0x0061 |
Ends the loading screen | |
0x06BC |
The player's path | The one message whose absence shows an add-on error |
Seeing others adds their create (0x0262), their movement relayed (0x0638), and a destroy when they leave. /say adds 0x01C2 to the sender, which is how it sees its own line, and 0x01C8 to listeners, on the client's built-in Say channel (type 4, id 0).
Done on bootstrap:
- the repository seeded once from NexusForever's
game_reworkwith its full history, and the old server trunk deleted in one commit; - the eleven projects that carried over renamed to
NexusTomorrow.*; - the SDK pinned, central package management, and a test workflow that runs only when dispatched;
- the SRP6 session key fixed to always be 64 bytes (it came out at 63 bytes on roughly one login in 256, which would give the client and server different world ciphers);
- nullable reference types on in nine of the eleven projects, with
Network.AuthandNetwork.Worldleft for step 2, which has since turned them on; - the code standard adopted and enforced in the build, with the tree normalized, formatted and renamed to it.
Two run-time checks are owed before bootstrap merges into main, both on a machine with a client: MapGenerator extracting tables from a real client, and ClientConnector writing its config.json from the first-run prompts and starting the client. Both changed shape in the nullable work, and only a real run proves the reflection-bound settings they now read.
The codec is built in three stages, and the first two are on bootstrap, each reviewed. Stage 1 is the machinery: the bit reader and writer, the hot-path switch, the declaration language, the source generator, and the client facts table with its check. Stage 2 declared every one of the old message models, 1,254 of them, and proved 1,227 declared types bit for bit against the old code; the 26 it couldn't prove are defects in the old code. Stage 3 has settled the opcode list and the swapped fields, brought the empty-path check down to 55 pinned disagreements, and deleted the old code: its reader and writer, its packet layer, the converter, and the copy of the old models the conversion was proven against. The facts check is the proof that remains. The design, and what's still open in it, is on Codec design.
Stage 3 is paused for an audit of every message. We assume every message and opcode we inherited is wrong until the client says otherwise. Before any more feature work, every message the client registers is checked against the client: its full layout first, then what it's for and what each of its fields means, and for the flows milestone one needs, the order the client expects. Each declaration records how far it has been verified, and a test holds every message to that, so nothing is used before it's verified. Until a message is verified it carries a neutral name and its fields carry no meaning, so the code never claims something nobody has checked. The results are published on this wiki as a protocol reference generated from the declarations, and step 3 starts once the audit closes. The whole design is on Message audit design. The neutral names, the verification check and the full-layout check are in, and all 1,119 of the client's messages are declared. The first area, pregame (login, realm select and character select), has been checked as far as milestone one needs: 40 of its 42 messages are verified down to their fields, and those 40 are the first messages the core may use, character creation (0x025B CharacterCreate), the character list (0x0117 CharacterList) and world entry (0x00AD EnterWorld) among them. Milestone one's next areas are world entry, entity commands and movement, and chat.
There's no upstream. The repository was seeded once and is never synced: no cherry-picks, and no comparing against NexusForever's server. The trunk is replaced, so upstream's changes to it don't apply, and the leaves have already moved on.
One plan per step, written when the step before it is done.
One world. An open-world zone is one map that every player in it shares, never split into layers or shards, so the people in a place can always see each other. Capacity work goes into making a crowded map cheaper to run, and once step 3 lands a load test measures how many players one map holds. Server core design has how.
Built to be hosted publicly. The core is designed, built and documented for a public deployment: Linux as the reference host, client ports hardened against hostile input, backups with a tested restore, outside monitoring, and DDoS protection at the host. A fresh install still binds everything to loopback, so going public is configuration. Server core design has the details.
Out of scope for the core:
| Area | Why |
|---|---|
| Creature AI and the volume of combat rules | The combat track's work. The core fixes the combat contract and the effect engine's shape |
| Content volume | The core builds the pipeline; filling the world is content work |
| Idea | What killed it |
|---|---|
| Keeping a playable server running through the rebuild | It would mean refactoring the old trunk in place, which the server core design rejects. The cost is a dark period until milestone one |
| Syncing with NexusForever | The trunk it changes is the part we replace, and the leaves have diverged |
| Building game systems before the core skeleton | Every system would be written against plumbing that's about to change |
| Claim | Basis |
|---|---|
| Steps 1 and 2 so far build and their tests pass | The CI run in the header badge: 263 of 263, step 1's seven among them |
| The SRP6 key fix | A test that fails on the old derivation and passes on the new one |
MapGenerator and ClientConnector still work |
Not run since the nullable work. Owed, as above |
| Milestone one's message list | Established from the client; the in-game pass that opens every window once is still to do |
- Whether pregame sends what the client needs to offer the Expert start and the level-50 entry.
- Which systems in step 6 come after events and the read model, beyond the order above.
| Piece | Path |
|---|---|
| What each step delivers |
Source/, Tools/
|
| The tests behind each step's status | Tests/ |
| The CI workflow that runs them | .github/workflows/test.yml |
Guides
Explanation
Reference
Design
About this wiki