NODE REFERENCE
Node reference
The node catalog, grouped by category. Pins are typed; the white exec pin carries control flow.
EVENT
1 NODESEntry points. Execution starts here when the event fires.
On Tick
event.onTickFires once every simulation tick. The primary entry point — execution starts here.
PINS
- ▶ out▹— Exec — fires every tick; wire it to the first node of your logic.
WHY
Core and actor logic begin with On Tick: it is the heartbeat that re-runs your graph continuously while the colony is live, even while you are offline.
EXAMPLE
On Tick → Scan(IRON) → Branch(found?) → Move To → Mine
SENSE
20 NODESRead the world — find targets, stats, paths, and prices.
Scan Entity
sense.scanSearches the area around the entity for a thing matching a filter — as a circle, a directional cone, or the whole chunk. Enable closest to pay extra load for the nearest match.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out — continues after the scan.
- ◦ target▹— A matching entity/tile (object), or empty if nothing matched. With closest enabled, this is the nearest match.
- ◦ found?▹— True when something matched — feed it into a Branch.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- filterdefault: IRON— What to look for, e.g. IRON, ICE, ENEMY, ALLY (same-colony).
- targetTypesdefault: drones,missiles,structures— For ENEMY scans, restrict matches to hostile drones, missiles, structures, or any combination.
- shapedefault: circle— circle (radius), cone (radius + angle + direction), or chunk (the whole 50×50).
- radiusdefault: 6— How many tiles out to search — wire a number in to vary it.
- coneAngledefault: 90— Cone width in degrees (cone shape only). Narrower = fewer cells.
- coneDirdefault: N— Cone direction (cone shape only): N, E, S, W.
- closestdefault: false— When enabled, searches all matches and returns the nearest one. Adds +2 load.
WHY
The main way an actor perceives the world — find ore to mine, an enemy to attack, or a depot to haul to. Pair its found? output with a Branch. A cone scans fewer cells in one direction; the whole chunk sees everything.
EXAMPLE
Scan(filter IRON, shape cone, radius 8, angle 60, dir E) → found? → Branch
Scan Entities
sense.scanEntitiesLike Scan Entity, but returns every matching target inside the scanned shape as a list, plus the count.
PINS
- ▶ in▸
- ▶ out▹
- ◦ list▹— Matching target objects with x/y/kind and entity fields when available — wire into For Each or Filter.
- ◦ count▹— How many matched (number) — feed into Compare.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- filterdefault: IRON— What to look for, same as Scan Entity: resources, ENEMY, ALLY (same-colony), or STATION.
- shapedefault: circle— circle (radius), cone (radius + angle + direction), or the whole chunk.
- radiusdefault: 6— How many tiles out to scan.
- coneAngledefault: 90— Cone width in degrees (cone shape only).
- coneDirdefault: N— Cone direction (cone shape only): N, E, S, W.
- closestdefault: false— When enabled, returns the full list sorted nearest-first. Adds +2 load.
WHY
Spatial logic over multiple targets: every ore tile in a cone, every ally in range, or every station target in a chunk. Wire list into For Each or Filter; branch on count.
EXAMPLE
Scan Entities(filter IRON, shape cone) → For Each ─body→ Move To(item)
Get Position
sense.getPositionReads an actor's current chunk-aware position.
PINS
- ▶ in▸
- ▶ out▹
- ◦ position▹— Full chunk position object: roomX, roomY, x, y.
- ◦ chunk▹— Chunk object for the actor's current chunk.
- ◦ chunk x▹— Current chunk X.
- ◦ chunk y▹— Current chunk Y.
- ◦ x▹— Tile X inside the chunk.
- ◦ y▹— Tile Y inside the chunk.
WHY
Use it before routing, filtering, or saving a scout's current chunk and tile into memory.
EXAMPLE
Get Position → Get Chunk Info(chunk)
Get Chunk Info
sense.getRoomInfoReturns known state for a chunk: visibility, scout intel, ownership, blockage, hostility, heat, notes, and distance.
PINS
- ▶ in▸
- ▶ out▹
- ◦ chunk▸— Optional chunk or position object. If unwired, chunk x/y params are used.
- ◦ info▹— Chunk info object with status, threat, resources, scout metadata and booleans.
- ◦ known?▹
- ◦ visible?▹
- ◦ scouted?▹
- ◦ occupied?▹
- ◦ blocked?▹
- ◦ self?▹
- ◦ hostile?▹
- ◦ manual note▹
- ◦ auto note▹
- ◦ last seen▹
- ◦ heat▹
- ◦ distance▹— Chunk-route distance from the actor's current chunk.
WHY
Branch before scouting or attacking: avoid blocked chunks, refresh stale chunks, pick hostile chunks, or inspect saved notes and heat.
EXAMPLE
Make Position(chunk 4,2) → Get Chunk Info → Branch(blocked?)
Scan Chunks
sense.scanRoomsLists known chunks around a source chunk with filters for visibility, scouting state, threat, blockage, and resource heat.
PINS
- ▶ in▸
- ▶ out▹
- ◦ from▸— Optional chunk or position object. Unwired means the actor's current chunk.
- ◦ first▹
- ◦ list▹— Matching chunk objects for For Each or Filter.
- ◦ count▹— How many chunks matched.
PARAMS
- radiusdefault: 1— Chunk distance around from.
- filterdefault: any— any, unvisited/unscouted, scouted, stale, visible, notVisible, empty, occupied, hostile, self, blocked, resource id/heat, or threat.
- staleTicksdefault: 100— A scouted chunk is stale when lastSeenTick is at least this many ticks old.
WHY
Scouting and target selection: find unscouted or stale neighbors, hidden chunks, hostile chunks, empty expansion candidates, or chunks with a desired resource heat signature.
EXAMPLE
Scan Chunks(radius 1, filter unvisited) → For Each → Find Chunk Route
Get Chunk Intel
sense.getRoomIntelReads persisted scout intel for a chunk without requiring current visibility.
PINS
- ▶ in▸
- ▶ out▹
- ◦ chunk▸— Optional chunk or position object. If unwired, chunk x/y params are used.
- ◦ intel▹— Chunk object with visible/scouted, manualNote, autoNote, lastSeenTick, heat and bestResource.
- ◦ scouted?▹
- ◦ visible?▹
- ◦ best resource▹
- ◦ heat score▹— Score for the chunk's best known resource.
- ◦ manual note▹
- ◦ auto note▹
- ◦ last seen▹
WHY
Use it when a route can address a fogged chunk but live chunk details are hidden: branch on scouted/stale notes, pick the best known resource, or log manual scout notes.
EXAMPLE
Scan Chunks(filter stale) → Get Chunk Intel → Resource Heat
Resource Heat
sense.resourceHeatReturns the known heat score for one resource in a chunk, 0..1.
PINS
- ▶ in▸
- ▶ out▹
- ◦ chunk▸
- ◦ score▹
PARAMS
- resourcedefault: IRON— Raw resource to score from the chunk's persisted heat map.
WHY
Rank scouting or mining targets without exposing live deposits for chunks that are currently fogged.
EXAMPLE
Scan Chunks(filter scouted) → Resource Heat(ICE) → Compare(> 0.6)
Get Chunk Exit
sense.getRoomExitReturns the neighboring chunk and the tile to stand on to exit in a cardinal direction.
PINS
- ▶ in▸
- ▶ out▹
- ◦ chunk▸— Optional source chunk or position object.
- ◦ next chunk▹— Neighbor chunk in the selected direction.
- ◦ exit▹— Tile position in the source chunk that leads to next chunk.
- ◦ found?▹— False when the neighboring chunk is unknown or blocked.
PARAMS
- directiondefault: N
WHY
Build low-level navigation graphs: move a scout to an exit, cross chunks, then continue toward the next target.
EXAMPLE
Get Chunk Exit(E) → Move To(exit)
Find Chunk Route
sense.findRoomRouteComputes a route across chunks and returns the next chunk plus the exit tile to head toward.
PINS
- ▶ in▸
- ▶ out▹
- ◦ from▸— Optional source chunk or position. Unwired means actor's current chunk.
- ◦ to▸— Target chunk or position. If unwired, to chunk x/y params are used.
- ◦ route▹— Chunk list from source to target.
- ◦ next chunk▹— The next chunk along the route.
- ◦ next exit▹— Exit tile in the current chunk.
- ◦ distance▹
- ◦ found?▹— True when a route exists.
PARAMS
- avoidBlockeddefault: true
- avoidHostiledefault: false
- avoidHighThreatdefault: false
WHY
The primitive for exploration and raids: graphs can choose a target chunk, route around blocked/hostile chunks, then Move To the next exit.
EXAMPLE
Make Position(chunk 6,3) → Find Chunk Route(to) → Move To(next exit)
Get Stat
sense.getStatReads a single live stat. Drone actors get drone stats; Core gets only Core runtime stats.
PINS
- ▶ in▸
- ▶ out▹
- ◦ of▸— Optional entity to read (from For Each / Self). Unwired ⇒ the running drone.
- ◦ value▹— The numeric stat value — feed it into Compare or Math.
PARAMS
- statdefault: charge— Drone: charge, hp, maxhp, weight, speed, cargo, cargocap, iswaiting, modules. Core: charge, tick, or busy.
WHY
Lets logic react to state: drones can recharge when charge is low or deposit when cargo is full; the Core can react to station charge or tick timing. Use Read Storage for stored resources. Wire an entity (from Self or a For Each item) into `of` to read that entity instead of yourself.
EXAMPLE
Get Stat(charge) → Compare(< 250) → Branch ─true→ Recharge
Is Busy?
sense.isBusyChecks whether Core or a building actor has a busy channel.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ actor▸— Optional Core/Processor entity to inspect. Unwired means the running actor.
- ◦ busy?▹— True when the selected channel is busy, or when any/all has no free channels.
- ◦ channels▹— Total channels on this actor.
- ◦ busy ch▹— How many channels were busy at the start of this tick.
- ◦ free ch▹— How many channels were free at the start of this tick.
PARAMS
- channeldefault: any— any = first free channel/no free channels; 1 or 2 checks a specific channel.
WHY
Use it before Construct Drone, Process Resource, Combine Resources, or Processor jobs. With channel=any, busy? means there are no free channels; with channel=1/2, it checks that channel exactly.
EXAMPLE
Get Entity(processor) → Is Busy?(actor, channel any) → Branch ─false→ Process Resource(actor)
Is Area Free?
sense.areaFreeChecks whether a blueprint footprint is free at map coordinates.
PINS
- ▶ in▸
- ▶ out▹
- ◦ occupied?▹— True when any footprint cell is blocked by terrain, deposit, unit, Core, building, or plan.
- ◦ free?▹— True when the full footprint can be placed.
PARAMS
- blueprintdefault: processor◦ wirable
- xdefault: 0◦ wirable
- ydefault: 0◦ wirable
WHY
Use it before Place Build Plan when scanning candidate coordinates. It only reports occupied/free, not what blocks the tile.
EXAMPLE
Is Area Free?(processor, x, y) → Branch ─true→ Place Build Plan
Get Build Need
sense.buildNeedReads the next missing resource for a build plan.
PINS
- ▶ in▸
- ▶ out▹
- ◦ plan▸— Build plan entity. If unwired, the runtime uses the first visible plan.
- ◦ good▹— Next missing resource id, e.g. SPACE_ALLOY.
- ◦ qty▹— Quantity still missing for that resource.
- ◦ funded?▹— True when all required inputs are already delivered.
WHY
Automates construction logistics: query a plan, withdraw the next needed good and quantity, then send a drone to Build.
EXAMPLE
Get Entity(plan) → Get Build Need → Withdraw Resource(good, qty) → Build(plan)
Get Entity
sense.getEntityReturns the first visible entity matching a kind.
PINS
- ▶ in▸
- ▶ out▹
- ◦ entity▹— The first matching entity, or empty if none exists.
PARAMS
- kinddefault: any
WHY
Use it to fetch a Processor actor, a build plan target, the Core, or a drone without doing an area scan.
EXAMPLE
Get Entity(processor) → Process Resource(actor)
Get Entities
sense.getEntitiesReturns all visible entities matching a kind.
PINS
- ▶ in▸
- ▶ out▹
- ◦ list▹— Matching entities as a list.
- ◦ count▹— How many matched.
PARAMS
- kinddefault: any
WHY
Use it to iterate all build plans, all Processors, or all drones in colony-wide automation.
EXAMPLE
Get Entities(plan) → For Each → Build(item)
Find Path
sense.findPathComputes an A* route from the entity to a target position or entity.
PINS
- ▶ in▸
- ▶ out▹
- ◦ to▸— Destination (object) to route toward.
- ◦ path▹— The computed route (object).
WHY
Use it when you need the path itself — distance, reachability, or feeding a precise route to Move To across obstacles.
EXAMPLE
Scan(target) → Find Path(to target) → Move To(path)
Read Storage
sense.readStorageReads how much of a given good sits in a storage depot or the core.
PINS
- ▶ in▸
- ▶ out▹
- ◦ qty▹— The stored quantity of the chosen good (number).
PARAMS
- gooddefault: IRON— Which good to count: IRON, SPACE_ALLOY, FUEL, …
WHY
Drives stock-based decisions — only haul when storage is low, only sell once a surplus has built up.
EXAMPLE
Read Storage(SPACE_ALLOY) → Compare(> 50) → Branch ─true→ Place Sell Order
Count Units
sense.countUnitsCounts the colony's active drones.
PINS
- ▶ in▸
- ▶ out▹
- ◦ count▹— How many drones match (number).
WHY
Population-aware logic: construct more drones only when there are fewer than N, balance the fleet, or stop building once the fleet is saturated. Wire the count into a Compare.
EXAMPLE
Count Units → Compare(< 5) → Branch ─true→ Construct Drone
Can Do?
sense.canDoProbes whether the selected actor can do something right now and outputs a boolean. Build a small graph of actions inside it (the Build probe graph button) — it dry-runs them with no side effects (no charge/resources change, nothing is committed) and returns true only if every action is feasible with current energy.
PINS
- ▶ in▸
- ▶ out▹
- ◦ target▸— Optional object the probe action should test against, e.g. a scanned resource tile. Wire actor to run the probe as another entity; unwired actor means Self.
- ◦ can?▹— True when every action in the probe graph is feasible this tick (bool).
PARAMS
- actiondefault: mine— Fallback action check used when no probe graph is attached. Select stealth to test Core invisibility readiness.
WHY
Guard before you act: only mine when a laser and free cargo capacity exist, only recharge when the Core is adjacent — without wasting a tick. Wire a scanned target into `target`; inside the probe graph that object is available from the function input. Probing is cheap (low load) and never changes the world.
EXAMPLE
Scan(target) → Can Do?(target; probe: Mine target) → Branch ─true→ Mine(target)
Get Market Price
sense.marketPriceReads the current exchange reference price of a good through a built Market actor.
PINS
- ▶ in▸
- ▶ out▹
- ◦ actor▸— A built Market entity, usually from Get Entity(market). Without a Market actor, price is empty.
- ◦ price▹— The current market reference price of the chosen good (number).
PARAMS
- gooddefault: SPACE_ALLOY— Which good to price: SPACE_ALLOY, FUEL, DEUTERIUM, …
WHY
The sensor behind trading bots — wire Get Entity(market) into actor, then buy inputs when cheap or sell goods when the price spikes.
EXAMPLE
Get Entity(market) → Get Market Price(actor, SPACE_ALLOY) → Compare(> 8) → Branch ─true→ Place Sell Order(actor)
COLONY
4 NODESColony-wide helpers — fleet lists and shared colony state.
Get Drones
colony.getDronesReturns every drone currently owned by your colony.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ list▹— All colony drones as a list — wire into For Each or Filter.
- ◦ count▹— How many drones exist.
WHY
Use it for fleet-wide logic: count all drones, iterate over the fleet, or filter by live stats.
EXAMPLE
Get Drones → Filter(charge < 250) → For Each ─body→ Recharge
Get Resources
colony.getResourcesReturns the colony's current resource stock rows as a list.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ list▹— Resource rows as a list. Each item has good and qty fields.
- ◦ count▹— How many resource rows exist.
WHY
Use it for resource-aware logic: filter by good or quantity, count matching rows, or feed resource rows into reusable functions.
EXAMPLE
Get Resources → Filter(good = IRON) → count → Compare(> 0)
Drone Group
colony.groupFor each of your drones in this group, run the body behaviours. A blank group name = ALL drones; a named group also keeps itself at the chosen fleet size (auto-building the loadout).
PINS
- ▶ in▸— Exec in.
- ▶ body▹— Runs ONCE PER DRONE in the group — wire your behaviour chain (Harvest, Defend, …) here.
- ◦ drone▹— The current drone; body behaviours pick it up automatically (no wiring needed).
- ▶ next▹— Optional — continues once AFTER the group, to chain the next Drone Group or a colony directive.
PARAMS
- group— Group name (the drone Label). Blank = every drone. Wire the port to drive it from another node (e.g. String / Get Memory).
WHY
The heart of fleet authoring: drop a group, wire abstract behaviours (Harvest/Defend/…) into `body`, and the whole fleet just works. Use `next` only to add a second group or a colony directive.
EXAMPLE
On Tick → Drone Group(miners) ─body→ Harvest(IRON)
Storage
prod.storageReads one selected good from shared Core stock, or writes incoming resources back to stock.
PINS
- ◦ in▸
- ◦ any▹
PARAMS
- gooddefault: ICE
- bufferLimitsdefault: [object Object]
WHY
Set good directly on Storage for common production lines; keep Filter for advanced mixed-stream routing. Storage inputs can receive multiple resources.
EXAMPLE
Storage(ICE) -> Process(ICE_TO_WATER)
BEHAVIOR
10 NODESHigh-level intents like Harvest, Defend, Build — one node runs a whole routine per drone.
Harvest
behavior.harvestScan when a target is needed, cache the resource tile, mine it until full, then haul it home. Empty scans wait for the rescan interval; optional periodic refresh keeps targets fresh.
PINS
- ▶ in▸
- ▶ out▹
- ◦ actor▸
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- resourcedefault: IRON— Which resource to mine and haul.
- radiusdefault: 6— How far to look for a deposit.
- rescanTicksdefault: 10— Ticks to wait before scanning again after an empty scan, and the interval for periodic refresh.
- periodicRescandefault: false— Refresh the cached target every rescan interval even while the current target is still valid.
WHY
The everyday miner. Assign it to a group of laser+storage drones and they keep the resource flowing without any wiring.
Defend
behavior.defendScan for selected hostiles, cache the target, and fire in range. Focus sends free weapons to one target; split distributes missiles and lasers across targets.
PINS
- ▶ in▸
- ▶ out▹
- ◦ actor▸
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- radiusdefault: 12— Engagement range (minimum 12).
- targetTypesdefault: drones,missiles,structures— Which hostile categories to engage: drones/raiders, in-flight missiles, structures, or any combination.
- missileModedefault: focus— focus: all free weapons fire at the nearest target. split: distribute missile tubes and laser modules across in-range targets.
- autoReloaddefault: false— When enabled, the drone reloads its onboard missile reserve from Core storage before defending.
- reloadGooddefault: MISSILE— Missile resource type used by automatic reload.
- reloadQtydefault: 3— Target onboard count maintained by automatic reload.
- rescanTicksdefault: 3— Ticks between enemy scans after an empty scan, and the interval for periodic target refresh.
- periodicRescandefault: true— Refresh the cached target every rescan interval while a target remains valid.
WHY
Standing guard. Put it at the top of a group's list so threats are answered before anything else.
Recharge
behavior.rechargeReturn to the Station and recharge by up to the configured amount per tick when charge is below a threshold.
PINS
- ▶ in▸
- ▶ out▹
- ◦ actor▸
PARAMS
- amountdefault: 100◦ wirable— Maximum charge to draw per tick while recharging.
- thresholddefault: 250◦ wirable— Start returning to the Core when the drone's charge is at or below this value.
- untilFulldefault: false— After a recharge starts, keep it active until the drone reaches full charge.
WHY
Drop it above your work behaviors — a drone only recharges when it actually needs to, then falls back to its job.
EXAMPLE
Recharge(amount 100, below 250, until full) → Harvest
Patrol
behavior.patrolPatrol a per-drone ring of waypoints around the Core, a building, a marker, or the chunk center.
PINS
- ▶ in▸
- ▶ out▹
- ◦ actor▸
PARAMS
- arounddefault: core— Anchor for the patrol ring: Core, a selected building type, a named marker, or the current chunk center.
- radiusdefault: 5— Distance of the patrol ring from the selected anchor.
- buildingdefault: processor— Building type to patrol around. If several match, the nearest matching building is used.
- markerName— Marker name to patrol around. The drone waits if no visible marker with this name exists.
WHY
Keep eyes on the perimeter - pair with Defend so patrollers engage anything they run into.
Scout
behavior.scoutMove toward the nearest unscouted or stale chunk and refresh its intel.
PINS
- ▶ in▸
- ▶ out▹
- ◦ actor▸
PARAMS
- radiusdefault: 4— Chunk-route radius around the scout.
- staleTicksdefault: 100— A scouted chunk becomes a refresh target after this many ticks.
- rescanTicksdefault: 100— Ticks to wait before choosing another chunk after no scout target is found.
- periodicRescandefault: false— Recompute the cached destination every rescan interval while it remains valid.
- avoidHostiledefault: true
- avoidHighThreatdefault: true
WHY
Assign it to fast drones to push back fog of war without exposing hidden chunks' live details.
Survey Resource
behavior.surveyResourceMove toward the best known/scouted chunk for the selected resource heat.
PINS
- ▶ in▸
- ▶ out▹
- ◦ actor▸
PARAMS
- resourcedefault: IRON— Raw resource heat to follow.
- minHeatdefault: 0.25— Ignore chunks below this heat score.
- radiusdefault: 8
- staleTicksdefault: 250— Stale matching chunks are preferred for refresh.
- rescanTicksdefault: 250— Ticks to wait before choosing another survey chunk after no match is found.
- periodicRescandefault: false— Recompute the cached destination every rescan interval while it remains valid.
- avoidHostiledefault: true
- avoidHighThreatdefault: true
WHY
Use it to send survey drones toward promising resource signatures and refresh stale high-value chunks.
Build
behavior.buildCarry a build plan's required inputs from the Core and construct it on-site.
PINS
- ▶ in▸
- ▶ out▹
- ◦ actor▸
PARAMS
- blueprint— Restrict to plans of this blueprint (blank = any plan).
- radiusdefault: 8— How far to look for a plan.
- rescanTicksdefault: 10— Ticks to wait before looking again after no matching plan is found.
- periodicRescandefault: false— Recompute the cached plan every rescan interval while it remains valid.
WHY
Hands-free construction: place a plan, assign a builder group, and the materials get delivered until it's done.
Repair
behavior.repairHeal the Core (first) or nearest same-colony ally when HP is below the configured percent. Needs a laser and spends 1 IRON per repair.
PINS
- ▶ in▸
- ▶ out▹
- ◦ actor▸
PARAMS
- radiusdefault: 12— How far to look for a damaged same-colony ally (Core is always prioritized).
- thresholddefault: 90◦ wirable— Start repairing when the target's HP percent is at or below this value.
- untilFulldefault: false— After a repair starts, keep it active until the target reaches full HP.
- rescanTicksdefault: 10— Ticks to wait before looking again after no repair target is found.
- periodicRescandefault: false— Recompute the cached repair target every rescan interval while it remains valid.
WHY
Keep a medic in the rotation — pair with 'drop cargo first' so a miner unloads its ore before patching the base.
EXAMPLE
Repair(below 90%, until full) → Harvest
Self-Destruct
behavior.selfdestructDestroy the drone immediately. Unconditional — every drone that reaches this node is removed this tick.
PINS
- ▶ in▸
- ▶ out▹
- ◦ actor▸
WHY
Retire or sacrifice drones on command. Gate it behind a trigger (e.g. When Threat) so it only fires when you mean it, or drones self-destruct on sight.
Maintain Fleet
behavior.spawnKeep a drone group at a target size — spawns drones labeled with the group until it's full.
PINS
- ▶ in▸
- ▶ out▹
PARAMS
- group— Group name (the drone Label) to maintain. Required — blank does nothing.
- countdefault: 0— Keep this many drones in the group, auto-building them (0 = off).
- modulesdefault: engine,laser,storage— Loadout for auto-built drones.
WHY
How drones join a named group: the colony auto-builds them with your chosen loadout, one at a time. Drone Group folds this in — reach for the standalone node only when spawning is decoupled from a group's body.
TRIGGER
11 NODESConditions that gate a behavior — threat, stock level, cargo, cadence.
Stock Gate
production.stockGateBranches production logic by stored resources.
PINS
- ▶ in▸
- ▶ true▹
- ▶ false▹
PARAMS
- requiresdefault: [object Object]
- stockBelowdefault: [object Object]
WHY
Use it in the Production graph to gate a recipe by required inputs or by a target stock ceiling without editing a table policy.
EXAMPLE
On Tick → Stock Gate(requires HYDROGEN/OXYGEN, below FUEL) → Production Combine
Charge Gate
production.chargeGateBranches production logic by Station charge.
PINS
- ▶ in▸
- ▶ true▹
- ▶ false▹
PARAMS
- minChargedefault: 0
- maxChargedefault: 0
WHY
Use min/max charge thresholds before expensive resource or energy work.
EXAMPLE
On Tick → Charge Gate(max 3000) → Production Energy
Stage Gate
production.stageGateBranches production logic by Core stage.
PINS
- ▶ in▸
- ▶ true▹
- ▶ false▹
PARAMS
- minStagedefault: 1
WHY
Keep higher-tier recipes in the Production graph without firing them before unlock.
EXAMPLE
On Tick → Stage Gate(2) → Production Combine(advanced recipe)
When Threat
trigger.threatTrue when a hostile is within range of the drone.
PINS
- ◦ actor▸
- ◦ ok?▹
PARAMS
- radiusdefault: 12
WHY
Gate a Defend or Retreat behavior so it only kicks in when there's actually a threat.
When Stock Below
trigger.stockBelowTrue when the colony's stock of a resource is below a threshold.
PINS
- ◦ actor▸
- ◦ ok?▹
PARAMS
- gooddefault: IRON
- ndefault: 50
WHY
Run a Harvest only while you're short of a resource, then let drones do something else.
Stock Requirements
trigger.stockRequirementsTrue when every listed stock requirement is met.
PINS
- ◦ ok?▹
PARAMS
- requirementsdefault: [object Object]
WHY
Replaces Read Storage → Compare → AND chains for recipe, building, and upgrade guards.
Ready For Upgrade
trigger.readyForUpgradeTrue when the Core can start the next requested upgrade.
PINS
- ◦ ok?▹
PARAMS
- targetStagedefault: next
WHY
Covers stage reached, busy channel, and required stock checks with the same logic as Upgrade Core.
Has Building
trigger.hasBuildingTrue when the colony already has a completed building of this blueprint.
PINS
- ◦ ok?▹
PARAMS
- blueprintdefault: processor
WHY
Use it to gate production logic without querying entities and branching manually.
Core Stage
trigger.coreStageTrue when the Core stage comparison passes.
PINS
- ◦ ok?▹
PARAMS
- opdefault: >=
- minStagedefault: 2
WHY
Replaces Get Stat(coreStage) → Compare branches.
When Cargo Full
trigger.cargoFullTrue when the drone's cargo hold is full.
PINS
- ◦ actor▸
- ◦ ok?▹
WHY
Switch a drone from gathering to delivering once it can't carry any more.
Every N Ticks
trigger.everyTrue once every N ticks (colony-wide cadence).
PINS
- ◦ actor▸
- ◦ ok?▹
PARAMS
- ticksdefault: 10
WHY
Throttle a periodic behavior so it doesn't fire every single tick.
FLOW
12 NODESControl the order of execution — branch, loop, sequence, merge, wait.
Branch (IF)
flow.branchSplits execution two ways on a boolean condition: TRUE or FALSE.
PINS
- ▶ in▸— Exec in.
- ◦ cond▸— The boolean that picks the branch.
- ▶ TRUE▹— Exec — runs when cond is true.
- ▶ FALSE▹— Exec — runs when cond is false.
WHY
The core decision node. Wire a bool (from Scan's found?, a Compare, …) into cond and the colony picks a path every tick.
EXAMPLE
Compare(a < b) → Branch ─true→ Action A ─false→ Action B
Loop
flow.loopRepeats its body output N times or while a condition holds, then continues on done.
PINS
- ▶ in▸— Exec in.
- ▶ body▹— Exec — runs each iteration.
- ▶ done▹— Exec — runs once the loop finishes.
WHY
Do something several times in one tick — scan a few tiles, deposit a stack — without duplicating nodes. Bounded by the sim's depth cap.
EXAMPLE
Loop ─body→ Haul (repeat) ─done→ Charge
Sequence
flow.sequenceRuns each of its exec outputs in order, one after another.
PINS
- ▶ in▸— Exec in.
- ▶ 0▹— Exec — runs first.
- ▶ 1▹— Exec — runs second.
- ▶ 2▹— Exec — runs third.
WHY
Chain several actions deterministically from one trigger — mine, then haul, then recharge — without nesting branches.
EXAMPLE
Sequence ─0→ Mine ─1→ Haul ─2→ Charge
Merge
flow.mergeCombines two execution paths into one continuation. When either input fires, execution leaves through out.
PINS
- ▶ A▸— Exec in — first incoming path.
- ▶ B▸— Exec in — second incoming path.
- ▶ out▹— Exec out — continues from whichever input fired.
WHY
Use it after a Branch or two alternate control paths when both routes should continue through the same downstream logic instead of duplicating nodes.
EXAMPLE
Branch ─true→ A Branch ─false→ B A/B → Merge → shared action
Wait
flow.waitPauses execution — for a fixed number of ticks, or until a signal arrives on a channel. Pick the mode.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out — fires after the tick delay, or once the channel has a live signal.
PARAMS
- modedefault: ticks— ticks (wait a fixed number of ticks) or signal (hold until a named signal goes live).
- ticksdefault: 4◦ wirable— How many ticks to wait before continuing (ticks mode).
- channeldefault: rally— The signal channel to wait on (signal mode).
WHY
Two ways to pause execution. ticks throttles logic — space out trades, idle between patrols, avoid acting every tick. signal waits for a trigger: emit 'rally' from Core or another actor-scoped action and listeners proceed the tick it goes live.
EXAMPLE
Attack → Wait(ticks 4) → Attack · On Tick → Wait(signal rally) → Move To(target)
Gate
flow.gatePasses execution only when it is open; otherwise it blocks the flow. Open state is a checkbox, a wired bool, or a named signal.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out — fires only when the gate is open.
PARAMS
- modedefault: checkbox— checkbox/bool (the `open` value) or signal (open while a signal on `channel` is live).
- opendefault: true— Whether the gate is open (checkbox mode) — or wire a bool in.
- channel— Signal channel that opens the gate (signal mode).
WHY
A one-way valve or cooldown/lock — let an action through only while a condition unlocks the gate. Drive `open` with a checkbox, wire a bool into it, or open it on a signal channel.
EXAMPLE
On Tick → Gate(open ✓) → Construct Drone
For Each
flow.forEachRuns its body once for each item in a list, exposing the current element on `item`, then continues on `done`.
PINS
- ▶ in▸— Exec in.
- ◦ list▸— The list to iterate (from Scan Entities, Get Drones, Get Resources, or Filter).
- ▶ body▹— Exec — runs once per element.
- ◦ item▹— The current element. Target/entity items can feed Move To / Transfer Charge / Get Stat when entity fields are present; resource items can feed data/memory logic.
- ▶ done▹— Exec — runs once the loop finishes.
WHY
Act on a whole group: visit every scanned ore tile, recharge every low drone from Get Drones, or retarget each filtered item. Wire a list (from Scan Entities, Get Drones, or Filter) in, read the current one with `item` (into Move To, Get Stat, …). Bounded per tick so it can't hang.
EXAMPLE
Scan Entities(IRON) → For Each ─body→ Move To(item) ─done→ …
Filter
prod.filterSelects one resource from a mixed production stream.
PINS
- ▶ in▸
- ▶ out▹
- ◦ in▸
- ◦ good▹
PARAMS
- gooddefault: ICE
WHY
Use it after Split/Merge or legacy generic Storage streams when routing needs to select one good explicitly.
EXAMPLE
Merge -> Filter(ICE) -> Stock Limit
Split
prod.splitSplits incoming tokens across two outputs, optionally trying one output first.
PINS
- ▶ in▸
- ▶ out▹
- ◦ in▸
- ◦ A▹
- ◦ B▹
PARAMS
- adefault: 1
- bdefault: 1
- prioritydefault: none
WHY
Use priority routing to fill production/storage first and spill overflow to cleanup.
EXAMPLE
Process -> Split(priority A) -> Storage + Destroy
Merge
prod.mergeMerges two incoming token streams into one output, draining the priority input first.
PINS
- ▶ in▸
- ▶ out▹
- ◦ A▸
- ◦ B▸
- ◦ out▹
PARAMS
- prioritydefault: A
- bufferLimitsdefault: [object Object]
WHY
Use it to feed one constrained recipe from a primary source, then backfill from a secondary source only when the primary stream cannot fill the buffer.
EXAMPLE
Storage(IRON) + Storage(NICKEL) -> Merge(priority A) -> Stock Limit
Gate
prod.gateStateful hysteresis gate for a resource stream.
PINS
- ▶ in▸
- ▶ out▹
- ◦ in▸
- ◦ out▹
PARAMS
- metricdefault: charge
- gooddefault: FUEL
- nodeId
- pinId
- startBelowdefault: 3000
- stopAtOrAbovedefault: 5000
- bufferLimitsdefault: [object Object]
WHY
Use it when production should start below one threshold and continue until a higher stop threshold.
EXAMPLE
Storage(FUEL) -> Gate(charge <3000 until >=5000) -> Energy
Stock Limit
prod.stockLimitPasses tokens only while the target Core stock stays below the limit.
PINS
- ▶ in▸
- ▶ out▹
- ◦ in▸
- ◦ out▹
PARAMS
- gooddefault: WATER
- maxdefault: 100
WHY
Use it as a visible guard before process, combine, energy, or cleanup branches.
EXAMPLE
Storage(ICE) -> Stock Limit(WATER < 100) -> Process
ACTION
32 NODESDo something — move, mine, haul, build, attack, trade, construct.
Move To
action.moveToPaths the drone tile-by-tile toward a target position or entity.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out — continues once moving/arrived.
- ◦ target▸— Where to go (object): a tile, an entity, or a path.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
WHY
The basic locomotion action — get in range before you mine, haul, or fire. A step takes more ticks the heavier the drone is relative to its speed.
EXAMPLE
Scan(target) → Move To(target) → Mine(target)
Move to Marker
action.moveToMarkerPaths the drone toward a named map marker, or toward the nearest marker when any is enabled.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out — continues once moving or already at the selected marker.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- anydefault: false— When enabled, ignore the name field and choose the nearest marker.
- name— Marker name to follow. Empty or missing names wait until a matching marker appears.
WHY
Use markers as player-authored destinations. With any off, the drone waits until a marker with the typed name exists; with any on, it heads to the nearest visible marker.
EXAMPLE
Gate(open) → Move to Marker(name BASE)
Mine Resource
action.mineFires the mining laser at a deposit within 2 tiles, loading raw resource into cargo.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ target▸— The deposit/resource tile to mine (object).
- ▶ error▹— Exec - runs when this node fails with a runtime error.
WHY
How raw resources enter the economy — IRON, ICE, NICKEL, COBALT, CARBON and SILICON come from finite deposit tiles. The drone must be within range 2 and carry a mining laser, so this is usually preceded by Move To.
EXAMPLE
Move To(nickel) → Mine Resource → cargo fills with NICKEL
Haul / Deposit
action.haulCarries the drone's cargo back to the Station and deposits it — optionally a specific good and amount.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ to▸— Destination (object): the Station.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- gooddefault: ANY◦ wirable— Which good to deposit, or ANY to deposit whatever is carried.
- qtydefault: 0◦ wirable— How much to deposit; 0 = all of it.
WHY
Closes the extraction loop — mined resource is useless until hauled to the Station, where it banks into colony stock. Pick or wire what to deposit and how much (good ANY + qty 0 ⇒ deposit everything carried).
EXAMPLE
Mine Resource → Haul(good IRON, qty 0) → IRON banked at the Station
Withdraw Resource
action.withdrawMoves a resource from Core storage into the drone's cargo when the drone is adjacent to the Core.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out — continues once the withdrawal action is chosen.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- gooddefault: IRON◦ wirable— Which resource to withdraw from Core storage. Defaults to IRON.
- qtydefault: 1◦ wirable— How much to withdraw; limited by Core stock and free cargo space.
WHY
Lets drones carry repair material or job inputs out of the Station. The drone needs free storage capacity, and it cannot mix different goods in one cargo hold.
EXAMPLE
Read Storage(IRON) → Compare(> 0) → Branch ─true→ Withdraw Resource(IRON, 1)
Build
action.buildBuilds a placed construction plan with the drone's cargo.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ actor▸— Drone that should build. Unwired means the running drone.
- ◦ plan▸— Build plan entity to construct.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
WHY
Each drone running Build transfers up to 1 matching resource from cargo into the plan per tick. Once all inputs are delivered, the building materializes immediately.
EXAMPLE
Get Entity(plan) → Build(target plan)
Missile Strike
action.attackFires every free missile launcher at a hostile within 10 tiles for 50 damage each.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ enemy▸— The hostile to hit (object), e.g. from Scan(ENEMY).
- ▶ error▹— Exec - runs when this node fails with a runtime error.
WHY
Fleet defense — a drone carrying missile launchers clears hostiles found by Scan. Requires a missile module; out-of-range targets are approached first.
EXAMPLE
Scan(ENEMY) → Branch(found?) ─true→ Missile Strike(target)
Laser Strike
action.laserAttackFires combat lasers at a hostile within 2 tiles for 25 damage per laser module.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ actor▸— Drone that should fire. Unwired means the running drone.
- ◦ enemy▸— The hostile to hit (object), e.g. from Scan(ENEMY).
- ▶ error▹— Exec - runs when this node fails with a runtime error.
WHY
Short-range defense for laser drones. The drone closes to beam range first, then spends charge each tick to deal damage.
EXAMPLE
Scan(ENEMY) → Branch(found?) ─true→ Laser Strike(target)
Reload Missiles
action.reloadMissilesMoves to the Core and fills this drone's onboard missile reserve up to the selected count.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ actor▸— Drone that should reload. Unwired means the running drone.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- gooddefault: MISSILE— Missile resource to load into the drone reserve.
- qtydefault: 3— Target onboard count for that missile type.
WHY
Missile launchers spend onboard ammo. Reload lets a combat drone top up from Core storage without using cargo space.
EXAMPLE
On Tick → Reload Missiles(type MISSILE, target 3) → Defend
Place Sell Order
action.marketSellPlaces a Market limit sell order using stock reserved from Core storage.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ actor▸— A built Market entity, usually from Get Entity(market).
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- gooddefault: SPACE_ALLOY◦ wirable— Which stored good to sell.
- qtydefault: 5◦ wirable— Whole units to sell.
- pricedefault: 0◦ wirable— Limit price. Use 0 to sell at the current market reference price.
WHY
Automate surplus sales from the Core graph. Wire a built Market into actor; price 0 uses the current market reference price for the selected good.
EXAMPLE
Get Entity(market) → Get Market Price(actor) → Compare(> 8) → Branch ─true→ Place Sell Order(actor)
Place Buy Order
action.marketBuyPlaces a Market limit buy order using colony credits and depositing fills into Core storage.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ actor▸— A built Market entity, usually from Get Entity(market).
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- gooddefault: SPACE_ALLOY◦ wirable— Which good to buy.
- qtydefault: 5◦ wirable— Whole units to buy.
- pricedefault: 0◦ wirable— Limit price. Use 0 to buy at the current market reference price.
WHY
Automate resource acquisition from the Core graph. Wire a built Market into actor; price 0 uses the current market reference price for the selected good.
EXAMPLE
Get Entity(market) → Get Market Price(actor) → Compare(< 6) → Branch ─true→ Place Buy Order(actor)
Construct Drone
action.spawnStarts drone construction when the Core is idle. Station only.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- labeldefault: Miner◦ wirable— Free-form drone text: name, job label, callsign, or any characters the player wants.
- modulesdefault: engine,laser◦ wirable— The module loadout, built with the −count+ builder (engine, storage, laser, missile, armor, battery). More modules = more HP but heavier (slower), costlier, and slower to construct. Wire a Drone Modules node here to reuse modules across constructions.
WHY
How the Station grows its fleet — it assembles a drone from modules (each adds HP but weight, slowing it) and gives it a free-form label. Construction is paid from the Station's charge pool: the drone's full charge capacity plus 50 charge per module. It takes 1 tick per module and blocks other Core building jobs while active.
EXAMPLE
On Tick → Construct Drone(label: Miner, modules: engine,laser)
Place Build Plan
action.placePlanCreates a build plan at map coordinates. Plan creation costs nothing and is idempotent.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- blueprintdefault: processor◦ wirable— processor or market.
- xdefault: 0◦ wirable— Center X for the 3x3 footprint.
- ydefault: 0◦ wirable— Center Y for the 3x3 footprint.
WHY
Lets the Core graph automatically reserve a Processor or Market footprint after checking Is Area Free. Drones later deliver resources and run Build on the plan.
EXAMPLE
Is Area Free?(x,y) → Branch ─true→ Place Build Plan(market,x,y)
Ensure Building
core.ensureBuildingEnsures a building plan exists at a Core-relative offset, then always continues.
PINS
- ▶ in▸
- ▶ out▹
PARAMS
- blueprintdefault: processor
- offsetXdefault: 3
- offsetYdefault: 2
- minStagedefault: 2
WHY
Replaces Stage/Area/Existing-plan branches around Processor or Market placement. It no-ops when locked, occupied, already built, or already planned.
EXAMPLE
On Tick → Ensure Building(processor, +3,+2) → Production Queue
Activate Stealth
action.stealth.activateConsumes one stealth charge to protect the colony's Core, buildings and drones in this chunk for 1000 ticks.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
WHY
Use it from the Core graph when a raid starts or before HP decay would finish the Core. Repeated calls while stealth is active or cooling down do nothing and spend nothing.
EXAMPLE
Get Stat(stealthCharges) → Compare(> 0) → Branch ─true→ Activate Stealth
Upgrade Core
action.upgradeCoreAttempts the requested Core upgrade when stage, stock and busy checks pass, then continues.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
PARAMS
- targetStagedefault: next
WHY
Progression gate for Processor production and Market economy. Safe to fire every tick: it no-ops when already reached, busy, or missing inputs; the game resolver owns the actual upgrade job.
EXAMPLE
On Tick → Upgrade Core
Process
prod.processStarts a processing recipe from routed resource inputs.
PINS
- ▶ in▸
- ▶ out▹
PARAMS
- recipedefault: ICE_TO_WATER
- batchdefault: 1
- bufferLimitsdefault: [object Object]
- runConditiondefault: [object Object]
WHY
A direct resource wire tells Production which stock may be consumed for this recipe.
EXAMPLE
Storage(ICE) -> Process(ICE_TO_WATER)
Combine
prod.combineStarts a combine recipe once all routed inputs are present.
PINS
- ▶ in▸
- ▶ out▹
PARAMS
- recipedefault: HYDROGEN_OXYGEN_FUEL
- batchdefault: 1
- bufferLimitsdefault: [object Object]
- runConditiondefault: [object Object]
WHY
Use it for fuel, alloy, methane, and advanced-fuel branches.
EXAMPLE
Storage(HYDROGEN) + Storage(OXYGEN) -> Combine(FUEL)
Energy
prod.energyConverts routed fuel into Station charge.
PINS
- ▶ in▸
- ▶ out▹
PARAMS
- resourcedefault: FUEL
- batchdefault: 1
- bufferLimitsdefault: [object Object]
- runConditiondefault: [object Object]
WHY
Use this instead of old exec energy policies in token-flow Production.
EXAMPLE
Storage(FUEL) -> Energy -> Storage(CHARGE)
Destroy
prod.destroyConsumes every incoming resource token from shared Core stock.
PINS
- ▶ in▸
- ◦ in▸
PARAMS
- bufferLimitsdefault: [object Object]
WHY
Use only for explicit surplus cleanup; anything that reaches Destroy is deleted.
EXAMPLE
Storage(IRON) -> Split -> Destroy
Production Process
production.processStarts process jobs from the Production graph using a chosen actor/channel policy.
PINS
- ▶ in▸
- ▶ out▹
PARAMS
- recipedefault: ICE_TO_WATER
- batchdefault: 1◦ wirable
- actordefault: processor-first
- channeldefault: any
- requiresdefault: [object Object]
- stockBelowdefault: [object Object]
- minChargedefault: 0
- minStagedefault: 1
WHY
Use this instead of the legacy Production Queue table for ICE→WATER, WATER electrolysis, and stealth-charge processing.
EXAMPLE
On Tick → Production Process(ICE_TO_WATER, processor-first)
Production Combine
production.combineStarts combine jobs from the Production graph using a chosen actor/channel policy.
PINS
- ▶ in▸
- ▶ out▹
PARAMS
- recipedefault: HYDROGEN_OXYGEN_FUEL
- batchdefault: 1◦ wirable
- actordefault: processor-first
- channeldefault: any
- requiresdefault: [object Object]
- stockBelowdefault: [object Object]
- minChargedefault: 0
- minStagedefault: 1
WHY
Use this for fuel, alloy, methane, and advanced-fuel chains as graph nodes instead of table entries.
EXAMPLE
On Tick → Production Combine(HYDROGEN_OXYGEN_FUEL, processor-first)
Production Energy
production.energyStarts fuel-to-charge jobs from the Production graph.
PINS
- ▶ in▸
- ▶ out▹
PARAMS
- resourcedefault: FUEL
- batchdefault: 1◦ wirable
- channeldefault: any
- requiresdefault: [object Object]
- maxChargedefault: 3000
- minStagedefault: 1
WHY
Use this as the graph-native replacement for Energy Policy rules.
EXAMPLE
On Tick → Production Energy(FUEL, maxCharge 3000)
Process Resource
action.processRequests a single-input refining job on Core or a Processor actor — turn ICE into WATER, electrolyse WATER, crack surplus fuels, or convert DEUTERIUM into a stealth charge.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out — emits the intent; the resolver gates the actual job start by actor/channel/inputs/charge.
- ◦ actor▸— Optional Core/Processor entity. Unwired means Core.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- recipedefault: ICE_TO_WATER— ICE_TO_WATER (5 ICE→4 WATER, tiny +DEUTERIUM chance), WATER_ELECTROLYSIS (3 WATER→2 H₂+1 O₂), FUEL_CRACKING (1 FUEL→1 H₂+1 O₂), METHANE_CRACKING (1 METHANE→1 CARBON+2 H₂), ADVANCED_FUEL_CRACKING (1 ADVANCED_FUEL→1 METHANE+1 O₂), DEUTERIUM_TO_STEALTH_CHARGE (1 DEUTERIUM→1 stealth charge). Use Generate Energy for FUEL or ADVANCED_FUEL → charge.
- batchdefault: 1◦ wirable— How many recipe units to run (1–10). Inputs, ticks and energy all scale with batch.
- channeldefault: any— any uses the first free channel; 1/2 targets a specific Processor channel.
WHY
Half of the resource economy: the tick resolver starts the job only when the chosen actor has a free channel, inputs, and charge. Once started, it reserves inputs and continues independently over several ticks. Core has one channel; Processor has two and supports Process/Combine only.
EXAMPLE
On Tick → Process Resource(ICE_TO_WATER, batch 2) → 10 ICE → 8 WATER
Generate Energy
action.energyRequests a Station energy job when the Core is idle — convert FUEL or ADVANCED_FUEL into station charge.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out — emits the intent; the resolver starts it only if the Core channel, fuel, and charge allow.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- resourcedefault: FUEL— Which stored fuel to convert: FUEL gives +1000 ⚡ per batch, ADVANCED_FUEL gives +2200 ⚡ per batch.
- batchdefault: 1◦ wirable— How many fuel units to convert (1–10). Inputs, ticks and charge output scale with batch.
WHY
The charge economy's explicit burn step: reserve fuel, spend a small amount of charge per tick, then top up the Station pool by +1000 charge per FUEL or +2200 per ADVANCED_FUEL. The active job continues on its own and blocks new Core building jobs; extra reached Process/Combine/Generate/Construct actions are ignored rather than queued.
EXAMPLE
On Tick → Generate Energy(FUEL, batch 2) → 2 FUEL → +2000 ⚡
Generate
action.generateConsumes 10000 CHARGE and 1 ADVANCED_FUEL to add +1000 profile XP and +1 rating.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out — emits the intent; the resolver applies it only if the Core channel, station charge, and ADVANCED_FUEL allow.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
WHY
Profile progress is permanent, while rating is risk-based: the resolver awards it only when the Core channel is free and the colony has enough charge and advanced fuel. Rating resets when the colony is lost.
EXAMPLE
On Tick → Generate → -10000 ⚡, -1 ADVANCED_FUEL, +1000 XP, +1 rating
Combine Resources
action.combineRequests a multi-input crafting job on Core or a Processor actor — fuse resources into fuel, alloy, methane, or advanced fuel, including byproducts that must be routed.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out — emits the intent; the resolver gates the actual job start by actor/channel/inputs/charge.
- ◦ actor▸— Optional Core/Processor entity. Unwired means Core.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- recipedefault: HYDROGEN_OXYGEN_FUEL— HYDROGEN_OXYGEN_FUEL (2 H₂+1 O₂→1 FUEL+1 WATER), IRON_NICKEL_ALLOY (2 IRON+1 NICKEL→1 SPACE_ALLOY+1 SLAG), CARBON_HYDROGEN_METHANE (1 CARBON+4 H₂→1 METHANE), METHANE_OXYGEN_ADVANCED_FUEL (1 METHANE+2 O₂→1 ADVANCED_FUEL+1 WATER).
- batchdefault: 1◦ wirable— How many recipe units to run (1–10). Inputs, ticks and energy all scale with batch.
- channeldefault: any— any uses the first free channel; 1/2 targets a specific Processor channel.
WHY
The other half of the economy: the tick resolver starts the job only when the chosen actor has a free channel, inputs, and charge. Once started, it reserves inputs and continues independently over 5–8 × batch ticks. Processor has two channels for Process/Combine automation.
EXAMPLE
On Tick → Combine Resources(IRON_NICKEL_ALLOY, batch 1) → 2 IRON + 1 NICKEL → 1 SPACE_ALLOY + 1 SLAG
Transfer Charge
action.charge.transferGives charge to an adjacent same-colony ally drone — a set amount, or as much as it can spare.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ to▸— The same-colony drone to charge (object), e.g. from Scan(ALLY).
- ▶ error▹— Exec - runs when this node fails with a runtime error.
PARAMS
- amountdefault: 0◦ wirable— How much charge to give; 0 = as much as can be spared.
WHY
Keep a forward fleet alive without trekking back to the Station — a support drone can ferry charge out to miners and fighters in the field. The target must be in an adjacent cell.
EXAMPLE
Scan(ALLY) → Branch(found?) ─true→ Transfer Charge(target, amount 0)
Repair (Laser)
action.healUses the mining laser in repair mode at range 2 to spend 1 IRON from cargo and restore 25 HP to itself, another drone, or the Core.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ target▸— Who to repair (object); defaults to self. Wire a scanned CORE target to repair the Core.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
WHY
A laser drone doubles as a repair unit — keep damaged drones alive and keep the Core from decaying to zero. Requires a mining laser module and IRON in the drone cargo.
EXAMPLE
Withdraw Resource(IRON, 1) → Scan(CORE) → Repair(target)
Self Destruct
action.selfDestructImmediately removes the running drone and everything it carries.
PINS
- ▶ in▸— Exec in. There is no exec out because the drone is gone after this runs.
- ▶ error▹— Exec - runs when this node fails with a runtime error.
WHY
Use it as an emergency terminal action: abandon a stranded drone, clear an obsolete unit, or stop that actor once it has served its purpose. Carried resources are discarded with the drone.
EXAMPLE
Branch(emergency?) ─true→ Self Destruct
Emit Signal
action.emitBroadcasts a signal payload to this colony's own graph logic.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
- ◦ payload▸— The message to broadcast (signal).
WHY
Coordinate same-colony drones and Core logic across ticks. Other player colonies are hostile, not signal listeners.
EXAMPLE
Scan(ENEMY) → Branch(found?) ─true→ Emit Signal(payload: 'raid')
Set Chunk Note
action.setRoomNoteWrites an automatic scout note for a chunk during graph execution.
PINS
- ▶ in▸
- ▶ out▹
- ◦ chunk▸— Chunk or position object to annotate. Unwired means the actor's current chunk.
- ◦ text▸— Note text. A wired value overrides the text parameter.
PARAMS
- text◦ wirable
WHY
Let a scout tag chunks deterministically when it reaches them or when a resource/threat rule matches. Manual notes from the world map stay separate.
EXAMPLE
Get Position(chunk) → Set Chunk Note(text 'frontier checked')
LOGIC
4 NODESBoolean logic — AND, OR, NOT, Is Null? — combine and invert conditions.
Is Null?
data.isNullTrue when the wired value is empty — a memory cell that was never written, a Scan that found nothing, or an empty list.
PINS
- ◦ value▸— The value to test (from Get Memory, Scan Entity, Scan Entities, Filter, …).
- ◦ null?▹— True when that value is empty/unset.
WHY
Guard on presence: scan for ore, stash the target with Set Memory, then only keep searching while Is Null?(Get Memory target) is true — stop once memory holds something.
EXAMPLE
Get Memory(target) → Is Null? → Branch ─true→ Scan(IRON)
Not
data.notInverts a boolean — true becomes false, false becomes true.
PINS
- ◦ in▸— The boolean to invert.
- ◦ out▹— The inverted value.
WHY
Flip a condition without rewiring or swapping a Branch's outputs: Not(found?) is true exactly when nothing was found. Feed into a Branch or Gate.
EXAMPLE
Scan(found?) → Not → Branch ─true→ (nothing found)
AND
data.andOutputs true only when both boolean inputs are true.
PINS
- ◦ a▸— First boolean input.
- ◦ b▸— Second boolean input.
- ◦ out▹— True when both inputs are true.
WHY
Combine guards before branching: enough stock AND Core is idle, target found AND cargo is not full.
EXAMPLE
Is Busy? → Not → AND(with Count check) → Branch
OR
data.orOutputs true when at least one boolean input is true.
PINS
- ◦ a▸— First boolean input.
- ◦ b▸— Second boolean input.
- ◦ out▹— True when either input is true.
WHY
Join alternative conditions without duplicating branches: alarm is set OR enemy is visible, storage is low OR charge is low.
EXAMPLE
Scan Enemy(found?) → OR(with alarm) → Branch
VALUE
4 NODESLiteral value nodes — String, Int, Boolean, List.
String
data.stringEmits a fixed text value.
PINS
- ◦ value▹— The literal text this node outputs.
PARAMS
- value— The text to emit.
WHY
Supply a literal string to another node — a memory cell name, a label, a channel.
EXAMPLE
String("alarm") → Set Memory.param.nameInt
data.intEmits a fixed whole number.
PINS
- ◦ value▹— The literal number this node outputs.
PARAMS
- valuedefault: 0— The number to emit.
WHY
Supply a numeric threshold or amount to another node — the 20 in 'energy < 20', the 30 in 'sell 30'.
EXAMPLE
Int(20) → Compare.b (a reusable threshold)
Boolean
data.boolEmits a fixed true/false value.
PINS
- ◦ value▹— The literal boolean this node outputs.
PARAMS
- valuedefault: false— The true/false value to emit.
WHY
Supply a constant flag — force a Gate open, seed an AND/OR, or default a wired condition.
EXAMPLE
Boolean(true) → Gate.param.open
List
data.listBuilds a list from up to three wired items (empty inputs are skipped).
PINS
- ◦ item 0▸— First item (optional).
- ◦ item 1▸— Second item (optional).
- ◦ item 2▸— Third item (optional).
- ◦ list▹— The assembled list — wire into For Each or a function input.
WHY
Assemble a small fixed list of entities/values to iterate with For Each or pass to a function.
EXAMPLE
Self + Scan Entity → List → For Each
DATA
13 NODESPure data nodes — memory, math, comparisons, filters, signals.
Drone Modules
data.modulesDefines a reusable drone module loadout and outputs the modules plus derived construction stats.
PINS
- ◦ modules▹— The assembled modules object — wire into Construct Drone's modules port.
- ◦ energy▹— Station charge cost to construct this drone.
- ◦ time▹— Construction time in ticks. Each module adds 1 tick.
- ◦ hp▹— Resulting max HP.
- ◦ weight▹— Resulting module weight.
- ◦ speed▹— Resulting movement speed.
- ◦ charge cap▹— Resulting charge capacity.
- ◦ cargo cap▹— Resulting cargo capacity.
PARAMS
- modulesdefault: engine,laser— The module loadout, built with the −count+ builder. The live readout shows the resulting HP, move delay, charge/cargo capacity, damage, cost and build time.
WHY
Author modules once — HP, speed, charge, cargo, energy cost, and construction time are computed live — then wire it into one or many Construct Drone nodes instead of re-typing the loadout each time.
EXAMPLE
Drone Modules(engine,engine,laser) → Construct Drone.modules
Blueprint
data.blueprintSelects a buildable blueprint.
PINS
- ◦ blueprint▹— The chosen blueprint id: processor or market.
PARAMS
- blueprintdefault: processor— Which blueprint to place: processor or market.
WHY
Use it to feed Place Build Plan's blueprint param.
EXAMPLE
Blueprint(market) → Place Build Plan.blueprint
Make Position
data.positionBuilds a chunk-aware target position object.
PINS
- ◦ chunk▸— Optional chunk object from Get Position, Scan Chunks, Get Chunk Info, or Find Chunk Route.
- ◦ target▹— Position object with roomX, roomY, x, y.
- ◦ chunk x▹— Chunk X used by the target.
- ◦ chunk y▹— Chunk Y used by the target.
- ◦ x▹— Tile X inside the chunk.
- ◦ y▹— Tile Y inside the chunk.
PARAMS
- xdefault: 25— Tile X inside the chunk. Default 25.
- ydefault: 25— Tile Y inside the chunk. Default 25.
WHY
Feed remote destinations into Move To, Find Path, Get Chunk Info, Find Chunk Route, Mine, or Missile Strike. Legacy x/y-only targets still mean the actor's current chunk.
EXAMPLE
Make Position(chunk 8,4, x 25, y 25) → Move To(target)
Signal
data.signalBuilds a signal on a named channel to broadcast with Emit Signal.
PINS
- ◦ signal▹— The signal to broadcast — wire into Emit Signal's payload.
PARAMS
- channeldefault: raid— The channel name other roles listen on.
WHY
Answers 'what do I emit?' — name a channel (raid, lowStock, rally) and wire it into Emit Signal. Core and actor-scoped logic can Wait (signal mode) on, or Gate by, the same channel to coordinate.
EXAMPLE
Signal(raid) → Emit Signal
Get Memory
data.getVarReads a memory cell — the drone's private memory, or the colony-shared core memory.
PINS
- ◦ value▹— The stored value; unset reads as empty.
PARAMS
- scopedefault: drone— drone = private to this drone; core = shared across the whole colony.
- namedefault: target— The memory cell name to read.
WHY
Recall state saved by Set Memory: a home tile, a target id, a counter, a colony-wide alarm flag. Drone memory is private to each drone; core memory is shared across the colony.
EXAMPLE
Get Memory(core, alarm) → Compare(> 0) → Branch
Set Memory
data.setVarWrites a value into a memory cell — drone-private or colony-shared.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
PARAMS
- scopedefault: drone— drone = private to this drone; core = shared across the whole colony.
- namedefault: target— The memory cell name to write.
- valuedefault: 0◦ wirable— The value to store; wire one in or type it.
WHY
Remember things across ticks and nodes instead of recomputing them: stash a target id, bump a counter, raise a colony alarm. Wire a value in or type it.
EXAMPLE
Scan(ENEMY) → Branch(found?) ─true→ Set Memory(core, alarm, 1)
Delete Memory
data.deleteVarDeletes a memory cell — drone-private or colony-shared.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out.
PARAMS
- scopedefault: drone— drone = private to this drone; core = shared across the whole colony.
- namedefault: target— The memory cell name to delete.
WHY
Clear stale state once it is no longer valid: forget a target after hauling, drop an alarm after the scan is clean, or reset a cached route.
EXAMPLE
Branch(done?) ─true→ Delete Memory(drone, target)
Compare
data.compareCompares two numbers (a vs b) with the chosen operator and outputs a boolean.
PINS
- ◦ a▸— Left operand (number).
- ◦ b▸— Right operand (number).
- ◦ result▹— Result of the comparison (bool).
PARAMS
- opdefault: <— The comparison operator: <, >, =, !=, >=, <=.
- adefault: 0— Left operand fallback. Ignored while the `a` pin is wired.
- bdefault: 0— Right operand fallback. Ignored while the `b` pin is wired.
WHY
Turns numeric sensors into decisions — energy < 20, price > 8, cargo = max. The usual source for a Branch's cond.
EXAMPLE
Get Stat(charge) → Compare(a < b, b = 250) → Branch.cond
Math
data.mathPerforms an arithmetic operation (+ − × ÷) on two numbers.
PINS
- ◦ a▸— First operand (number).
- ◦ b▸— Second operand (number).
- ◦ =▹— The result (number).
PARAMS
- opdefault: +— The operator: +, −, ×, or ÷.
WHY
Compute thresholds and amounts on the fly — scale a quantity, derive a budget, combine two sensors before comparing.
EXAMPLE
Get Stat(cargo) × Int(2) → Math → Compare → Branch
Filter
data.filterNarrows a list to items whose chosen field satisfies a comparison. The field picker follows the connected list source.
PINS
- ◦ list▸— The list to narrow (from Scan Entities, Get Drones, Get Resources, or another Filter).
- ◦ list▹— The matching subset (a list) — wire into For Each.
- ◦ count▹— How many items passed the filter.
PARAMS
- fielddefault: x— Which item field to test. Options are inferred from the list wired into `list`.
- opdefault: <— Comparison operator: <, >, =, !=, >=, <=.
- valuedefault: 20— The threshold to compare against.
WHY
Pick the subset you care about before iterating: scanned targets by x/y/kind, drones with charge < 250, or resource rows by good/qty. Wire a list in and a narrowed list out into For Each.
EXAMPLE
Scan Entities(IRON) → Filter(x > 10) → For Each ─body→ Move To
Self
data.selfA reference to the entity currently running this graph path.
PINS
- ◦ entity▹— The running entity (object).
WHY
Point actions and sensors at yourself — read your own stats, haul to your own position, or pass self into a function.
EXAMPLE
Self → Get Stat(charge) (read my own charge)
Random
data.randomOutputs a random number within a min–max range.
PINS
- ◦ value▹— A random value between min and max.
PARAMS
- mindefault: 0— Lower bound (inclusive).
- maxdefault: 10— Upper bound.
WHY
Add variety so units don't act identically — jitter patrol points, stagger trades, pick among targets.
EXAMPLE
Random(0–10) → Wait(ticks) (stagger units so they don't sync)
Log
logPrints the wired value to the console, or fixed text when no value is wired.
PINS
- ▶ in▸— Exec in.
- ▶ out▹— Exec out — passes control straight through.
- ◦ value▸— Optional value to print (any type). When wired, it takes priority over the text field.
PARAMS
- text— Fixed text to print when no value is wired.
- logdefault: true— Toggle console output on/off.
WHY
The debugging tool. Drop it inline to watch what a graph is doing every tick; toggle it off without deleting the node.
EXAMPLE
Log(text) or Scan(target) → Log(value)