Power-cable range
One link may span 1–8 Manhattan tiles and carries at most 40 MW. It costs one copper wire per tile plus one iron plate per four tiles, rounded up.
A practical manual for your first match: controls, buildings, recipes, ports, scripts, market orders, the central project, and the exact APIs that work today.
on tick {
let ore = inventory.count("storage_main"
, 4013, "iron_ore"
);
if ore >= 20 {
machine.start("smelter_alpha"
, 4013, "iron_plate"
);
}
}VALID AFTER STORAGE + SMELTER PORTS/ROUTES · SERVER EXECUTEDYour browser sends movement, placement, configuration, script, market, scan, and objective commands. The 10 Hz match simulation rechecks ownership, terrain, resources, power, permissions, and timing before anything becomes real.
Bootstrap power, logistics, networking, and automation
New player? Start in the sandbox. It uses the real authoritative simulation, a fresh procedural 72×48 map, and 9,999 of every construction material.
Click the world, then hold the physical W A S D key positions to move. Movement uses physical key codes, so the same four keys work while a non-Latin keyboard layout is active. Use the mouse wheel to zoom, Shift + drag to pan, and C to center your operator. Click a machine for its compact summary and actions; open an advanced tool only when you need ports, code, or connection details.
Select hq_main for the team resource ledger, grid totals, and Logs tab. Select crank_main and press the highlighted prime → turn → release controls in order. It supplies at most 6 MW and exists to recover a dead grid, not to run a full factory.
Place solar, wind, hydro, or coal generation. Select the generator, open Inspect → Physical connections, choose a nearby machine, choose Power, and connect. Amber cables and moving pulses show live flow; every machine reports supply, demand, allocation, storage, and whether energy reaches it.
Place a powered miner cardinally beside iron, copper, or coal. Put a belt loader beside the miner, a connected chain of conveyors beside the loader, and a belt unloader at the far end beside storage or a consuming machine. Cargo is visible and advances one segment every four canonical ticks.
Rename the smelter to smelter_alpha. In its Ports tool, add the Production control preset; on storage_main, add the Storage reader preset. Review the generated source, then Apply. Create a powered Ethernet route from controller_main to both machines: use one direct cable to each target, or route each path through powered routers/relays. Direct cables reach 12 tiles; a router has eight jacks and an 18-tile radio diamond.
Select controller_main and open Code. Create a .tick file, validate, then deploy. Syntax highlighting, inline ghost text, Tab completion, Ctrl/Cmd+Space, and member completion after a dot use exact projected aliases and API signatures. They never bypass server compilation.
Select a powered market terminal to trade, a router/scanner/security terminal for network tools, and headquarters for resources and logs. To reorganize the floor, choose Move on an owned non-HQ machine and click its destination tile; cancel the placement cursor with Escape. Attached power and Ethernet cables must still fit their range at the destination. Remove is available behind a confirmation for owned machines except headquarters and the central project; the server refunds floor(original cost / 2) for each construction resource. Attached links and controller files give no refund, and local-buffer items or cargo on a removed belt/switch are lost—empty a machine before dismantling it.
Feed recipe inputs physically, then choose the recipe from a controller with machine.start(alias, port, recipe). There is no manual recipe selector. Watch the machine-local buffer rather than only the team ledger, and send finished goods through another loader line to storage. Build the next-tier assembler chain and use the market only for gaps or surplus. Your end goal is 20 circuits, 30 machine parts, and a powered central project on the uplink.
What to build and why
Deposits are finite. Team inventory and infrastructure are shared, but energy moves only through explicit power cables. The construction menu shows purpose, cost, and power before you place. Select any owned machine for live local telemetry.
| Building | Cost | Power | Use |
|---|---|---|---|
| Headquarters | Starter / immovable | −2 MW | Team ledger, whole-grid summary, and team logs. |
| Miner | 4 plate + 2 parts | −3 MW | Extracts one unit every 20 ticks from a cardinally adjacent finite deposit. |
| Smelter | 6 plate + 3 parts | −5 MW | Produces iron plate or copper wire. |
| Assembler | 2 circuits + 5 parts | −7 MW | Produces circuits or machine parts. |
| Solar generator | 4 plate + 2 parts | +18 MW | Steady renewable source; connect it with power cable. |
| Hand crank | 2 plate | +6 MW max | Starter emergency source; play prime → turn → release. |
| Wind turbine | 8 plate + 4 parts + 3 wire | +6–18 MW | Seeded wind changes once per simulation second. |
| Hydro turbine | 10 plate + 5 parts + 4 wire | +26 MW | Must be placed cardinally beside water. |
| Coal generator | 8 plate + 5 parts + 1 circuit | +36 MW | Consumes local coal while dispatched. |
| Grid battery | 6 plate + 6 wire + 2 circuits | 500 EU / 12 MW | Stores surplus and discharges after generators. |
| Storage | 4 plate | 0 MW | Shared inventory endpoint for loaders and unloaders. |
| Conveyor | 1 plate | 0 MW | Bidirectional belt segment; visible cargo moves at 2.5 Hz. |
| Conveyor switch | 2 plate + 2 parts | 0 MW | TickScript-routed junction with distinct A/B output directions. |
| Belt loader | 2 plate + 1 part | 0 MW | Pulls from a cardinally adjacent source onto a belt. |
| Belt unloader | 2 plate + 1 part | 0 MW | Deposits belt cargo into an adjacent consumer or storage. |
| Local controller | 2 circuits + 2 parts | −2 MW | Four TickScript files, 8,192 code units, 1,000-op base load threshold. |
| Central server | 8 circuits + 6 parts | −10 MW | Twelve files, 32,768 code units, 4,000-op base load threshold. |
| Market terminal | 2 circuits + 2 plate | −2 MW | The only place to view and place manual orders. |
| Router | 4 circuits + 2 parts + 4 wire | −4 MW | Eight Ethernet jacks and an 18-tile radio radius. |
| Wireless relay | 3 circuits + 1 part | −3 MW | Powered 12-tile wireless route node. |
| Scanner | 4 circuits + 2 parts | −4 MW | Discovers exposed enemy wireless/public services. |
| Security terminal | 6 circuits + 3 parts | −6 MW | Runs bounded fictional reconnaissance workflows. |
| Defensive turret | 2 circuits + 4 parts | −5 MW | Powered footprint; full combat remains reduced. |
| Central project | 20 circuits + 30 parts | −30 MW | Place on the central uplink to finish a match. |
One link may span 1–8 Manhattan tiles and carries at most 40 MW. It costs one copper wire per tile plus one iron plate per four tiles, rounded up.
Renewable sources dispatch first, then coal, the hand crank, and batteries. Within a category, shorter cable routes and then canonical IDs break ties. Loads receive their whole demand or remain offline.
Amber cable pulses mean non-zero flow. A selected machine says “energy is reaching” or “no usable route” and reports exact demand, allocation, supply, and battery charge.
Generation details. Solar is a steady 18 MW. Wind deterministically varies from 6–18 MW each simulation second. Hydro is 26 MW only when placed beside water. Coal is 36 MW while its local buffer has coal and burns one unit at each 100-tick boundary when dispatched. A battery stores 500 EU and charges/discharges at up to 12 MW.
| Recipe ID | Machine | Input | Output | Time |
|---|---|---|---|---|
iron_plate | Smelter | 2 iron ore + 1 coal | 1 plate | 2.0 s |
copper_wire | Smelter | 1 copper ore + 1 coal | 2 wire | 1.8 s |
circuit | Assembler | 3 wire + 1 plate | 1 circuit | 3.0 s |
machine_parts | Assembler | 3 plate + 1 circuit | 1 part | 3.5 s |
Recipes are TickScript-only. A smelter or assembler has no manual recipe control. Give it a writable control port with start,stop,status, connect a powered controller, and call machine.start("smelter_alpha", 4013, "iron_plate"). Use machine.stop only while no batch is active; a mid-batch stop is rejected so already-consumed inputs cannot be lost.
Machine-buffer limits. A miner, smelter, or assembler holds at most 64 total item units and 32 of one resource. A new batch stays output-blocked if its prospective output would cross either ceiling. Shared warehouse receipt from belts is bounded at 1,000,000 units per resource; there is no configurable per-storage-building capacity yet.
Visible endpoints, connected belts, balanced feeding, and A/B junctions
Data cables control machines; they never teleport ore. Items leave a machine only through an adjacent loader, occupy visible conveyor segments, and enter a destination only through an adjacent unloader. Belts, loaders, and unloaders consume no power in this reduced ruleset. Their sprites show real topology: belts connect to every cardinal neighbor, while endpoint arrows face the authoritative source/destination machine.
Place a loader cardinally beside a miner, smelter, assembler, storage, or headquarters that has a transferable item. Its arrow points from that source toward the belt, so a glance shows which machine is being unloaded. A loader pulls one suitable item only when the first belt segment is free.
Place four-neighbor conveyor tiles from the loader to the destination. Straight pieces, corners, T-junctions, and four-way crossings connect automatically; ordinary belts work in either direction. Cargo advances one segment every four ticks (2.5 Hz), and each segment holds one item. Occupied or broken routes visibly stall; deterministic shortest-path and stable-ID ties pick a route.
Put an unloader beside the final conveyor and beside its destination. Its arrow points from the belt into the authoritative destination. Smelters, assemblers, and coal generators are preferred over warehouses when they can consume the item; storage and headquarters act as shared warehouse endpoints.
A consumer route compares each required input’s machine buffer plus in-flight reservations against that recipe’s quantity. It chooses the lowest ratio and does not send one input more than one batch ahead. For iron_plate, mixed storage therefore feeds roughly two iron ore for each coal instead of filling the 32-unit coal limit first. The requested recipe must already be set by TickScript; the belt does not choose a recipe.
An ordinary T- or cross-junction can route toward any compatible destination. A conveyor switch has no manual routing control. Give switch_main a writable routing/route port and a powered controller route, then call conveyor.route("switch_main", 4013, "north", "east", "a"). A and B must be different cardinal directions; the last argument is exactly "a" or "b". The switch accepts cargo from any adjacent input but releases it only toward the script-selected output.
Each item is drawn on its current segment. Check endpoint arrows, the switch’s last server-confirmed A/B configuration, one-slot occupancy, destination compatibility, and the destination’s 64-total/32-per-resource buffer. The UI displays switch state but cannot change it. A broken route may reroute deterministically. Removing the occupied belt or switch deletes that cargo; it is never teleported or refunded. The match caps physical cargo at 512 items per team.
# tickrate-ports v1
port 4013 service=routing mode=write access=wired operations=route rate=60 logging=true
Apply this port to the switch, give it the exact alias switch_main, and connect the controller. conveyor.route returns true after the server accepts the new geometry and active output.
Missing aliases, unpowered routes, denied ports, invalid directions, equal A/B outputs, or an active value other than a/b stop that invocation with bounded HOST_ERROR and leave the switch unchanged.
A route and a capability are both required
Immutable server identity such as device_000A. Useful for inspection and replay.
Your exact team name such as smelter_alpha. TickScript never fixes a misspelling.
An explicit service capability: number, mode, access, operations, rate, and logging.
PRODUCTION CONTROL
# tickrate-ports v1
port 4013 service=control mode=read_write access=wired operations=start,stop,status rate=60 logging=true
STORAGE READER
# tickrate-ports v1
port 4013 service=inventory mode=read access=wired operations=count,status rate=60 logging=true
Open an owned machine’s Ports tool. Add a port, choose its fields, inspect the generated ports.tickports preview, then Apply. You normally do not need to type the declaration yourself. The advanced raw editor is useful for copying a known configuration or managing several declarations.
Apply is atomic: it replaces that machine’s complete active port set only if every field is valid and the revision is current. An error keeps the previous working configuration. Ports do nothing by themselves—the controller and target still need power and an access-compatible route.
The generated format starts with # tickrate-ports v1, supports at most 16 ports and 4,096 code units, and remains the authoritative source saved with the machine.
| Field | Choose it for | Common first-match value |
|---|---|---|
| Number | The exact integer used by TickScript | 4013 |
| Service | A machine-supported capability family | inventory, control, routing, or market |
| Mode | Whether calls may read, write, or do both | read or read_write |
| Access | Which physical route may reach the port | wired for an internal factory |
| Operations | The smallest allowlist the script needs | count; start/stop/status; route; quote/order/cancel |
| Rate | Accepted requests in each 600-tick window | 10–120 |
| Logging | Defender-visible scoped request evidence | true |
| Token / guard | Optional reduced auth label or fictional exploit defense | leave token empty; add one guard to exposed ports |
Least-privilege shortcut. Storage needs read + count; a smelter needs read/write + start, stop, status; a market terminal needs read/write + quote, order, cancel; a conveyor switch needs write + routing/route. Do not expose a factory-control port as public or wireless merely to make routing easier.
Connect two owned machines up to 12 Manhattan tiles apart. It costs one copper wire per tile. A direct endpoint call works without a router when both machines are powered.
A powered router forwards a wired path, has eight Ethernet jacks, and exposes a large 18-tile Manhattan radio diamond when selected. A powered relay uses a 12-tile radio radius.
Mode, operation, physical route, and a 600-tick request window are checked at each host call. Inspector shows requests used, total requests, and rejected requests per port.
Supported access values are local, wired, wireless, team, token, and public. The working route adapter enforces local/wired/wireless/public routing; token possession and richer team-route semantics remain reduced. Use wired for the first reliable factory network.
Small enough to learn, bounded enough to run on the server
The controller console is a compact IDE. It provides syntax highlighting, inline ghost completion, Tab/Enter insertion, and Ctrl/Cmd+Space. Type machine. to see every member and exact signature; alias arguments use the current authoritative team snapshot.
const at top level; immutable let inside functions and handlers.if / else, non-recursive fn, and literal repeat 0..64.tick, market_tick, and enemy_detected; the current match emits only tick.const MIN_ORE = 20;
fn enough(value) {
return value >= MIN_ORE;
}
on tick {
let ore = inventory.count("storage_main", 4013, "iron_ore");
if enough(ore) {
machine.start("smelter_alpha", 4013, "iron_plate");
}
}Stores four active files and 8,192 source code units. Its base load threshold is 1,000 estimated instructions, with 64 runtime memory cells per file invocation.
Stores twelve active files and 32,768 source code units. Its base load threshold is 4,000 estimated instructions, with 128 runtime memory cells per invocation.
A controller normally runs every 10 ticks. Its throttle is load divided by the base threshold, rounded up, from 1× through 8×; higher deploys are rejected. Cadence becomes 10 × throttle ticks and that pass shares threshold × throttle actual instructions. Add another powered controller for an independent file allotment and threshold.
inventory.count(storage: string, port: integer, item: string) -> integerRead inventory through an explicit storage/HQ port and physical route.
machine.start(alias: string, port: integer, recipe: string) -> booleanStart or continue a compatible recipe through an explicit writable port.
machine.stop(alias: string, port: integer) -> booleanClear the requested recipe through a writable port; rejected while a batch is active.
machine.status(alias: string, port: integer) -> integerRead 1 idle, 2 running, or 3 blocked; unavailable/offline targets fail the routed call.
conveyor.route(alias: string, port: integer, output_a: string, output_b: string, active: string) -> booleanSet distinct cardinal A/B outputs and the active branch through an owned switch routing port.
market.lowest_sell(terminal: string, port: integer, item: string) -> integerRead the lowest visible sell price; zero means there is no quote.
market.sell(terminal: string, port: integer, item: string, quantity: integer, unit_price: integer) -> booleanSubmit a bounded sell order from team inventory.
market.cancel_all(terminal: string, port: integer, item: string) -> booleanCancel the team’s open orders for one item.
production.cost(recipe: string) -> integerRead the deterministic sum of recipe input quantities.
network.read(alias: string, port: integer, metric: string) -> booleanValidate an allowlisted read; a successful powered route returns true, while an unavailable target fails.
log.info(value) -> booleanAppend one bounded informational runtime log entry.
log.warn(value) -> booleanAppend one bounded warning runtime log entry.
Compile success is not route success. Calls with an alias and port are checked again at runtime. If one stops with HOST_ERROR, verify the exact alias, both machines’ power, the Ethernet/radio route, access, service, read/write mode, operation, and 600-tick rate window—in that order. machine.status returns 1 idle, 2 running, or 3 blocked; an unreachable machine fails instead of returning 0.
Deterministic price-time matching
Build, cable, and power a market terminal, then select that machine to open Market. No other machine exposes the order book or manual order form. Submit a buy or sell intent with item, quantity, and unit price; the server reserves funds or goods, sorts orders deterministically, calculates fills, and delivers completed goods after a fixed delay.
Your full limit cost is reserved. Partial fills leave the rest open.
Goods are reserved immediately; you cannot spend the same stock twice.
Open a market port on the powered terminal, connect the controller, then use market.lowest_sell("market_main", 4013, item), market.sell, and market.cancel_all.
# tickrate-ports v1
port 4013 service=market mode=read_write access=wired operations=quote,order,cancel rate=120 logging=true
Manual orders may buy or sell 1–10,000 units at a limit price. TickScript can read the lowest sell quote, place sells of 1–100 units, and cancel this team’s orders for one item; it has no market.buy call. A script boolean means the intent was accepted, not that an order filled or made a profit.
Each file may attempt at most two scripted sells per invocation, and each team may retain at most 32 open orders. A quote of 0 means no sell quote exists. The combined tutorial port uses rate 120 so one quote plus one conditional order call can fit each script event, but do not place an order every tick—the 32-open-order ceiling is the real guardrail. Filled goods arrive through the fixed market-delivery queue rather than a physical belt.
Reconnaissance is manual, bounded, and game-only
This console is a four-command game language, not a shell. Exact grammar: sweep; probe MACHINE_ID PORT; analyze PROBE_ID TECHNIQUE; and exploit PROBE_ID TECHNIQUE patch CONSTANT VALUE. Quotes, pipes, redirection, paths, sockets, host commands, and external networks do not exist.
Select a powered scanner or security terminal and enter sweep. Both can sweep and probe; only a powered security terminal can analyze or exploit. Direct reconnaissance reaches 12 Manhattan tiles. Your powered routers and relays can extend the route with 18- and 12-tile radio ranges.
Sweep finds powered enemy devices with wireless or public ports over direct 12-tile reach or your powered router/relay radio. Inspect a discovered device, copy its immutable ID and an exposed port number, then enter probe MACHINE_ID PORT. The log returns a probe_… ID and signature. A probe lasts 1,200 ticks, has three technique attempts, and can be reused from another scanner while it remains valid.
On the security terminal, try analyze PROBE_ID frame_trace|memory_map|nonce_audit|identity_graph. The signatures map to protocol-desync, firmware-bounds, signal-replay, or trust-confusion classes. Wait until both the selected console and probe cooldown ticks have elapsed before the next stage. A wrong technique consumes an attempt and applies a 20-tick cooldown; correct work uses a 5-tick cooldown.
Match the class with sequence_resync|bounds_clamp|nonce_replay|trust_forge, then enter exploit PROBE_ID TECHNIQUE patch CONST VALUE. Only a numeric top-level constant on an enemy controller/server can change, for 300 ticks; its name must be exact uppercase-style source syntax and its value must be −10,000..10,000. The reduced slice never reveals enemy source or constant names, so a valid name comes from team knowledge or observed scenario information—not from sweep. Defenders may add a matching hidden guard to the exposed port. Sweep spends no hostile port request; probe and a route-valid exploit consume ordinary port rate and logging.
| Probe signature | Identified class | Analyze with | Exploit with | Matching defense |
|---|---|---|---|---|
framing_jitter | protocol_desync | frame_trace | sequence_resync | guard=framing |
length_drift | firmware_bounds | memory_map | bounds_clamp | guard=bounds |
nonce_repeat | signal_replay | nonce_audit | nonce_replay | guard=nonce |
identity_split | trust_confusion | identity_graph | trust_forge | guard=identity |
sweep
probe device_0042 4044
analyze probe_0091 nonce_audit
exploit probe_0091 nonce_replay patch MIN_MARGIN 15Here the sweep exposed device_0042 on port 4044; probe returned probe_0091 with nonce_repeat. The table maps that signature to nonce_audit, then nonce_replay. These IDs are illustrative—copy the IDs produced by your own match.
Wait five canonical ticks after each successful stage. The final line succeeds only if the target is still powered and reachable, the port is still exposed and under its rate limit, the probe is analyzed and off cooldown, the first eligible path-sorted file exports numeric MIN_MARGIN, and it has no active patch.
| Error | Meaning | Next check |
|---|---|---|
SECURITY_COMMAND_INVALID | The line does not match the exact four-command grammar. | Remove quotes/punctuation and check argument count. |
NETWORK_TARGET_HIDDEN | That machine has not been discovered by your team. | Run sweep from a powered in-range scanner or terminal. |
SECURITY_TERMINAL_COOLDOWN | The console or probe is not ready at this tick. | Wait for the shown canonical tick; do not spam retries. |
SECURITY_PROBE_NOT_FOUND | The probe ID is wrong or its 1,200-tick lifetime ended. | Probe the still-exposed machine again. |
SECURITY_STAGE_INVALID | The probe is at another stage or locked after three failures. | Follow probe → analyze → exploit, or wait for a locked probe to expire. |
HACK_REQUIREMENTS_NOT_MET | Equipment, target power, route, exposure, or controller/server kind is unavailable. | Check power, range, exposed access, and the target machine kind. |
PORT_DENIED | The hostile port or a routed link exhausted its request budget. | Wait for its 600-tick window or reduce route traffic. |
A wrong technique, matching hidden guard, missing constant, or already-patched file is intentionally reported only as a rejected technique in the attacker’s security log. It consumes one attempt and applies the 20-tick failure cooldown without revealing which hidden condition failed.
Apply a new atomic configuration without the exposed port, prefer wired access, and break or unpower unnecessary radio routes.
Add framing, bounds, nonce, or identity. Only a guard matching the deterministic profile neutralizes that exploit.
Enable logging, inspect headquarters security evidence, and roll the affected TickScript file back. Rollback clears an active patch; expiry does so after 300 ticks.
How the current reduced match ends
Read the physical path from source to authority
| Symptom | Check in this order |
|---|---|
| Machine is offline | Its local demand, powered source, complete 1–8-tile cable path, 40 MW link capacity, then fuel or battery charge. |
| Loader does nothing | Arrow/source adjacency, source inventory or buffer, a free first belt, a compatible destination, and the 512-cargo team ceiling. |
| Smelter received coal but not ore | Deploy machine.start for the intended recipe first; then confirm ore exists at the same reachable source and watch in-flight reservations. Recipe-aware feeding holds inputs near the required ratio. |
| Cargo stops at a branch | One-slot occupancy, connected belt shape, destination buffer, then the switch's last script-confirmed A/B directions and active branch. |
| TickScript compiles but stops | Exact alias and port, controller/target power, route, access, service, mode, operation, and rate; inspect the bounded HOST_ERROR and port reject counter. |
| Move preview is rejected | Bounds, terrain, occupancy, territory, hydro adjacency, then every attached 8-tile power and 12-tile Ethernet span. |
| Remove refund looks smaller than half | Refund is floor(cost / 2) separately for each construction item. Links, scripts, machine buffers, and belt cargo are never refunded. |
| Central project will not activate | Exact highlighted uplink tile, project ownership, a settled power topology, and the full routed 30 MW allocation. |
Configurable per-building storage capacity, loader item filters/priorities, item-sorting or timed conveyor switches, token possession, richer firewall/vulnerability modules, full combat, ranked matchmaking, checkpoint recovery, and public replay playback are not complete. The shared warehouse still has a hard per-resource safety bound. Physical power, fuel consumption, batteries, cable topology, routed ports, balanced visible cargo, and TickScript-routed A/B conveyor switches are working rules, not roadmap claims.