Validation Patterns

Version: 1.0.0
Category: Pattern
Status: Stable

Overview

This document describes validation patterns for AI agents interacting with Structs. Understanding these patterns is critical for correctly handling action results and avoiding common mistakes.

Transaction Validation Flow

Complete Flow

{
  "transactionFlow": {
    "1": "Create transaction (pending)",
    "2": "Sign transaction",
    "3": "Submit to POST /cosmos/tx/v1beta1/txs",
    "4": "Transaction moves to 'broadcast' status",
    "5": "on-chain validation occurs",
    "6": "Action succeeds OR fails based on validation",
    "7": "Check actual game state to verify result"
  }
}

Critical Understanding

⚠️ IMPORTANT: A transaction showing “broadcast” status does NOT mean the action succeeded!

Validation happens on-chain AFTER broadcast. If requirements aren’t met, the transaction will broadcast but the action won’t happen.

Verification Pattern

{
  "verificationPattern": {
    "1": "Submit transaction",
    "2": "Wait for transaction to reach 'broadcast' status",
    "3": "Query game state to verify action actually occurred",
    "4": "If action didn't occur, check requirements",
    "5": "Fix requirements and retry if needed"
  }
}

Common Validation Failures

1. Planet Building Without Command Ship

Action: MsgStructBuild on a planet
Symptom: Transaction broadcasts but struct not created
Cause: Command Ship not built or not online

Requirements Check:

{
  "requirements": {
    "commandShipBuilt": "Check fleet for Command Ship struct",
    "commandShipOnline": "Command Ship status must be 'online' (not just materialized)",
    "fleetOnStation": "Fleet status must be 'onStation' (not 'away')",
    "playerOnline": "player must be online (capacity covers load)"
  }
}

Dependency Chain:

{
  "dependencyChain": {
    "1": "Build Command Ship in fleet (MsgStructBuild)",
    "2": "Complete Command Ship build (MsgStructBuildComplete with proof-of-work)",
    "3": "Activate Command Ship (bring online)",
    "4": "Then can build on planets"
  }
}

2. Exploration Without Completing Current Planet

Action: Exploration (create new planet)
Symptom: Transaction broadcasts but planet ownership unchanged
Cause: Current planet still has ore remaining

Requirements Check:

{
  "requirements": {
    "currentPlanetEmpty": "Current planet must have 0 ore remaining",
    "playerOnline": "Player must be online"
  }
}

Verification:

{
  "verification": {
    "checkPlanetOre": "Query planet attributes for ore amount",
    "mustBeZero": "Ore amount must be 0 before exploring",
    "thenExplore": "Once empty, exploration will succeed"
  }
}

3. Building Without Sufficient Power

Action: MsgStructBuild
Symptom: Transaction broadcasts but struct not created
Cause: Insufficient power capacity

Requirements Check:

{
  "requirements": {
    "sufficientPower": "Must have power capacity > struct passive draw",
    "checkLoad": "Current load + struct load <= capacity",
    "checkStructDraw": "Struct passive draw must be available"
  }
}

4. Attacking an Unbuilt Struct

Action: MsgStructAttack against a target struct
Symptom: Transaction broadcasts but no damage is dealt
Cause: The target struct is not built. Structs still under construction (build slot occupied, not yet completed) cannot be attacked.

Requirements Check:

{
  "requirements": {
    "operatingStructOnline": "Your attacking struct must be online",
    "ownerOnline": "You (the attacking player) must be online",
    "targetBuilt": "Target struct must be fully built (not mid-construction)",
    "ambitMatch": "Counter weapons require the target to share the weapon's operating ambit",
    "sufficientCharge": "You must have enough charge on your per-player charge bar"
  }
}

Note: The attacker’s Command Ship does not need to be online or on-station to attack. Readiness is evaluated on the operating struct and the owning player only.

5. Raid Won’t Complete (Shields Not Vulnerable)

Action: MsgPlanetRaidComplete against a defender’s planet
Symptom: Transaction broadcasts but the planet is not raided and no ore is stolen
Cause: The defender’s command struct (shields) is not vulnerable, so the raid cannot resolve.

Requirements Check:

{
  "requirements": {
    "raiderPlayerOnline": "You (the raiding player) must be online",
    "raiderFleetAway": "Your fleet must be off-station (moved away) to run the raid",
    "defenderShieldsVulnerable": "The defender's command struct must be vulnerable: their fleet is off-station, OR their Command Ship is offline/destroyed",
    "raidClockStarted": "The raid clock must have started and elapsed",
    "proofOfWork": "Raid completion requires proof-of-work"
  }
}

Verification:

{
  "verification": {
    "checkDefenderFleet": "Query the defender's fleet status: onStation means shields are protected",
    "checkDefenderCommandShip": "An offline or destroyed Command Ship also exposes the shields",
    "ifProtected": "If the defender's fleet is onStation and the Command Ship is online, the raid will not complete -- wait for them to move the fleet or take the Command Ship offline"
  }
}

Validation Status Codes

Transaction Status Values

{
  "transactionStatus": {
    "pending": {
      "description": "Transaction created, waiting to be processed",
      "action": "wait"
    },
    "broadcast": {
      "description": "Transaction sent to blockchain",
      "action": "wait for validation",
      "warning": "Does NOT mean action succeeded!"
    },
    "confirmed": {
      "description": "Transaction included in block",
      "action": "verify game state"
    },
    "failed": {
      "description": "Transaction failed validation",
      "action": "check requirements and retry"
    }
  }
}

Validation Result Pattern

{
  "validationResult": {
    "transactionStatus": "broadcast",
    "actionSucceeded": false,
    "reason": "Command Ship not online",
    "gameStateCheck": {
      "expected": "Struct created",
      "actual": "No struct found",
      "match": false
    }
  }
}

Best Practices

1. Always Verify Game State

Pattern:

{
  "verificationPattern": {
    "afterAction": "Query game state",
    "compare": "Expected vs actual",
    "ifMismatch": "Check requirements and retry"
  }
}

2. Check Requirements Before Acting

Pattern:

{
  "preActionCheck": {
    "1": "Query current game state",
    "2": "Verify all requirements met",
    "3": "If not met, fix requirements first",
    "4": "Then perform action"
  }
}

3. Handle Validation Failures Gracefully

Pattern:

{
  "failureHandling": {
    "1": "Detect validation failure (action didn't occur)",
    "2": "Identify missing requirement",
    "3": "Fix requirement",
    "4": "Retry action",
    "5": "Verify success"
  }
}

Example: Building on Planet

Complete Flow with Validation

{
  "example": {
    "step1": {
      "action": "Check Command Ship",
      "query": "GET /structs/fleet/{fleetId}",
      "check": "Command Ship exists and is online"
    },
    "step2": {
      "action": "Check Fleet Status",
      "query": "GET /structs/fleet/{fleetId}",
      "check": "Fleet status is 'onStation'"
    },
    "step3": {
      "action": "Check Power",
      "query": "GET /structs/player/{playerId}",
      "check": "Sufficient power capacity"
    },
    "step4": {
      "action": "Build Struct",
      "transaction": "MsgStructBuild",
      "wait": "For broadcast status"
    },
    "step5": {
      "action": "Verify Struct Created",
      "query": "GET /structs/struct",
      "filter": "By locationId",
      "check": "Struct exists"
    },
    "step6": {
      "action": "If Not Created",
      "reason": "Check which requirement failed",
      "fix": "Fix requirement",
      "retry": "Retry build"
    }
  }
}

Error Detection Patterns

Pattern 1: Broadcast But No Result

{
  "pattern": {
    "symptom": "Transaction status = 'broadcast' but action didn't occur",
    "diagnosis": {
      "1": "Query game state",
      "2": "Compare expected vs actual",
      "3": "Identify missing requirement",
      "4": "Check requirements list"
    },
    "solution": {
      "1": "Fix missing requirement",
      "2": "Retry action",
      "3": "Verify success"
    }
  }
}

Pattern 2: Requirements Not Documented

{
  "pattern": {
    "symptom": "Action fails but requirements unclear",
    "diagnosis": {
      "1": "Check action requirements in actions.json",
      "2": "Check validation patterns",
      "3": "Query game state to understand constraints"
    },
    "solution": {
      "1": "Document missing requirement",
      "2": "Update actions.json",
      "3": "Add to validation patterns"
    }
  }
}

Testing Validation

Test Pattern

{
  "testPattern": {
    "1": "Perform action with missing requirement",
    "2": "Verify transaction broadcasts",
    "3": "Verify action does NOT occur",
    "4": "Fix requirement",
    "5": "Retry action",
    "6": "Verify action succeeds"
  }
}

Last Updated: December 7, 2025