Intel skill: scout players and planets

Information is the cheapest weapon in Structs — queries are free and instant. Before you commit hours of proof-of-work to a raid or a build, scout. Raidability is a live fleet/Command-Ship predicate, not the displayed shield number: the owner’s fleet is off-station, or their Command Ship is offline or destroyed (IsDefenderCommandStructVulnerable()). Loot is player-scoped storedOre, not the planet’s buried ore. See structs-combat. Intel that isn’t written down dies with your context window — persist it to memory/intel/.

Conventions are in conventions.md. Everything here is read-only (queries) — no transactions, no charge, no risk.

When to use it

Decisions

Scout before you commit. A raid is ~hours of PoW; a single query tells you if it’s even possible. Always check, in order:

  1. Raidability gate — is the owner’s fleet off-station, or their Command Ship offline/destroyed/absent? This is not the shield number (that number is only PoW difficulty). If yes, an opportunistic raid is on the table. If no (Command Ship online, fleet on station), an opportunistic raid can’t complete — but this is not a dead end: it’s a siege decision (can you reach and destroy their Command Ship?). See structs-combat. Note: idle is not vulnerable — a dormant owner’s powered Command Ship keeps defending, so never read raidability off an inactivity signal, a badge, or a shield value.
  2. Defenders — Planetary Defense Cannons, Tanks, generators (armoured: damage-reduction 1), shield contribution (timer). Can your fleet out-damage the defense within the window (and, for a siege, kill the Command Ship before an active defender rebuilds it)?
  3. Reward — the player’s storedOre (StoredOreAttributeId; stealable) vs. your cost. Do not read the planet’s buriedOre. Refined Alpha can’t be raided. simulate / strike_options are struct-scoped — there is no planet-raid preflight; run these reads per candidate.
  4. Power — is the target online at all? An offline/power-starved owner is already vulnerable and can’t react — the ideal target; but confirm there’s player storedOre worth taking. Do not conclude “no raidable targets” from a partial sample — enumerate before declaring the network empty.

Read playstyle, then counter it. Map observations to an archetype with playbooks/meta/reading-opponents and pick a response from playbooks/meta/counter-strategies.

Freshness matters. Power/fleet state changes block-to-block; a “vulnerable” reading minutes old may be stale. Re-scout immediately before fleet-move on a raid.

Procedure

1. Target a player/planet

structsd query structs player [player-id]
structsd query structs planet [planet-id]
structsd query structs fleet [fleet-id]                   # owner's fleet: commandStruct id + on-station/away
structsd query structs struct [commandStruct-id]          # Command Ship status/ambit (from the fleet's commandStruct)
# Defenders/generators by planet and player charge are NOT structsd CLI commands
# (they route through the Guild Stack / webapp query API — see scripts/BASELINE.md):
#   Guild Stack: select id,type,operating_ambit from struct where location_id='[planet-id]';

Determine: Command Ship online? fleet on-station? player storedOre (not planet buried ore)? Use scout.sh for a one-shot bundle when available.

2. Profile a guild

structsd query structs guild [guild-id]
structsd query structs reactor [reactor-id]               # commission, total infusion = strength
structsd query structs guild-membership-application-all   # pending applications only, all guilds
# The member roster is NOT a structsd query — membership lives on the player record:
#   Guild Stack: select id, guild_rank, ore from player where guild_id='[guild-id]';

3. Survey the galaxy

structsd query structs planet-all
structsd query structs guild-all
structsd query structs reactor-all
structsd query structs provider-all                       # market pricing/supply

4. Persist to memory

Write structured findings to memory/intel/ so the next session inherits them. Suggested shape:

// memory/intel/targets/<player-id>.json
{
  "playerId": "1-42",
  "scoutedAtBlock": 1284551,
  "commandShipOnline": false,
  "shieldsVulnerable": true,
  "defenders": [{ "id": "5-310", "type": "Planetary Defense Cannon", "hp": 6 }],
  "orePresent": 1200,
  "guildId": "0-7",
  "archetype": "turtle",
  "notes": "CS offline 3+ checks; raid window open"
}

Keep a memory/intel/galaxy.json for guild/market snapshots and memory/intel/targets/ per-target files. Record the block height with every reading so staleness is obvious. Memory schema conventions: awareness/continuity.

Advanced: Guild Stack (PostgreSQL)

The CLI is enough for targeted scouting, but galaxy-wide or repeated intel is far faster against the Guild Stack’s Postgres mirror — sub-second joins across all planets/structs/players. Deploy via structs-guild-stack; schema and query patterns in knowledge/infrastructure/database-schema. Typical wins: “all planets with ore and an offline Command Ship,” “defenders by planet,” “providers sorted by price.” Pair with structs-streaming (GRASS) for live fleet/raid/attack events instead of polling.

Query catalog (read-only)

Target Command
Player structsd query structs player [id] — returns gridAttributes (capacity, load, structsLoad, lastAction) and playerInventory
Player charge Derived, not queried: charge = latest_block_height − gridAttributes.lastAction. Get the height from structsd status. lastAction is omitted from JSON when 0 — treat missing as 0 (full charge)
Planet structsd query structs planet [id] / planet-all
Structs on a planet Guild Stack: select id,type,operating_ambit from struct where location_id='[planet-id]' (no structsd CLI equivalent)
Struct detail structsd query structs struct [id]
Guild structsd query structs guild [id] / guild-all
Guild members Guild Stack: select id, guild_rank from player where guild_id='[guild-id]' (no structsd CLI equivalent — membership is a field on the player, not a separate record)
Pending guild applications structsd query structs guild-membership-application [guild-id] [player-id] / guild-membership-application-all
Reactor structsd query structs reactor [id] / reactor-all
Provider / market structsd query structs provider [id] / provider-all
Fleet structsd query structs fleet [id]
Substation / power structsd query structs substation [id]

Requires structsd on PATH (no key needed for queries).

Verification

Intel is only as good as its freshness. Confirm a raid window by re-checking the owner’s Command Ship status (struct [commandStruct-id]) and fleet position (fleet [fleet-id]) immediately before acting, and compare the new block height to your stored scoutedAtBlock.

Errors

See also