Scoping investigation for an in-house, game-agnostic email and engagement system: modules declare domain events and their data contract, core owns the rules, preferences, templates and delivery. Records the current-state map (notifications, email, the module contract and the job/scheduling infrastructure), a gap list, the proposed schema additions, the module registration mechanism, an eleven-phase plan with an acceptance check per phase, and a catalogue of what the system could be used for. Five findings contradict the brief this started from and shape the plan: - There is no in-app channel. Core has one sink, the content-free push tickle; the in-app inbox has to be built, not adapted. - Email is already two-thirds of an engagement system, scoped to Teams. The Teams pipeline is generalised and migrated onto the new one, not duplicated. - The IDOC example's payload is not on the wire, and estimated_collapse is not exactly knowable in advance: ServUO draws each decay stage's duration at random when the stage is entered, so it is exact only at IDOC. - Event-name collision handling already exists (registries.js namespaced() + apply()), so the brief's forward-compat note is already satisfied. - MODULE_API_VERSION 1.6.0 is on main now, so the engagement additions take a real 1.7.0 rather than joining 1.6.0 in place. Five scope decisions settled by the org lead are recorded at the top: the in-app channel is in scope, the Teams pipeline is migrated, the house.decay protocol enrichment is in scope, Gmail OAuth2 is removed rather than retained as a transport, and the system ships with seeded templates plus an editor. No code. Nothing is implemented until the org lead approves the phase. Co-Authored-By: Claude <noreply@anthropic.com>
123 lines
7.8 KiB
Markdown
123 lines
7.8 KiB
Markdown
# Runic Gateway — Documentation
|
|
|
|
Central documentation for the Runic Gateway platform. The docs here were
|
|
extracted from the two code repositories (with full commit history preserved)
|
|
so they live in one place, independent of either codebase.
|
|
|
|
## Layout
|
|
|
|
```
|
|
website/ docs from the website core (Node/Express + MariaDB + React/Vite)
|
|
modules/ docs for installable game modules — one directory per module id
|
|
link/ docs from the ServUO bridge (C# plugin + Rust sidecar + Node WS)
|
|
android/ docs from the native Android client (Kotlin + Jetpack Compose)
|
|
installer/ docs for the installer that deploys a shard's bridge components
|
|
ci/ cross-cutting CI/quality notes
|
|
```
|
|
|
|
**Setting up a shard?** [`installer/INSTALL.md`](installer/INSTALL.md) is the operator guide, and
|
|
the installer is the supported path: one binary deploys the plugin overlay, installs the uo-link
|
|
sidecar as a service, and hands you the values the website needs.
|
|
|
|
### `website/`
|
|
| Doc | What it covers |
|
|
|---|---|
|
|
| [BACKEND_DESIGN.md](website/BACKEND_DESIGN.md) | API contract, DB schema, security model |
|
|
| [ARCHITECTURE.md](website/ARCHITECTURE.md) | The system diagram — how core, an installed module, the sidecar and the clients fit together |
|
|
| [TEAMS.md](website/TEAMS.md) | Teams as a platform primitive: roster, forums, notifications, Discord slash commands and voice — design of record |
|
|
| [ENGAGEMENT.md](website/ENGAGEMENT.md) | The engagement system: module-declared event triggers, rules, cooldowns, templates and the email / push / in-app delivery channels — design of record |
|
|
| [HERO_EDITOR.md](website/HERO_EDITOR.md) | Hero canvas editor feature spec |
|
|
| [THEMING_AND_NAV.md](website/THEMING_AND_NAV.md) | Admin-configurable theme, brand assets and navigation — build contract |
|
|
| [MODULE_SYSTEM.md](website/MODULE_SYSTEM.md) | Making the site game-agnostic: game logic becomes an installable module — design of record |
|
|
| [MODULE_API.md](website/MODULE_API.md) | The module ↔ core contract: `ctx`, the `register*` calls, the client registry and the loader's obligations |
|
|
| [WIKI_UPGRADE.md](website/WIKI_UPGRADE.md) | Wiki subsystem upgrade notes |
|
|
| [SHARD_VISIBILITY.md](website/SHARD_VISIBILITY.md) | Who sees which shard data — the admin-configurable audience framework |
|
|
| [TRUSTED_DEVICES_MFA.md](website/TRUSTED_DEVICES_MFA.md) | TOTP two-factor, trusted devices and recovery codes |
|
|
| [MODERATION_APPEALS.md](website/MODERATION_APPEALS.md) | Moderation actions, content reports and the appeals flow |
|
|
| [SPAWN_ATLAS.md](website/SPAWN_ATLAS.md) | The bestiary / spawn atlas: what the shard contains, parsed from its own ServUO tree |
|
|
| [CLILOCS.md](website/CLILOCS.md) | UO's id → name table: converting one from your client so items have names |
|
|
| [UOFIDDLER.md](website/UOFIDDLER.md) | **Operator runbook** — step-by-step extraction from your own UO client (cliloc table, creature art) |
|
|
| [MARKETPLACE.md](website/MARKETPLACE.md) | The player-vendor index: how it is gathered, what it costs, how to tune it |
|
|
| [website-README.md](website/website-README.md) | Snapshot of the website repo's README (setup/run reference) |
|
|
| [test-plan.md](website/test-plan.md) | The website's test strategy and harness |
|
|
| [API_V2_PLAN.md](website/API_V2_PLAN.md) | Router domain split + CSP hardening. The split is complete; only the CSP enforce step remains |
|
|
| [API_V2_SKELETON.md](website/API_V2_SKELETON.md) | **Superseded** — the `/api/v2` scaffold that was never built. Kept as the record of why the split was done in place instead |
|
|
| [PROJECT_TREE.md](website/PROJECT_TREE.md) | Auto-generated snapshot of the repo's tracked file layout |
|
|
|
|
### `modules/`
|
|
|
|
Documentation for installable game modules aggregates here rather than in each module's repo
|
|
([MODULE_SYSTEM.md](website/MODULE_SYSTEM.md) §2.10). The website core knows nothing about any
|
|
particular game; a module is what makes it a site *for* one.
|
|
|
|
| Doc | What it covers |
|
|
|---|---|
|
|
| [uo/](modules/uo/README.md) | **module-uo** — the Ultima Online module: what it serves, what it owns, and what an operator needs |
|
|
| [uo/API.md](modules/uo/API.md) · [uo/SCHEMA.md](modules/uo/SCHEMA.md) | module-uo's own route surface and the tables it owns |
|
|
| [kit-acceptance.md](modules/kit-acceptance.md) | The Integration Kit acceptance run — building a module by following the kit alone, and what it found |
|
|
| [rust-dryrun.md](modules/rust-dryrun.md) | A written, deliberately unimplemented `module-rust` — the test that the module contract generalises past the game it was extracted from |
|
|
|
|
### `link/`
|
|
| Doc | What it covers |
|
|
|---|---|
|
|
| [INTEGRATION.md](link/INTEGRATION.md) | How the website integrates with the uo-link sidecar |
|
|
| [PROTOCOL_2.md](link/PROTOCOL_2.md) | Protocol 2.0 / 2.1 design |
|
|
| [v3.md](link/v3.md) | Protocol 3.0 design — shard content/standings streams + the visibility framework |
|
|
| [v4.md](link/v4.md) | Protocol 4.0 — guild membership on the wire (`guild.roster`, `guild.leave`). **The current protocol** |
|
|
| [ADMIN_CONTROLS.md](link/ADMIN_CONTROLS.md) | Staff write-plane (kick/ban/broadcast, page queue) |
|
|
| [SHARD_PREREQS.md](link/SHARD_PREREQS.md) | Shard-side prerequisites for the bridge |
|
|
| [PLAN.md](link/PLAN.md) | uo-link build plan |
|
|
| [RESEARCH.md](link/RESEARCH.md) | Research notes |
|
|
| [link-README.md](link/link-README.md) | Snapshot of the link repo's README |
|
|
| [PROJECT_TREE.md](link/PROJECT_TREE.md) | Auto-generated snapshot of the repo's tracked file layout |
|
|
|
|
### `android/`
|
|
| Doc | What it covers |
|
|
|---|---|
|
|
| [PLAN.md](android/PLAN.md) | Android client build plan / milestones |
|
|
| [COVERAGE_PLAN.md](android/COVERAGE_PLAN.md) | Test-coverage rollout plan |
|
|
| [APP_LINKS.md](android/APP_LINKS.md) | Android App Links / deep-link setup |
|
|
| [theme-plan.md](android/theme-plan.md) | Theming plan |
|
|
| [THEMING_AND_NAV.md](android/THEMING_AND_NAV.md) | The app's half of admin-configurable theming and navigation — build contract |
|
|
| [TRUSTED_DEVICES_APP_HANDOFF.md](android/TRUSTED_DEVICES_APP_HANDOFF.md) | Trusted-devices app handoff notes |
|
|
| [PROJECT_TREE.md](android/PROJECT_TREE.md) | Auto-generated snapshot of the repo's tracked file layout |
|
|
|
|
### `installer/`
|
|
| Doc | What it covers |
|
|
|---|---|
|
|
| [INSTALL.md](installer/INSTALL.md) | **Start here to set up a shard** — the installer deploys the plugin overlay and the uo-link sidecar, registers the service, and connects it to the website. Appendix A is the same thing by hand, still supported |
|
|
| [PLAN.md](installer/PLAN.md) | Installer design of record — phases, locked decisions, the bundle/compat-matrix model |
|
|
| [PROJECT_TREE.md](installer/PROJECT_TREE.md) | Auto-generated snapshot of the repo's tracked file layout |
|
|
|
|
### `ci/`
|
|
| Doc | What it covers |
|
|
|---|---|
|
|
| [SONARQUBE.md](ci/SONARQUBE.md) | The SonarQube setup: project keys, how analysis runs, and how to read a report |
|
|
|
|
## Provenance
|
|
|
|
- `website/*` was extracted from `RunicGateway/website` via `git filter-repo`.
|
|
- `link/*` was extracted from `RunicGateway/link` via `git filter-repo`.
|
|
|
|
Commit history and authorship for each doc are preserved. The two source repos
|
|
retain a short pointer to this repo in their own READMEs; the authoritative copy
|
|
of each document now lives here.
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
Runic Gateway's documentation is free: licensed under the **GNU General Public
|
|
License v3.0 or later** — see [LICENSE.md](LICENSE.md).
|
|
|
|
Copyright (C) 2026 Runic Gateway
|
|
|
|
This documentation is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY. You may redistribute and/or modify it under the terms of
|
|
the GNU General Public License as published by the Free Software Foundation,
|
|
either version 3 of the License, or (at your option) any later version.
|
|
|
|
Contributions are welcome — please read [CONTRIBUTING.md](CONTRIBUTING.md) (note
|
|
the **AI-usage disclosure** requirement) and our
|
|
[Code of Conduct](CODE_OF_CONDUCT.md).
|