Where the game stops
The core site does not know what game it serves, what that game calls a group of players, or that Ultima Online and Rust exist. Everything that does lives in an installable module on the other side of a declared interface — which is what makes "put your game on it" a shape rather than a slogan.
A module declares which versions of the interface it speaks. If that does not match what the site offers, it refuses to load and the site comes up without it.
Not just screens: its routes, its database tables, its navigation rows, its slice of the OpenAPI spec and its own prebuilt client bundle. Installing it is a paste in the admin panel or a line in your environment — never a build step, because production runs an image you pulled, and an operator who has to compile something has been handed a maintenance job rather than a feature.
A module that will not load is marked as failed and the site starts without it. Disabling one is a kill switch, not a visibility flag — its routes stop answering and its live connections close. Uninstalling keeps the data, and destroying the data is a separate, deliberate choice made in its own dialog.
Core owns the Teams primitive — the roster, the forum, the notifications, the voice channel — and does not own the word. A Team cannot be created in core at all; it arrives from the module, which is why each module calls them by its own game’s word and builds those pages itself. That is the pattern the whole interface is built on: core supplies the machinery, the module supplies the meaning.
Two modules exist: Ultima Online, and Rust, which this project built second, from the Integration Kit. Where the Rust module needed something the contract did not yet offer, the gap was closed in core, for every module, rather than in a fork — so the seam now has two games on its far side instead of one. What two modules built inside this project cannot prove is that somebody outside it can do the same, and that is why the Integration Kit still says draft.