Mawu · Features

Moremi: The Server-Authoritative Roleplay Framework

A focused page within the Mawu Features documentation. The full map and every sibling page live in the Features hub.

6sections11 minread1diagram

On this page

Every great roleplay community of the last decade — the cities, the "serious RP" servers, the economies with their own police, paramedics, and corner stores — was built on the same trick: a host process owns the truth of the world, and everyone else is a guest who can only ask to change it. That is the FiveM / Cfx.re lineage, and Moremi is V7's answer to it, hardened for a creator republic where the platform does not trust the people who run the worlds.

Moremi is the framework that lets a creator stand up a deep roleplay realm — a living city, a frontier town, a courtroom drama with a real docket — and have it stay fair without the platform paying to babysit every instance. It gives that creator three things: a server-authoritative simulation host that owns money, items, and position so a tampered client can never grant itself any of them; a reference roleplay framework (the Nàná core) that ships working characters, jobs, an economy, property, and civic institutions out of the box, the way ESX/QBCore/Qbox shipped them for FiveM; and a two-level governance model where a realm owner is sovereign over their own rules but never above the platform's safety floor. The behaviour of a realm is assembled from resources — bundles of assets, data, and sandboxed WASM scripts — and the frameworks creators build are themselves resources, so the whole thing is extensible all the way down.

This page is the feature-level tour of that framework: what server authority buys you, what the Nàná core gives a creator on day one, and where the honest edges are. The netcode and the deterministic-simulation engineering live in the companion ../architecture/moremi-realm-server-and-netcode.md; the realm/population topology lives in ./realm-model-and-danu-population.md and the script sandbox in ./ixchel-sandbox-and-modding.md. For the full V7 feature scope this slots into, start at the hub: ../V7_features.md.

What ships, honestly#

The description and the code do not fully agree, and this page follows the code. Three honest layers:

  • Real and eval-gated. The entire Nàná roleplay domain is genuine, test-driven Rust in apps/v7/moremi-realm-server/src/lib.rs: a character store with Iris-consent deletion limits, a job registry, a double-entry economy ledger, an inflation auto-balancer, a property registry with ACLs, civic institutions (law / EMS-fire / government), and realm moderation. Each system has a strict passed() eval gate that would fail on a stub. The server-authority security path — validate-before-mutate, HMAC-signed intents, scope checks — is genuine Rust in libs/v7/realm-protocol/src/lib.rs. There are 69 #[test] cases in the server, 30 in realm-protocol, and 2 in libs/v7/nana, and they assert domain correctness (debits equal credits, a realm owner cannot silently erase a character, a realm ban is never global).
  • Library-grade, not a running daemon. The server's run_service() (lib.rs:12462) calls run_health_server(&DESCRIPTOR), which binds a socket and answers exactly one route — GET /health (apps/v7/service_contract.rs:36, :88). There is no accept loop feeding live client packets into a ticking realm, and the crate has no tokio and no QUIC dependency despite the monolith's # Rust + tokio + QUIC note — its deps are wasmtime, pubgrub, semver, sha2, and four workspace path crates (v7-nana, v7-realm-protocol, v7-substrate-bridge, and the danu-mesh-cluster sibling) (Cargo.toml). The simulation and every Nàná system are exercised by evals, not by a live socket. Treat Moremi as a verified runtime library, not a deployed cluster.
  • Product model vs. code. The standalone libs/v7/nana crate is intentionally tiny — a NanaCharacterRecord with validate() and nothing else (nana/src/lib.rs:14, :84) — because the real Nàná systems live in the server crate as the MoremiNana* type family. And several headline realm options in the monolith are product model with no code today: a search of the server for federation, corridor, permadeath, and crypto returns zero hits. Cross-realm character corridors, federated economy bridges, and permadeath are described intent, not implemented behaviour. Society accounts, by contrast, are real (MoremiNanaLedgerAccountKind::Society).

The roleplay framework: resources and the Nàná core#

A realm's behaviour is built from resources — the FiveM unit, here hardened and capability-sandboxed. A resource is an Ixchel mod layer that bundles assets, data, and executable scripts (TypeScript or visual logic, both compiled to the same WASM target), declares its dependencies and the sandbox tier it needs, exports events and callbacks for other resources to consume, and hot-loads at runtime. The roleplay frameworks a community builds — the V7 equivalents of ESX, QBCore, and the ox libraries — are themselves resources: a base framework resource exposes inventory/job/economy primitives, and content resources build on it.

V7 ships that base framework so a server owner has a working RP loop out of the box. The server advertises it in its DESCRIPTOR (lib.rs:98) — owner "Moremi", port 47201, and 121 capability strings — under the nana-reference-base-framework and default-realm-boot-smoke capabilities, and run_moremi_nana_default_realm_boot() (lib.rs:5031) proves the reference framework boots a default realm cleanly. The sandbox that makes community code safe to run at all — the six capability tiers, fuel budgeting, the escape-corpus CI gate — is its own subject; see ./ixchel-sandbox-and-modding.md.

Server authority: the structural anti-cheat foundation#

The load-bearing rule is Design Posture 1: all gameplay state is server-authoritative, and the sender is assumed hostile. Clients send intent; the realm validates it against the rules before anything touches state, then replicates the result. This is not a policy — it is enforced in the type system of libs/v7/realm-protocol.

A client message arrives as a RealmEnvelope (:140) carrying a RealmSecurityToken (:121, a platform-issued HMAC-SHA256 binding of a sender to a realm audience), a signed intent with issue/expiry stamps, and a detached signature. validate_cross_trust (:1781) checks shape, sender identity, signature presence, intent freshness, the token's audience/expiry/MAC, and the envelope signature — in that order, returning a precise typed error on the first failure. Only then does apply_client_intent_to_authoritative_state (:1835) run: it re-validates cross-trust, rejects any non-ClientIntent message, requires the realm ids to match, and requires the token to carry the realm.intent.submit scope (REALM_CLIENT_INTENT_REQUIRED_SCOPE, :82) before it parses the movement and advances the actor. The whole chain is exercised adversarially by run_event_tamper_eval (:2624), which accepts one valid intent (state hash changes) and replays a corpus of hostile attempts — forged MAC, wrong audience, expired intent, missing scope — asserting that every hostile attempt leaves the authoritative state hash byte-for-byte unchanged. Money, items, and position are server-owned; a tampered client cannot mint any of them.

Server authority only means something if the server is reproducible, so the simulation is deterministic by construction: a fixed timestep (MOREMI_FIXED_TIMESTEP_HZ = 30 for persistent zones, MOREMI_COMBAT_TICK_HZ = 60 for combat, lib.rs:73:74), a SHA-256 state hash folded over actor positions (run_moremi_deterministic_replay, :9117), a smoke test that replays the same input log twice and compares hashes (run_moremi_determinism_smoke, :9151), and untrusted creator scripts metered by fuel (MOREMI_IXCHEL_DETERMINISTIC_FUEL_PER_TICK = 8_000, :78) so a plugin traps at the same instruction on every replay. The world is not ticked at one rate, either: run_moremi_dual_tick_fixture_case (:3622) runs combat at 60 Hz and open-world entities at an interest-banded 10 / 20 / 30 Hz (MoremiOpenWorldInterestBand::update_hz, :3482), bounded by a hard per-node budget (MOREMI_DUAL_TICK_NODE_BUDGET_US_PER_SECOND = 20_000, :77). The deep netcode — prediction/reconciliation, snapshot interpolation, delta compression, lag compensation, and the packet-loss gate — is the architecture companion's subject.

sequenceDiagram participant C as Client (Mawu UE5) participant M as Moremi Realm Server (Rust, authoritative) participant N as Nephthys (durable truth) C->>M: RealmEnvelope{ signed ClientIntent } M->>M: validate_cross_trust (token MAC, intent expiry, signature) M->>M: require realm.intent.submit scope, realm-id match alt valid M->>M: apply intent -> tick deterministic sim -> state hash changes M->>N: durable authority view (crash-recoverable) M-->>C: authoritative delta (interest-filtered) else hostile (forged MAC / expired / wrong audience / no scope) M-->>C: typed rejection; state hash UNCHANGED end

What creators can build: the Nàná framework#

This is where Moremi stops being plumbing and becomes a roleplay platform. The Nàná core ships the systems that make a realm a functioning society, each as a real MoremiNana* implementation with its own eval gate.

Persistent characters, not accounts#

A player plays a character, not just a login. The wire-level record is a NanaCharacterRecord (libs/v7/nana/src/lib.rs:14) — an Ori identity, a realm id, a display name, employment, and realm-scoped balances — and the server wraps it in a MoremiNanaCharacterStore (lib.rs:3889) that persists, loads, and audits it across sessions. The governance teeth are real: persistence and deletion are both gated by an MoremiNanaIrisConsentGrant (lib.rs:3809), and request_deletion (lib.rs:3954) refuses a realm owner who tries to delete a character without the originating user's Iris consentRealmOwnerDeletionRequiresIrisConsent, logged as denied:iris-consent-required. Even a permitted deletion is a tombstone (deleted_at), not an erase. This is the V6 steward-not-owner posture made executable, and run_moremi_nana_character_deletion_limit_eval (lib.rs:5162) pins it: its violation set includes SilentRealmOwnerDeletionAllowed and CharacterRecordErased, so the gate fails if either ever happens.

Jobs#

Jobs are the spine of RP, and the MoremiNanaJobRegistry (lib.rs:4149) ships them as data. A MoremiNanaJobDefinition (lib.rs:4114) has a legality flag (Legal / Illegal), and a stack of grades, each with a title, a payout_minor_per_shift, and duties. register_resource (lib.rs:4159) loads jobs from a resource and records which resource authored each one, so a community job is attributed to its mod; assign_job (lib.rs:4167) resolves a job and grade, sets the character's on_duty employment, and returns a receipt with the duties and payout. V7 ships both a reference registry (moremi_reference_job_registry_resource, lib.rs:5311) and a community example (lib.rs:5364), and run_moremi_nana_job_registry_eval (lib.rs:5394) proves a realm can load both, cover legal and illegal work, and assign from each.

A real economy with real inflation control#

The economy is a double-entry ledger, not a balance counter. MoremiNanaEconomyLedger::post_entry (lib.rs:4393) rejects any entry that is not balanced() (lib.rs:4360) — every line is purely a debit or purely a credit, and total debits must equal total credits — or that touches an unknown account. Accounts come in Cash, Bank, Society, Faucet, and Sink kinds (lib.rs:4267); payroll, fines, and taxed purchases settle through them, and run_moremi_nana_economy_ledger_eval (lib.rs:5585) only passes if the authoritative writer is "moremi:server-authority", all three flows posted, and the ledger's imbalance is exactly zero.

What turns that into a tunable society is the inflation auto-balancer. A realm owner configures sink primitives — RepairDegradation, PropertyUpkeep, TransactionTax, ServiceFee (lib.rs:4505) — and a target inflation band; the balancer samples a MoremiNanaEconomyHealthSnapshot (money supply, faucet flow, sink flow, inflation, sink coverage) and adjusts the transaction tax to pull inflation back into band (run_moremi_nana_inflation_balancer_eval, lib.rs:5945). Its eval flags a SinklessConfigNotFlagged economy — a money faucet with no drain — as a violation, which is exactly the failure mode that wrecks amateur RP economies. The real-money creator economy (Abundantia) is kept strictly separate from in-realm play currency to keep gambling/age/compliance lines clean.

Property and persistent interiors#

run_moremi_nana_property_eval (lib.rs:6174) backs ownable housing, businesses, and vehicles. A MoremiNanaPropertyAsset carries a MoremiNanaPersistentInterior (lib.rs:4667) and an access-control list of MoremiNanaPropertyAclEntrys granting typed rights (MoremiNanaPropertyAclRight, lib.rs:4636) — so storage and entry are permissioned, not open. Crucially, an interior is a handoff target, not a loading-screen instance: a MoremiNanaDanuInteriorHandoffProbe (lib.rs:4698) models a building's inside as a meshed shard the Danu population layer can hand a player into seamlessly. The meshing mechanics belong to ./realm-model-and-danu-population.md.

Civic institutions — the "serious RP" layer#

Realms can run structured institutions, shipped as toggleable resources on the Nàná core and proven by run_moremi_nana_civic_institutions_eval (lib.rs:6487). Three kinds exist (MoremiNanaCivicInstitutionKind, lib.rs:4764): Law, with a CAD/MDT record family — CadMdtRecord, Warrant, ChargeBooking (MoremiNanaCivicRecordKind, lib.rs:4771) and a dispatch loop; EMS/Fire, with a Downed → Revive → Treatment response loop tied to the character record; and Government, with License, Permit, and BusinessRegistration. The eval loads each as a real resource, runs its dispatch loop, and fails if a LawCadMdtMissing or EmsFireLoopMissing gap appears — a dispatcher coordinating units is a first- class, tested RP moment, not a vibe.

Whitelisting and realm moderation#

A realm owner runs their own door inside the platform floor. The membership policy is Open / Whitelisted / InviteOnly (lib.rs:4906); whitelist applications carry a character backstory and a reviewer decision, and the gate admits approved applicants and denies unapproved ones. In-realm admin tools cover Spectate, Freeze, Teleport, Kick, and RealmBan (MoremiNanaAdminActionKind, lib.rs:4940), and every action is written to a moderation audit log. Platform-policy violations escalate to a MoremiNanaKuanyinEscalation (lib.rs:4971) for human review. The two-level model is enforced, not aspirational: run_moremi_nana_moderation_eval (lib.rs:6967) only passes if every MoremiNanaRealmBan is scoped_to_realm and not platform_global — a realm owner can ban from their own realm but can never issue a platform-wide ban, which only Kuanyin/Themis can do.

The Unreal side#

The client half of Moremi in V7/ue/Source/MawuRealm is honest about its scope. AMawuComposedRealmActor (Public/MawuComposedRealmActor.h:14) is not a net driver and does no prediction — it is a lock-file compositor: ApplyLockFile takes an Ixchel FMawuRealmLockFile (priority-ordered layers of primitives) and builds the realm's geometry on the client through real UE5 Geometry Script operations on a runtime UDynamicMesh (BuildProceduralPrimitive calls AppendBox, ApplyMeshSolidify, and boolean Union/Subtract/Intersection, Private/MawuComposedRealmActor.cpp), folding triangle/vertex/watertight stats into an FMawuCompositionReport. Its Build.cs depends on GeometryFramework/GeometryScriptingCore/DynamicMeshno networking module at all. What is server-shaped is the build target: MawuDedicatedRealmServer.Target.cs is a TargetType.Server build compiled with project-module FPSemanticsMode.Precise, stricter /fp:strict /fp:except- on Win64, and V7_MAWU_DEDICATED_REALM=1 — the engine-side constraint paired with the authoritative Rust replay-hash gate. The integrated path — a Mawu client speaking the realm wire format to a live moremi-realm-server through the gateway — is not assembled in code yet.

Where this connects#