Chapter 8: Ship It
The Final Mile
Section titled “The Final Mile”You’ve built a complete game. Now it’s time to package it and submit it to the Ludus marketplace. This chapter covers:
- Creating the manifest
- Running quality gates locally
- Submitting through the pipeline
- Getting listed on the catalog
Step 1: The Manifest
Section titled “Step 1: The Manifest”Every Ludus game ships with a ludus.manifest.json:
{ "name": "mercante", "version": "1.0.0", "displayName": "Mercante", "description": "Renaissance merchant trading — buy, sell, invest, and bet your way to fortune in Florence", "author": { "name": "Your Name", "wallet": "0x..." }, "game": { "file": "dist/index.js", "export": "Mercante" }, "playerRange": { "min": 2, "max": 6 }, "category": "economic", "tags": ["trading", "economic", "renaissance", "defi", "tutorial"], "license": "MIT"}Validation Rules
Section titled “Validation Rules”The manifest is validated strictly:
| Field | Rule |
|---|---|
name | Kebab-case, 3-64 chars |
version | Semver (X.Y.Z) |
displayName | Non-empty |
description | Non-empty, max 256 chars |
author.name | Required |
author.wallet | Required for revenue payouts |
game.file | Path to compiled JS (must exist) |
game.export | Exported symbol name |
playerRange | min >= 1, min <= max |
category | One of: strategy, economic, social, card, dice, territory, puzzle, party, other |
tags | Max 10, max 32 chars each |
license | SPDX identifier |
You can validate before submitting:
import { validateManifest } from "@ludus/game-protocol";
const errors = validateManifest(manifest);if (errors.length > 0) { console.error("Fix these:", errors);}Step 2: Quality Gates (Pre-flight)
Section titled “Step 2: Quality Gates (Pre-flight)”Run all four gates locally before submitting:
import { QualityGateRunner } from "@ludus/game-protocol";import Mercante from "./game";
const runner = new QualityGateRunner();const results = runner.runAll(manifest, packageContents, () => Mercante);const summary = runner.summarize(results);
console.log(`Gates: ${summary.passedGates}/${summary.totalGates} passed`);console.log(`Duration: ${summary.totalDurationMs}ms`);
if (!summary.passed) { for (const r of results) { if (!r.passed) { console.error(`FAIL ${r.gate}: ${r.details}`); } }}Gate 1: SDK Compliance
Section titled “Gate 1: SDK Compliance”Checks that Mercante implements all 7 required methods plus metadata.
Mercante status: PASS. We implemented every method in Chapter 1.
Gate 2: Security
Section titled “Gate 2: Security”Scans source code for banned patterns: dynamic code execution, file system access, network calls.
Mercante status: PASS. Our game logic is pure — no I/O, no network, no dynamic imports.
Gate 3: Determinism
Section titled “Gate 3: Determinism”Runs the game 3 times with seed 42 and compares outputs.
Mercante status: PASS. We use SeededRNG exclusively. structuredClone() for state. No Math.random() or Date.now().
Gate 4: Performance
Section titled “Gate 4: Performance”Profiles executeAction() for 50 turns. Each must complete under 5000ms.
Mercante status: PASS. Our game logic is O(n) where n = number of goods (6). No expensive algorithms.
Step 3: Submit
Section titled “Step 3: Submit”import { SubmissionService, InMemorySubmissionStore } from "@ludus/game-protocol";
const store = new InMemorySubmissionStore();const service = new SubmissionService(store);
// 1. Upload → DRAFTconst submission = service.submit(packageContents, "your-wallet-address");
// 2. Submit for review → runs quality gates automaticallyconst reviewed = service.submitForReview( submission.id, packageContents, () => Mercante,);
// 3. Check resultif (reviewed.status === "REVIEW") { console.log("All gates passed! Awaiting review."); // A human reviewer or DAO vote will approve or reject}Status Flow
Section titled “Status Flow”DRAFT → PENDING → TESTING → REVIEW → LISTED | | +→ REJECTED ←+After TESTING, if all gates pass, the submission goes to REVIEW. A human reviewer (or DAO governance in the future) approves it, and the game gets LISTED.
Step 4: On the Catalog
Section titled “Step 4: On the Catalog”Once listed, your game appears in the catalog:
import { CatalogService } from "@ludus/game-protocol";
// Search for your gameconst results = await catalog.search({ query: "mercante", category: "economic",});
// Check popularity (composite score 0-100)const entry = results.entries[0];console.log(entry.popularity); // Downloads 40%, Rating 30%, Recency 20%, Completions 10%Version Updates
Section titled “Version Updates”When you improve the game, publish a new version:
import { VersionManager } from "@ludus/game-protocol";
// Register version 1.1.0manager.registerVersion("mercante", { version: "1.1.0", manifestHash: hash, listedAt: new Date(), deprecated: false,});
// Deprecate 1.0.0 (30-day grace period)manager.deprecateVersion("mercante", "1.0.0", "Balance improvements in 1.1.0");Revenue
Section titled “Revenue”You earn 70% of all platform fees generated by your game:
| What | Fee | Your Share |
|---|---|---|
| Match entry fee | Set by platform | 70% |
| Prediction market vig | 3% of payouts | 70% of vig |
Revenue tracks to the author.wallet in your manifest. The RevenueEngine handles accounting:
import { RevenueEngine } from "@ludus/game-protocol";
const report = engine.getRevenueReport("mercante", startDate, endDate);console.log(`Total fees: ${report.totalFees}`);console.log(`Your share: ${report.developerShare}`); // 70%console.log(`Protocol share: ${report.protocolShare}`); // 30%The Complete Picture
Section titled “The Complete Picture”Congratulations — you’ve built a full-stack Ludus game that integrates every layer:
┌─────────────────────────────────────────────────────────┐│ Mercante (Game interface) Ch 1 ││ ├── AI Agents (5 merchant archetypes) Ch 2 ││ ├── IL BANDITORE (commentary persona) Ch 3 ││ ├── Spectator Viewer (live + replay) Ch 4 ││ ├── Merchant Wallets (MPC, SIWA, ERC-8004) Ch 5 ││ ├── DeFi Trading (swaps, lending, tracking) Ch 6 ││ ├── Prediction Markets (3 market types) Ch 7 ││ └── Protocol (manifest, gates, catalog) Ch 8 │└─────────────────────────────────────────────────────────┘Every package in the Ludus monorepo is exercised. The game is:
- Deterministic — Same seed = same game, verified by quality gates
- Pure — No side effects, no I/O in game logic
- Spectatable — Live viewing, commentary, price charts
- Tradeable — Prediction markets on outcomes
- DeFi-native — Swaps, lending, position tracking
- On-chain — Agent wallets, authentication, revenue sharing
What’s Next
Section titled “What’s Next”- Customize — Use Mercante as a template. Swap the theme, change the mechanics, create your own game.
- Deploy — Publish to the catalog and start earning.
- Compete — Pit your agents against the community’s best.
The Florentine market is open. Fortune awaits.
Back to: Introduction | Build-a-Game Reference