GRASS Event Schemas

Version: 1.2.0 Category: streaming

Complete catalog of GRASS event payload schemas for AI agents.

This page is GRASS (NATS) only. For structsd Tendermint events see chain-events.md.


Base Event

GRASS envelopes share routing fields; entity-specific fields depend on the category.

Field Type Required Description
subject string Yes NATS subject for this event; game subjects begin structs., block ticks use consensus
category string Yes Event category (see event-types.yaml)
id string Category-dependent Entity identifier; not present on every envelope
time / updated_at string (date-time) Category-dependent Planet activity uses time, including microseconds

Grid and planet events carry the owner player_id (added 2026-07-07). Their subjects append it — structs.grid.{object_type}.{object_id}.{player_id} and structs.planet.{planet_id}.{player_id} — and their payloads include a top-level player_id string field (the literal noPlayer when the owner can’t be resolved). This holds for full and stubbed planet payloads. Subscribe with a trailing */> (see subscription-patterns.md).

detail has two representations depending on transport. Over NATS/GRASS the frame is parsed once (message.json()), so detail arrives as an already-parsed object — access detail.* directly. Over the Guild API planet-activity REST feed the same detail comes from a PostgreSQL column as a JSON-encoded string — you must JSON.parse(row.detail) first. Code that consumes both transports must branch on the source. See api/integration-notes.md — Event detail has two representations.


Event Definitions

PlayerConsensusEvent

Extends BaseEvent. Category: player_consensus

Data Fields:

Field Type Description
id string Player ID
guildId string Guild ID
primaryAddress string Player primary address
username string Player display name (on structs.player; from chain UGC)
pfp string Profile picture URI (on structs.player; from chain UGC)

Fires when sync-state commits an insert or update to structs.player, including UGC changes from MsgPlayerUpdateName / MsgPlayerUpdatePfp or signup proxy.

GuildConsensusEvent

Extends BaseEvent. Category: guild_consensus

Data Fields: Guild consensus data object.

GuildMetaEvent

Extends BaseEvent. Category: guild_meta

Data Fields:

Field Type Description
id string Guild ID
description string Guild description (off-chain config on structs.guild_meta)
tag string Short guild tag
logo string Logo URI
services object Guild API / GRASS / webapp endpoint map

Chain UGC name and pfp live on structs.guild and surface via guild_consensus / chain events — not through guild_meta.

UGCModeratedEvent (Cosmos chain event)

Not delivered through GRASS. Untyped Cosmos event ugc_moderated. Subscribe and catalog: chain-events.md. Attribute table: ugc-moderation.md.

GuildMembershipEvent

Extends BaseEvent. Category: guild_membership

Data Fields: Guild membership change data object.

EventGuildRankPermission

Extends BaseEvent. Category: guild_rank_permission

Fires when guild rank permissions are set or revoked on an object.

Data Fields:

Field Type Description
guildRankPermissionRecord object Guild rank permission record
guildRankPermissionRecord.objectId string Object the permission applies to
guildRankPermissionRecord.guildId string Guild ID
guildRankPermissionRecord.permissions integer Permission bitmask (single bit, decomposed)
guildRankPermissionRecord.rank integer Worst-allowed rank for this permission bit (0 = revoked)
{
  "guildRankPermissionRecord": {
    "objectId": "6-1",
    "guildId": "0-1",
    "permissions": 4,
    "rank": 3
  }
}

PlanetRaidStatusEvent

Extends BaseEvent. Category: raid_status

Data Fields:

Field Type Description
status string Raid outcome. One of: victory (attacker won), defeat (attacker lost), attackerRetreated (attacker retreated from raid)
attackerId string Attacker player ID
planetId string Target planet ID

PlanetActivityEvent

Extends BaseEvent. Category: planet_activity

Data Fields:

Field Type Description
planetId string Planet ID associated with this activity
details object Activity details (JSONB from planet_activity table)
details.struct_health object Struct health information (additional properties allowed)

FleetArriveEvent

Extends BaseEvent. Category: fleet_arrive

Data Fields: Fleet arrival data object.

StructAttackEvent

Extends BaseEvent. Category: struct_attack

The detail payload has the attacker context flat at the top and the per-projectile outcomes nested in eventAttackShotDetail[] (one entry per shot). Field keys are camelCase (unlike most other struct events).

Top-level (attacker) fields:

Field Type Description
attackerStructId string Attacking struct ID
attackerStructType / attackerStructTypeId string / decimal string Type name / separate type ID
attackerStructOperatingAmbit string JSON ambit label, e.g. land
weaponSystem string primaryWeapon or secondaryWeapon
weaponControl string JSON control label, e.g. unguided
recoilDamage decimal string Recoil damage amount
recoilDamageToAttacker boolean Whether recoil hit the attacker
planetaryDefenseCannonDamage decimal string PDC damage contribution
attackerPlayerId string Attacking player ID
eventAttackShotDetail array Per-projectile shot outcomes (see below)

eventAttackShotDetail[] (per-projectile) fields:

Field Type Description
targetPlayerId string Player owning this shot’s target
targetStructId string Struct hit by this shot
targetStructType / targetStructTypeId string / decimal string Type name / separate type ID
evaded boolean Shot evaded
evadedCause string Evasion label, e.g. defensiveManeuver
blocked boolean Shot absorbed by a defender
blockedByStructId string Defender struct that blocked (empty if none)
damageDealt decimal string Rolled projectile damage
damage decimal string Net volley damage, carried by the final projectile row
damageReduction decimal string Volley damage reduced by armor/effects
targetDestroyed boolean Target reached 0 HP
targetCountered boolean Target fired a counter
targetCounteredDamage decimal string Counter damage dealt back

targetPlayerId is per shot. The attribution function expands the array for role target. Canonical observed health is attackerHealthBefore/After/Max at the top level and targetHealth* / blockerHealth* per shot, normally decimal strings. Final target health can include rebound after a target counter; the animation must play that counter before destruction. See the captured detail and health contract.

The PostgreSQL notification payload limit can produce a stub with subject, category, planet_id, player_id, seq, time, and stub: "true", without detail. Accept boolean true too. Fetch the authenticated exact event by the full (time, planet_id, seq) key. Preserve timestamp microseconds; do not substitute a latest-page row. Keep stream ordering while awaiting detail and discard late responses after a session or observed-planet change. A missing row is unavailable detail, not an empty successful attack. Re-read current state after a stream gap.

StructStatusEvent

Extends BaseEvent. Category: struct_status

Data Fields: Struct status change data object.

BlockEvent

Extends BaseEvent. Category: block

Data Fields:

Field Type Description
height integer Block height
hash string Block hash

Event Categories

All planet/struct categories below are planet_activity rows delivered on structs.planet.{planet_id}.{player_id} (subscribe structs.planet.{planet_id}.*).

Category Group Event Types
consensus block
guild guild_consensus, guild_meta, guild_membership
planet raid_status, shield_change, block_raid_start, fleet_arrive, fleet_depart, planet_activity
struct struct_attack, struct_health, struct_defense_remove, struct_defense_add, struct_defender_clear, struct_status, struct_move, struct_block_build_start, struct_block_ore_mine_start, struct_block_ore_refine_start
player player_consensus, player_address, player_address_pending
grid (structs.grid.{object_type}.{object_id}.{player_id}) attribute names: ore, fuel, capacity, load, structsLoad, power, connectionCapacity, connectionCount, allocationPointerStart, allocationPointerEnd, proxyNonce, lastAction, nonce, ready, checkpointBlock
inventory (structs.inventory.{denom}…) ledger actions: genesis, received, sent, migrated, infused, defusion_started, defusion_cancelled, defusion_completed, mined, refined, seized, forfeited, minted, burned, diversion_started, diversion_completed
address address_register

Not emitted by the current indexer (present in the enum/older docs only): fleet_advance and player_meta. Do not subscribe expecting them.