Game
The spine of **GANESHA: GUARDIAN OF THE PORTAL**. One shared module every slice requires: the tuning numbers, the eight Rakshasas and their arenas, the eleven quests, the story machine's acts, the mount points, and the event bus. It draws nothing, moves nothing and sounds nothing…
Game
The spine of GANESHA: GUARDIAN OF THE PORTAL. One shared module every slice requires: the tuning numbers, the eight Rakshasas and their arenas, the eleven quests, the story machine's acts, the mount points, and the event bus. It draws nothing, moves nothing and sounds nothing — it is the contract that lets a slice be written without knowing who else is in the world.
require returns one shared instance per world, so G.state read in the
hero slice is the same table the interface slice reads, and G.on / G.emit
is how one slice learns what another did.
Exports
G.TITLE,G.SUBTITLE— the title card's own words.G.ART_STYLE— the one art-direction sentence every visual decision answers to.G.PALETTE(hex, for the interface) andG.RGB(0-1 triples, for lights/materials).G.ACT/G.ACT_ORDER— the story machine's phases.G.QUESTS— the eleven quests, in order:{ title, objective }.G.PLAYER— the guardian's 2000 HP, speeds, stamina, jump.G.ATTACKS/G.ATTACK_ORDER/G.ABILITY_BAR— the four attacks with damage, timing, reach, arc and cooldown.G.FOES— the eight Rakshasas: health, speed, damage, reach, behaviour, tells.G.ARENAS— the eight battlefields: ground colour, sky, sun, fog, props.G.BEATS— timings for the beats between fights.G.state— the shared run state (act, quest, arena, health, foe, banner…).G.EV— event names;G.on(name, fn)andG.emit(name, payload).G.setAct/G.setQuest/G.setArena— the only writers of those fields.G.banner/G.toast/G.kick/G.freeze— the presentation verbs.G.MOUNTS/G.SLICES— where each slice is booted.G.clamp/G.lerp/G.damp/G.angleDelta/G.horizDist/G.yawTo.G.arena()/G.foeAt(i)/G.questForArena(i)/G.restart().
Usage
local G = require("game.Game")
G.on(G.EV.FOE_DIED, function(foe)
G.setQuest(G.questForArena(G.state.arena))
end)
if G.state.act == G.ACT.FIGHT then
local arena = G.arena()
local tuning = G.foeAt(G.state.arena)
end
Notes
- State has one writer per field. The hero slice owns
health,staminaandcooldowns; the foes slice ownsfoeandbossBar; the world slice ownsacttransitions from its own beats. Announce changes withG.emitso the interface and the sound slice hear them. - The bus is per world, not per frame. Subscribe in
start()and keep the unsubscribe function the subscribe returns; drop it inonDestroy()or a reload will leave two listeners running. - Arenas are 1-indexed and match
G.FOESbyarena.foe.
Scoped to this part · feeds back into the world's score.