Ambroflow is a game runtime. It plays games. It does not author them — that is the Atelier's function. The distinction matters: Ambroflow receives a game definition and executes it. Your game definition specifies the world, the entities, the rules, and the lore. Ambroflow provides the engine that makes those definitions live.
The engine is an economic and cultural artifact. It was built by practitioners of Wunashako — a practice of relational trance and structural clarity — and its architecture reflects that origin. The systems that handle player transformation are not metaphors. They are designed to encode, track, and respond to genuine change in a player's navigational relationship to a game world. What you do with that is yours to determine.
The engine repository is separate from any specific game. Games built on Ambroflow link against it as a dependency. They define their worlds using the engine's schema; the engine provides execution.
Ambroflow is organized around a central game state machine that coordinates discrete subsystems. Each subsystem is independently queryable and writable. The state machine does not impose narrative structure; it provides the substrate on which narrative structure runs.
from ambroflow.engine import GameEngine engine = GameEngine( world_def = my_world, # your WorldDefinition player_def = my_player, # your PlayerDefinition config = my_config, # GameConfig ) engine.start() state = engine.tick(player_input)
Every tick() advances the world by one input event and returns
the current GameState. The state is a snapshot: it contains the
full world and player state at that moment, including all memory layers, active
quests, inventory, sanity values, and the current resonance token.
| Subsystem | Responsibility | Entry Point |
|---|---|---|
| World Runtime | Zone management, entity placement, terrain | engine.world |
| Player State | Skills, stats, flags, inventory | engine.player |
| Quest Tracker | Quest state, objectives, completion flags | engine.quests |
| Sanity System | 4-fold sanity, consonance/dissonance | engine.sanity |
| Alchemy | Spatial transformation, reagent resolution | engine.alchemy |
| Memory | Narrative, Relational, Akashic, Personal layers | engine.memory |
| Encounter | Conflict resolution, skill checks | engine.encounter |
| Resonance | State fingerprinting and delta tracking | engine.resonance |
| Orrery | Cross-game state propagation (optional) | engine.orrery |
Ambroflow's world model is zone-based. A world is a graph of zones connected by exits. Each zone has a terrain type, dimensions, entity spawns, and a set of exits that connect it to other zones. The engine handles pathfinding between zones using A* over the zone graph.
from ambroflow.world import Zone, Exit, Terrain market_square = Zone( id = "market_square", name = "The Market Square", width = 32, height = 24, terrain = Terrain.COBBLESTONE, description = "Stone-paved and loud with trade at any hour.", exits = [ Exit(direction="north", to_zone="guild_hall", at=(16, 0)), Exit(direction="east", to_zone="riverside", at=(31, 12)), Exit(direction="south", to_zone="slum_warren", at=(16, 23)), ], spawns = [ Spawn(entity_id="merchant_variel", at=(10, 12)), Spawn(entity_id="guard_post", at=(28, 4)), ], )
Zone IDs are strings. They can be anything your world requires. The engine does not impose a naming convention. Exit positions define where the player arrives in the connected zone. Spawns define where entities appear when the zone loads.
The WorldPlay runtime manages the active world during a session:
loading zones on demand, tracking entity positions, handling transitions, and
maintaining spatial memory (which zones the player has visited, which entities
they have encountered, which positions carry scarring from prior events).
from ambroflow.world import WorldPlay world = WorldPlay(zone_registry=my_zones) world.enter_zone("market_square", at=(16, 23)) nearby = world.entities_within_radius(center=player.pos, radius=4) world.exit_zone(direction="north")
These systems operate identically regardless of the lore you apply to them. They have no opinions about what skills mean, what sanity represents, or what alchemy produces. Those meanings are yours to define.
Skills are named float values from 0.0 to 5.0. They have no predefined list. You define the skill names your game uses; the engine provides rank storage, check resolution, and experience accumulation.
# Define skills at game init player.skills.define([ "alchemy", "navigation", "persuasion", "meditation", "survival" ]) # Train a skill player.skills.train("alchemy", amount=0.2) # Skill check (returns True/False + margin) result = engine.encounter.skill_check( skill = "alchemy", difficulty = 2.5, modifiers = {"reagent_quality": +0.5}, )
VITRIOL is a 7-axis affinity system. The axes are named after the alchemical acronym but carry no mandatory meaning — they are slots. You assign what each axis means in your lore. The engine tracks affinities, applies them as modifiers to relevant skill checks, and makes them available for narrative queries.
# Assign axis meanings at game init (all are yours to define) engine.vitriol.configure({ "V": "Visita", # your meaning here "I": "Interiora", "T": "Terrae", "R": "Rectificando", "I2": "Invenies", "O": "Occultum", "L": "Lapidem", }) # Query player affinity dominant = player.vitriol.dominant() score = player.vitriol.score("V")
Ambroflow tracks sanity on four independently configured dimensions. The dimension names, their ranges, and what counts as consonance or dissonance between them are yours to define. The engine tracks values, applies events that shift them, and calculates an aggregate coherence score used by other systems.
# Configure dimensions at game init engine.sanity.configure(dimensions=[ SanityDim(id="alchemical", label="Alchemical", range=(0,100)), SanityDim(id="narrative", label="Narrative", range=(0,100)), SanityDim(id="terrestrial", label="Terrestrial", range=(0,100)), SanityDim(id="cosmic", label="Cosmic", range=(0,100)), ]) # Apply an event engine.sanity.shift("alchemical", delta=-8, reason="reagent_failure") # Query coherence (variance across dimensions) coherence = engine.sanity.coherence() # 0.0 = maximum dissonance
Alchemy in Ambroflow is spatial, not key-triggered. The player arranges reagents in a physical space; the engine evaluates proximity, combination rules, and environmental conditions to determine the outcome. You define the reagents, the combination rules, and the output schema. The engine handles spatial resolution.
# Define a combination rule engine.alchemy.register_rule(AlchemyRule( reagents = {"sulfur", "mercury", "salt"}, conditions = {"heat": True}, output = "philosophers_stone", skill_check = ("alchemy", 4.0), )) # Resolve a spatial arrangement result = engine.alchemy.resolve( arrangement = player.workbench.current_layout(), environment = zone.conditions, player = player, )
Ambroflow tracks four distinct memory layers. Each operates on a different time horizon and serves different narrative purposes. You define what events write to each layer; the engine stores, queries, and makes them available to dialogue and encounter systems.
| Layer | Scope | Substrate | Use |
|---|---|---|---|
| Narrative | Player + named NPCs | Event log | What happened. Dialogue callbacks, journal entries. |
| Relational | Player + NPCs + locations | TileTracer | Object permanence, spatial scarring. What changed and where. |
| Akashic | Player + specific entities | Resonance tokens | Cross-timeline tracking. Death, transformation, choice across sessions. |
| Personal | Every NPC independently | Per-entity runtime | What this NPC knows about the player. Dialogue lens. |
# Write a narrative event engine.memory.narrative.record( event = "player_refused_merchant_offer", actor = "player", target = "merchant_variel", context = {"offer_value": 400, "location": "market_square"}, ) # Query what an NPC knows knowledge = engine.memory.personal.for_entity("merchant_variel") refused = knowledge.has_event("player_refused_merchant_offer") # Write relational scarring to a location engine.memory.relational.scar( zone = "market_square", at = (10, 12), label = "blood_spilled", radius = 2, )
TileTracer is the substrate for the Relational memory layer. It tracks which tiles have been visited, modified, or scarred, and makes that information available for zone rendering and entity dialogue. It is also the attestation substrate for any mechanic you build around witnessed events.
# Check if a tile has been witnessed witnessed = engine.memory.relational.tile_witnessed( zone = "market_square", at = (10, 12), ) # Get full scar history for a zone scars = engine.memory.relational.zone_scars("market_square")
The Resonance Function is Ambroflow's mechanism for encoding player state as a mathematical fingerprint. It is multiversal: it operates at the level of mathematics, not lore. The Ko's Labyrinth series uses it as the substrate for the Breath of Ko. Your game can call it whatever your world requires.
token, julia_params, delta = engine.resonance.capture(state={
"alchemical_sanity": 72.4,
"primary_skill": 3.1,
"quests_completed": 14,
"dominant_vitriol": "V",
"last_choice": "refused_contract",
"time_in_world_days": 38,
})
The state parameter is a free-form dict. There
are no required keys. You pass whatever your game tracks. The engine derives
a deterministic mapping from the dict's content to a complex number c,
computes the Julia set for that c, and returns three values:
| Return value | Type | Description |
|---|---|---|
token |
str |
A hex string uniquely identifying this state. Storable, comparable, transmissible. |
julia_params |
ComplexPoint |
The c value used to generate the Julia set. Use this to render the fingerprint visually if your game surfaces it. |
delta |
ResonanceDelta |
Distance and angular shift from the previous token. This is what you build mechanics on. |
The ResonanceDelta carries three values:
delta.distance # float: magnitude of change (0.0 = identical state) delta.angle # float: direction of change in parameter space delta.is_first # bool: True if no prior token exists for this player
What you do with the delta is entirely your design decision. Gate progression on minimum distance (require genuine change before a threshold is crossable). Score authenticity. Detect stagnation. Log the arc of transformation as a time series. The engine makes no judgment about what constitutes meaningful change — that judgment belongs to your lore.
Call resonance.capture() at any moment you designate as
meaningful in your game. Common patterns:
# On sleep / rest engine.on_rest(lambda: engine.resonance.capture(state=current_state())) # On quest completion engine.quests.on_complete(lambda q: engine.resonance.capture( state={**current_state(), "completed_quest": q.id} )) # On explicit practice mechanic (meditation, ritual, etc.) def player_meditates(): token, params, delta = engine.resonance.capture( state=current_state() ) if delta.distance > 0.3: unlock_next_practice_tier(player)
If your game surfaces the fingerprint visually, use
julia_params with the engine's built-in Julia renderer:
image = engine.resonance.render(
julia_params = julia_params,
width = 512,
height = 512,
iterations = 256,
colormap = "your_palette", # or None for greyscale
)
The rendering is optional. The fingerprint is mathematically meaningful whether or not it is ever displayed. Some games will surface it as an artifact the player carries. Others will use it invisibly as a gating mechanism. Both uses are correct.
Ambroflow's dialogue renderer handles branching conversation trees, NPC memory integration, and conditional branch evaluation. Dialogue scripts are written in a structured format; the engine resolves conditions against live game state at render time.
# Dialogue script format { "npc": "merchant_variel", "lines": [ { "text": "You again. Still thinking about my offer?", "condition": {"memory.narrative.has": "player_refused_merchant_offer"} }, { "text": "First time in the market?", "condition": {"memory.narrative.lacks": "player_visited_market"} } ], "choices": [ { "label": "Ask about the northern road.", "requires": {"skill.navigation": {"gte": 2.0}}, "triggers": ["flag.asked_northern_road"] } ] }
Encounters are discrete resolution events: skill checks, contested rolls, environmental hazards, social negotiations. The encounter resolver accepts a definition and returns a structured result including outcome, margin, and any state changes to apply.
result = engine.encounter.resolve(EncounterDef(
type = "skill_check",
skill = "persuasion",
difficulty = 3.0,
stakes = {
"success": ["flag.merchant_trusts_player"],
"failure": ["flag.merchant_wary_player", "sanity.narrative:-5"],
},
))
The Orrery is Ambroflow's cross-game state propagation system. It records significant player events in a multiverse stack and makes them available to future games in the same series. It is entirely optional. If your game is standalone, skip this section.
If you are building a series of connected games, the Orrery lets you propagate specific flags, resonance tokens, and named outcomes from one game to another without requiring the player to replay or the developer to hard-code dependencies.
# Record a significant event to the Orrery engine.orrery.record( game_id = "your_game_slug", event = "player_refused_throne", token = current_resonance_token, metadata = {"consequence_tier": "major"}, ) # Query from a later game prior = engine.orrery.query( game_id = "your_game_slug", event = "player_refused_throne", ) if prior.found: modify_world_for_prior_refusal()
The Ko's Labyrinth series (31 games) is one game architecture built on Ambroflow. It is not the engine. Everything in the preceding sections operates without any KLGS lore, characters, or cosmological structure.
The following KLGS-specific features exist in the engine repository as reference implementations. Use them as patterns, replace them entirely, or ignore them:
| KLGS Feature | Engine Equivalent | Your Path |
|---|---|---|
| Breath of Ko | Resonance Function (§6) | Call engine.resonance.capture() with your state. Name it what your world calls it. |
| Wunashakoun trigger | Any trigger point | Sleep, ritual, meditation, choice, death — any moment you designate. |
| Void Wraith entities | Antagonist entity template | The entity class pattern works for any persistent antagonist with memory of the player. |
| Ko dialogue renderer | Dialogue system (§7) | The renderer is lore-neutral. The Ko portrait is a KLGS asset. Replace it with yours. |
| Shygazun byte table | Not part of the engine | The language is external to Ambroflow. You do not need it to use the engine. |
| 4-fold sanity dimensions | Sanity system (§4) | Define your own dimension names and ranges. The engine does not require the four KLGS axes. |
The smallest Ambroflow game requires a world definition, a player definition, and a game config. Everything else is additive.
from ambroflow.engine import GameEngine, GameConfig from ambroflow.world import WorldDefinition from ambroflow.player import PlayerDefinition world = WorldDefinition(zones=[your_zones], start_zone="your_start") player = PlayerDefinition(skills=["your_skills"], start_pos=(8, 8)) config = GameConfig(title="Your Game", save_path="./saves/") engine = GameEngine(world, player, config) engine.start() while engine.running: state = engine.render() action = your_input_handler(state) engine.tick(action)
Roko is the Guild's structural assessment AI. It evaluates practitioner output through two Hopfield passes — Giann (ground truth attractor) and Keshi (dream projection) — and returns a gate-level reading that determines whether a body of work is eligible for Quack minting. When you integrate Roko into an Ambroflow game, you are connecting your game's Resonance output directly to the living Quack economy.
An Ambroflow game with Roko integration can submit a practitioner's Resonance delta to the Guild's assessment endpoint and receive:
| Field | Type | Description |
|---|---|---|
gate_level | str | Tiwu through ZoWu. Structural depth of the contribution. |
tongue_activations | list | Which Shygazun tongues are activated by the practitioner's symbol output. |
quack_eligible | bool | Whether the Akinen total meets the current minting floor. |
quack_akinen_total | int | Total Akinen count across all activated tongues. |
r0_signal | float | Raw structural coherence score from the R₀ pass. |
Roko integration is available exclusively to Guildbound developers. This is not a licensing formality. It is a structural requirement with a specific economic rationale.
The Quack is peri-fungible: its value as an economic instrument derives from the fact that every minted Quack represents attested Wunashakoun practice and a genuine extension of the Shygazun byte table. The Akinen floor, the tongue activation logic, and the gate-level system exist to maintain the integrity of that attestation. Roko's assessment output feeds directly into the minting pipeline.
An ungated Roko integration would allow developers to submit arbitrary Resonance tokens without going through the Guild's accountability structure. At sufficient volume this destabilizes the Quack market by diluting the semantic integrity of the byte table — the substrate on which the entire peri-fungibility argument rests. The Guildbound requirement is the mechanism that prevents that. It is the attestation requirement made structural.
Guild membership is open to studios and independent developers building on Ambroflow. The process:
| Step | What happens |
|---|---|
| 1. Register | Create a studio account at quantumquackery.org/guild. Describe your project and intended use of Roko. |
| 2. Review | The Guild steward reviews your application. This is a structural review, not a content gatekeeping exercise. We are checking that your integration architecture is sound and that you understand what the attestation requirement means. |
| 3. Credentials | You receive API credentials scoped to your studio account and a Guild listing entry. |
| 4. Integration | Wire engine.resonance output to the Roko endpoint. The Guild provides a reference integration for Ambroflow developers. |
For Roko integration enquiries, Guild membership, or questions about the Guildbound requirement:
quantumquackerydivinearts@gmail.com
Include your project name, the platform you are building for, and a brief description of how you intend to use the Resonance Function in your game. Applications without this context will not be reviewed.
Ambroflow is an open engine. Quantum Quackery Divine Arts — Studio 42/6. The Ko's Labyrinth series is a separate commercial work built on this substrate. The engine is the substrate. The games are the meaning.