Military System (Deterministic, Optional)
Optional, deterministic combat layer built on continuous attrition, four army states, and food-based maintenance.
Military System (Deterministic, Optional)
Armies are a secondary layer on top of the economic core.
Design constraints
- one army per tile
- deterministic combat only — outcomes are calculable before committing
- all actions are immediate, each followed by a cooldown
- army size is the only real metric
Army slots and unit tokens
Armies have two distinct components:
Army slots are auctioned separately from land tiles, using the same popcorn bidding format (10% min increment, non-refundable bid credits). Each new slot is positioned at the current frontier — the most recently claimed tiles at the map edge. Owning a slot grants the right to field one army on the map. The slot auction includes 100 unit tokens transferred to the winner — these are real, tradeable unit tokens, not just capacity. When an army is completely destroyed, its slot returns to the auction pool.
Dynamic auction window: the popcorn countdown timer adjusts based on observed demand, controlled by two admin-settable parameters:
- If recent slot auctions are averaging ≥ threshold bids → use the short window (high demand, faster slot issuance)
- If recent slot auctions are averaging < threshold bids → use the long window (low demand, slower slot issuance)
This self-regulates supply without a fixed slot-to-tile ratio: competitive periods produce slots faster, quiet periods slow issuance down.
Army unit tokens (soldiers) are a separate on-chain token issued through a continuous daily auction. The total emission is 100 units/day per active slot in the game. Players earn a share of the daily issuance proportional to their share of resources being burned at that moment:
unitShare = playerResourceBurnRate / totalResourceBurnRate
dailyUnitsEarned = unitShare × (100 × activeSlots)
Only uncommon or higher rarity resources are accepted for burning. Unit tokens are freely tradeable on secondary markets — players can earn them by burning resources or buy them directly.
Deploying units to an army is a token transfer: the player sends unit tokens to their slot's contract instance. Units can be deployed at any time, including during active combat — but deployed units have a 24-hour activation delay before they count toward army size and combat calculations.
Pending units are visible on-chain. Both sides in a fight can see incoming reinforcements and factor them into their decisions — whether to press the attack before they arrive, hold out until they do, or retreat. The full-information promise is preserved: current combat outcomes are always calculable from active units alone.
Army states
Each army is always in one of four states:
- Moving: the army has just relocated to an adjacent tile. Movement is instantaneous — the army appears on the destination tile immediately. The move then triggers a 12-hour cooldown before any further action is possible. The cooldown exists to keep movement human-controllable rather than purely bot-speed.
- Trenching: fortified in place. Grants a defensive bonus.
- Raiding: occupying a tile and capturing its resource yields. The tile's licensee no longer receives the resources produced, but continues their maintenance obligation and receives their USDCx stream. The raiding army's proceeds route to the army beneficiary if one is set, otherwise to the army slot owner.
- Attacking: engaged in combat with an army on a bordering tile.
Every state transition is instantaneous. The new state takes effect immediately, and a cooldown begins. While in cooldown, the army cannot take any new action and suffers a defense malus.
Retreat is not a separate state — it is simply a move. An army in any state, including Attacking, can transition to Moving at any time. The army instantly relocates to an adjacent tile and the 12-hour cooldown begins. Retreat closes the combat stream — combat ends the moment either side's stream to 0xdead closes.
Maintenance
Armies are sustained by a FOOD tank denominated in one selected common-tier resource token. All tier-0 resources are valid FOOD choices, but an army can only use one FOOD token at a time. Higher-tier resources are deliberately rejected for upkeep so the army economy consumes abundant low-tier production instead of rare strategic resources.
Food funding is open and additive. Anyone can deposit the selected FOOD token directly into the army tank with depositFood(token, amount). Player proxies can also stream the selected FOOD token to the army slot; settleFood() / reportMaintenance() credits streamed input into the tank and consumes elapsed upkeep. The configured maintenanceSource is only the preferred/default source for legacy stream cleanup.
The v1 food requirement remains:
foodCost = baseRate × assignedUnits^α (α > 1, exact value TBD)
This means many small armies are cheaper in aggregate than one large army of equivalent total unit count. A player fielding ten small armies pays less food than one player with a single army of the same combined size, keeping slots competitive and preventing a single mega-army from being the dominant strategy.
activeUnitsmeans units that have matured and count toward army size.- Matured-but-unsynced pending units also count once their activation timestamp has passed.
- Very small or empty configured armies have a minimum requirement of 1 wei/sec so starvation/destruction remains reachable in edge cases.
requiredFoodRate()is the live burn rate used by clients and agents to calculate runway.
If the food stream stops, the army enters chaos:
The tank is explicit: foodToken() identifies the selected common resource, foodBalance() is the settled tank balance, lastFoodSettlement() is the last accounting timestamp, foodStreamingRate() is the current aggregate incoming stream rate for the selected token, and foodSecondsRemaining() reports runway. If net streaming is at least the required rate, runway is effectively unbounded until rates or army size change.
Changing FOOD token is owner/authorized-manager only and settles first. The army must have zero tank balance before switching, so balances are never silently mixed across resource tokens.
Streams are a convenience input, not the maintenance truth condition. The current v1 ledger exposes current aggregate incoming rate but not a per-sender historical accumulation log. Player-proxy stream updates settle the army before changing rates, which keeps the standard path coherent. Direct ledger writes by arbitrary streamers are still accepted as input, but settlement can only approximate past accrual from the current aggregate rate over the elapsed window until richer stream history exists.
If settlement finds that the tank ran dry, the army enters chaos:
- Any active raid immediately ends and stolen tile yield returns to the tile owner.
- The army cannot move, raid, or attack while in chaos.
- Refilling the tank and calling
reportMaintenance()clears chaos back to Moving. - If not resupplied before 48 hours elapse, anyone can call
destroyIfStarved()to destroy and recycle the slot.
Keeper calls are intentionally idempotent. Repeated reportMaintenance() calls do not double-charge elapsed time and do not repeatedly reroute raid streams.
Combat
Two armies must be on bordering tiles. One army initiates by entering the attacking state.
Combat is implemented as token streams. When initiateAttack() is called, both ArmySlotInstance contracts open a stream of ArmyUnitToken to address(0xdead) — tokens burned continuously represent casualties:
baseRate = min(armyA, armyB) / (48 × 3600) // units per second, same for both sides
slotA → 0xdead at baseRate × modifierA
slotB → 0xdead at baseRate × modifierB
The slot's live ArmyUnitToken.balanceOf(slotInstance) IS the current army size at any moment — no separate counter. Superfluid tracks it continuously; anyone can read it with a plain balance call.
Rate is set at combat start from the current unit counts. Modifiers apply per-side independently. The rate must be explicitly updated via updateCombatRate() when:
- Reinforcements activate (after their 24-hour delay)
- A modifier changes (trenching, cooldown expiry, starvation onset)
Either party can call updateCombatRate(). Leaving a stale rate disadvantages whoever it hurts — managing this is part of the game.
The larger army takes casualties at the same absolute rate as the smaller, surviving proportionally longer. When both armies are equal size, both die linearly over 48 hours of unmodified combat.
Bonuses and maluses modify each side's effective death rate independently. A well-positioned or recently-trenched defender can substantially tilt the outcome even at a size disadvantage.
Destruction bonus
A player who completely destroys an enemy army receives a loot bonus. Any such bounty or raid-derived payout routes to the army beneficiary if one is set, otherwise to the army slot owner. Exact loot composition remains TBD, likely a portion of the destroyed army's remaining food stores or a resource drop.
Without this, the dominant defensive play is always to let the army dwindle and retreat before dying. The destruction bonus closes this loophole: attackers are incentivised to pursue a weakened enemy, and defenders must weigh early retreat against the risk of total loss.
Modifiers (indicative)
| Condition | Effect | |---|---| | Trenching | defense death rate reduced | | Post-action cooldown | death rate increased (malus) | | Starvation / chaos | death rate increased (malus), actions locked | | Ally support | TBD | | Terrain | TBD |
Why deterministic?
- Outcomes can be fully calculated from currently active units before committing.
- Pending reinforcements are visible on-chain, so both sides fight with full information.
- Trade-offs stay in planning, positioning, and timing — not luck.
Armies cannot conquer land
Armies cannot directly change tile licences. The only path to acquiring a tile is the Harberger acquisition mechanic.
What armies enable is economic subdual: a sustained raid strips the licensee of their resource yield, starving them of the resources needed to meet their maintenance obligation. A maintenance-starved licensee becomes increasingly vulnerable to a cheap claim. The full conquest path is therefore: raid → resource starvation → maintenance weakness → acquisition claim.
Armies disrupt but do not hold licences. They do not affect licence counters or maintenance rates, which are driven purely by the licence holder.
Mercenaries
Army control can be delegated using the PermissionRegistry — the army owner grants the mercenary's PlayerProxy function-scoped permissions on their ArmySlotInstance: move(), attack(), trench(), and raid() as separate grants. The mercenary cannot transfer the slot. Payment terms are agreed directly between parties (off-protocol, or via resource/USDCx streams). Delegation handles who can act; beneficiary routing handles who receives value.
This creates a distinct playstyle: a mercenary band holds no licences, maintains a mobile army, and sells military capability to whoever needs raids, protection, or territorial pressure. Mercenaries have no stake in the licence outcome — only in the fees they earn.
Scout / defensive agent
trench()retreat(uint256)
Raider agent
move(uint256)raid()retreat(uint256)
Combat agent
move(uint256)attack(uint256)retreat(uint256)trench()
Full army manager
- all combat-agent selectors
setBeneficiary(address)only if the owner trusts the agent with payout routingsetFoodToken(address)/configureMaintenance(address,address)only if the owner trusts the agent with FOOD configurationdepositReinforcements(uint256)only if the agent controls funded unit inventory and allowances
Delegation controls who can act, not who pays. ENERGY burns, unit deposits, and FOOD streams still require funded sources. In practice an agent-managed army needs:
- tactical permissions on the army slot
- a funded ENERGY source for movement
- an active FOOD stream from the owner, a sponsor, or the agent's own player proxy
- optional beneficiary rights if the agent is meant to collect raid proceeds or mercenary payment
Revocation is just as granular: revoke the same selector permissions from the operator. Transferring the army slot closes existing maintenance config and raid routing, so stale delegation/payment assumptions should be refreshed after ownership changes.
Army upgrades
Armies can be upgraded to increase size or unlock modifier bonuses. Upgrades require burning resources — exact costs and progression are TBD.
Early v1 scope
Ship first with:
- summon, move, trench, raid, attack, cooldown
- no unit specialization
- no hidden modifiers
- no multi-stage battle chains