# OgUi
Origocraft's view layer — every zui screen, as **pure builders**: each
returns a widget tree from the current game state and never mutates it.
Screens it builds:
- **Menus** — main / class-select / settings / credits.
- **HUD** — player, target, and pet frames; the ability hotbar; the
Dawnvale minimap; the quest tracker; the combat log; the XP bar.
- **World overlay** — floating combat text, enemy nameplates, the cast
bar, boss slam warnings, audio-cue subtitles, the victory banner.
- **Panels** — inventory/character, NPC dialogue, vendor, bank, pause,
and death.
## How the controller drives it
The screens read live game state through six refs the controller
**binds once per refresh**, then calls the builders:
```luau
local Ui = require("@root::og.OgUi")
Ui.bind({ S = state, U = uiState, actors = actors,
saved = saved, w2s = worldToScreen, readPos = readPos })
ui.updateScreen("og_frames", Ui.scrFrames())
ui.updateScreen("og_menu", Ui.buildMenu())
```
Exposed builders: `scrDim`, `buildMenu`, `buildPanel`, `scrFrames`,
`scrMap`, `scrQuest`, `scrLog`, `scrBar`, `buildOverlay`.
Requires [OgData](../OgData.module) and [OgSim](../OgSim.module) for
content and queries, and `@builtin::modules.zui` for widgets. Reskinning
the game is a matter of editing this module — the palette `C` and every
layout live here, and nothing here touches entities or the simulation.
# OgData
Static design data for Origocraft — the Dawnvale starter zone. Pure
tables, zero dependencies.
Exposes tuning constants (`GCD`, `XP_CURVE`, `MAX_LEVEL`, ranges) and the
content tables:
- `CLASSES` — warrior / mage / hunter, each with resource model and a
5-ability hotbar.
- `MOBS` — dawnwolf → the Grovekeeper boss, with AI/stat/drop fields.
- `ITEMS` — equipment, **consumables** (health/mana potions with an
`effect` + `cooldown`), quest items, and junk.
- `QUESTS` — the four-quest Dawnvale chain.
- `NPCS`, `NPC_QUESTS`, `STARTER` — town actors, quest givers, starting kit.
- `VENDOR_STOCK` — the item ids Vendor Pip offers for purchase.
```luau
local Data = require("@root::og.OgData")
local warrior = Data.CLASSES.warrior
```
Required by [OgSim](../OgSim.module) (logic) and the OrigoGame
controller (view). Change balance/content here and both pick it up on
hot-reload.
# OgVoxel
A module script.
# OgScenery
The scenery builder for Origocraft. Spawns the static stage — Dawnvale
town, the Whispering Wood, the mire, the Sunken Glade, the graveyard,
and **Frostmere Reach** (the northern frontier: a snowfield, Frostmere
Hold keep, frozen pines, and the Frost-Jarl's hall) — plus the PBR
materials they use.
- `ensureMaterials()` — idempotently creates the `ow_*` material set.
- `buildScenery()` — clears prior scenery (`ow_prop`/`ground`) and
rebuilds the whole zone. Safe to call repeatedly.
- `clearAll()` — despawn scenery only.
- `LAYOUT` — the data the controller reads to place actors:
`playerSpawn`, `graveyard`, `townCenter`, `dungeonCenter`, `packs`,
`crates`.
```luau
local Scenery = require("@root::og.OgScenery")
Scenery.buildScenery()
local spawn = Scenery.LAYOUT.playerSpawn
```
No data dependency. Spawns only from its functions — never at module
load — so requiring it is side-effect free.
# OgSim
The Origocraft simulation kernel — engine-agnostic gameplay logic that
operates on a plain `state` table. No `entity`, `ui`, `camera`, or
rendering calls live here, so the same systems can drive any view.
`state = OgSim.newState()` then `OgSim.createCharacter(state, class, name)`
gives a live game. The controller calls into these each tick:
- **Character & stats** — `createCharacter`, `recomputeStats`,
`relearnAbilities`, `hotbar`.
- **Combat & casting** — `tryCast`, `canCast`, `tickCasting`,
`resolveAbility`, `tickAutoAttack`, `damageMob` (rolls **critical
strikes** on player damage via `opts.canCrit` + `player.critChance`),
`damagePlayer`.
- **Mobs & boss** — `tickMob`, `mobAttack`, `tickBoss`, `killMob`,
targeting (`cycleTarget`, `setTarget`, `targetMob`).
- **Quests** — `acceptQuest`, `questEvent`, `turnInQuest`,
`npcQuestState`.
- **Inventory & economy** — `addItem`, `equip`, `sellItem`, `buyItem`
(vendor purchase), `useConsumable` (drink potions on a shared
cooldown), `bankDeposit`/`bankWithdraw`.
- **Progression** — `grantXp`, `onLevelUp`, `xpToNext`.
- **Persistence** — `serialize`/`deserialize`,
`saveSnapshot`/`loadSnapshot`.
```luau
local Sim = require("@root::og.OgSim")
local state = Sim.newState()
Sim.createCharacter(state, "warrior", "Recruit")
```
Requires [OgData](../OgData.module). Side-effecting world updates
(moving entities, audio, UI) are the controller's job — OgSim only
mutates `state` and appends to its `floaters` / `cues` / `combatLog`
queues for the controller to drain.