---
name: modtrick
description: >
  Bootstrap and enforce ModTrick "everything is a mod" architecture for games.
  Use when the user mentions modtrick.com, modtrick.pages.dev, /modtrick,
  /modtrick-bootstrap, "everything is a mod", "how to build a mod", "add modding
  to my game", ModRuntime, configure mod, mod config, ASEC, Core Gameplay Kit,
  orbit/FPS/third-person, particles, post-fx, collectibles, quest, portal, HUD,
  teaching a game to load mods, or scaffolding mod.json. Works across Grok Build,
  Claude Code, Codex, and Cursor.
---

# ModTrick — Everything Is a Mod

**Primary:** https://modtrick.com · **Fallback:** https://modtrick.pages.dev  
**Fetch first:** `/agents/bootstrap.json`  
**Config catalog:** `/agents/mod-catalog.json`  
**Config guide:** `/docs/MOD-CONFIG.md`  
**Law:** `/docs/EVERYTHING-IS-A-MOD.md`  
**Build:** `/docs/HOW-TO-BUILD-A-MOD.md`  
**Game paste:** `/docs/agents/ADD-MODDING-TO-GAME.md`  
**Proof:** `/game/outpost/`

## Absolute rules

1. **Everything is a mod** — `mods/<id>/` + `mod.json` (ASEC) + `AGENT.md`.  
2. **Game = ModRuntime host** — no second plugin system.  
3. **ASEC:** META · GENESIS · SHADOW · MGS.  
4. **MGS:** install → tune → verify → maintain.  
5. **Configure don’t rewrite** — use `configure()` / `runtime.configure(id, opts)` for tunables.  
6. **Host inject** — under ModRuntime, `camera` / `renderer` / `domElement` / `bus` auto-fill.  
7. **SHADOW honesty.** Prefer catalog mods.

---

## Subskill A — Bootstrap a game

```
1. GET bootstrap.json + MOD-CONFIG.md
2. Copy host/mod-runtime.js (+ frame-context.js)
3. runtime = new ModRuntime({ scene, camera, renderer, THREE })
4. runtime.setDefaults(id, { ... }) // optional globals
5. await runtime.loadManifestUrl(..., { options })
6. each frame: runtime.tick(t, dt); runtime.render(t)
7. Update game AGENTS.md
```

See `references/add-modding-to-game.md`.

---

## Subskill B — Configure existing mods (prefer this)

When user wants tweaks (“more gems”, “slower cam”, “heavier rain”):

```js
runtime.configure("threejs-collectibles", { count: /* not hot - recreate */, collectDistance: 2, respawn: true });
// For count/shape rebuild: dispose + load again with new options
handle.getConfig(); // inspect
runtime.list();     // all loaded + configs
```

| Prefer | Avoid |
|--------|--------|
| `configure` / presets | Forking mod source for numbers |
| bus fields (`bus.damage`, `bus.toast`) | Cross-importing other mods’ internals |
| `setDefaults` before load | Hard-coding host paths in packages |

Full field tables: `references/mod-config.md` + `/agents/mod-catalog.json`.

### Hot vs cold

- **Hot:** safe in `configure()` (speeds, colors, distances, enabled, many UI fields).  
- **Cold:** geometry counts, mesh topology — dispose + recreate with new GENESIS options.

---

## Subskill C — Author a new mod

Follow `references/how-to-build-a-mod.md` and:

1. Use `/mods/_shared/mod-kit.js` → `injectHost`, `mergeConfig`, `withConfig`.  
2. Implement `getConfig` + `configure`.  
3. Add `config` block to `mod.json` (`fields`, `hot`, `presets`, `needsHost`).  
4. Document bus in/out in AGENT.md.  
5. Register catalog + bootstrap + mod-catalog.json.

---

## Subskill D — Bus contracts (coupling)

Do not deep-import mods. Publish/consume:

`playerPos`, `playerYaw`, `character`, `sunDir`, `sunColor`, `score`, `collected`, `health`, `dead`, `damage`, `heal`, `currency`, `currencyDelta`, `sfx`, `toast`, `dialogue`, `timeOfDay`, `fps`, …

---

## Core mod matrix (abbreviated)

| id | export | needsHost | notes |
|----|--------|-----------|--------|
| threejs-grid-floor | createGridFloor | — | stage |
| threejs-sky | createSky | — | setTimeOfDay, sun |
| threejs-ocean | createOcean | — | setWind/setParams |
| threejs-orbit-camera | createOrbitCamera | camera, dom | |
| threejs-fps-controller | createFpsController | camera, dom | |
| threejs-third-person | createThirdPerson | camera, dom | + target, bounds, configure |
| threejs-simple-character | createSimpleCharacter | — | bus.playerPos |
| threejs-collectibles | createCollectibles | — | presets, respawn, configure |
| threejs-particles | createParticles | — | 6 presets, configure |
| threejs-post-fx | createPostFx | renderer, camera | **render()** |
| threejs-hud | createHud | DOM | theme, bus hud* |
| threejs-health | createHealth | DOM opt | i-frames, regen |
| threejs-quest | createQuest | — | auto gems |
| threejs-portal | createPortal | character | A↔B |
| threejs-day-cycle | createDayCycle | sky | |
| threejs-currency | createCurrency | — | |
| threejs-inventory | createInventory | — | |
| threejs-dialogue-box | createDialogueBox | DOM | |
| threejs-audio-bus | createAudioBus | gesture | |
| threejs-light-rig | createLightRig | — | sun follow |
| threejs-debug-stats | createDebugStats | renderer | |
| threejs-toast | createToast | DOM | |
| … | see mod-catalog.json | | 30 packages |

**Playground:** `/studio/playground.html` · **Outpost:** `/game/outpost/`

---

## Load + configure example

```js
const runtime = new ModRuntime({ scene, camera, renderer, THREE });
runtime.setDefaults("threejs-particles", { preset: "embers" });
await runtime.loadManifestUrl(`${BASE}/mods/threejs-collectibles/mod.json`, {
  baseUrl: `${BASE}/mods/threejs-collectibles/`,
  options: { preset: "coins", count: 20 },
});
runtime.configure("threejs-collectibles", { respawn: true });
// frame:
runtime.tick(t, dt);
runtime.render(t);
```

---

## Refuse

- Free-floating systems without mod packages  
- Editing mod source for simple tunables (use configure)  
- Parallel loaders bypassing ModRuntime  
- Overselling SHADOW residuals  

## References

- `references/architecture.md` — law  
- `references/mod-config.md` — configuration subskill  
- `references/how-to-build-a-mod.md`  
- `references/add-modding-to-game.md`  
- `references/host-integration.md`  
- `references/harness-matrix.md`  
