Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CadeRemote Service

The CadeRemote gRPC service is exposed by AoE2DE during replay playback. It provides control over the replay viewer and streams game state deltas. This definition was reverse-engineered from the *.caderec format as part of the LibreMatch delta-play-replay project.

RPCs

RPCRequestResponse
InfoInfoRequestInfoResponse
PausePauseRequestPauseResponse
SetFogOfWarSetFogOfWarRequestSetFogOfWarResponse
SetPerspectiveSetPerspectiveRequestSetPerspectiveResponse
FramesFramesRequeststream FrameSequence

Info

Returns game version, API version, base directory, and enabled mod directories.

Pause

Controls the game pause state during replay playback.

SetFogOfWar

Toggles fog of war visibility.

SetPerspective

Changes the player perspective (which player’s point of view is shown).

Frames

The primary streaming RPC. Sends a continuous stream of FrameSequence messages containing delta patches, events, commands, and metrics. The request allows configuring update resolution per category and filtering particles/commands.

Proto File

syntax = "proto3";

package cade_api.rpc;

option cc_enable_arenas = true;
option optimize_for = SPEED;

service CadeRemote {
  rpc Info(InfoRequest) returns (InfoResponse);
  rpc Pause(PauseRequest) returns (PauseResponse);
  rpc SetFogOfWar(SetFogOfWarRequest)
    returns (SetFogOfWarResponse);
  rpc SetPerspective(SetPerspectiveRequest)
    returns (SetPerspectiveResponse);
  rpc Frames(FramesRequest) returns (stream FrameSequence);
}

Messages

InfoRequest / InfoResponse

message InfoRequest {}

message InfoResponse {
  uint32 gameVersion = 1;
  uint32 apiVersion = 2;
  string baseDirectory = 3;
  repeated string enabledModDirectories = 4;
}

PauseRequest / PauseResponse

message PauseRequest { bool paused = 1; }

message PauseResponse {
  bool success = 1;
  bool changed = 2;
}

SetFogOfWarRequest / SetFogOfWarResponse

message SetFogOfWarRequest { bool fogOfWar = 1; }

message SetFogOfWarResponse {
  bool success = 1;
  bool changed = 2;
}

SetPerspectiveRequest / SetPerspectiveResponse

message SetPerspectiveRequest { int32 playerId = 1; }

message SetPerspectiveResponse {
  bool success = 1;
  int32 playerId = 2;
}

FramesRequest

Configures the frame stream. Resolution entries control how often different categories of data are sent.

message FramesRequest {
  repeated ResolutionEntry desiredResolutions = 1;
  message ResolutionEntry {
    Category key = 1;
    enum Category {
      TIME_STEP = 0;
      LOW_PRIORITY = 1;
      SLEEPING_UNIT = 2;
      PARTICLES = 3;
      GAME_OPTIONS = 4;
      PARTICLES_SIMULATION_OUTPUT = 5;
    }

    int32 gameTimeResolution = 2;
  }

  bool disableCommands = 2;
  bool disableParticles = 3;
  repeated string particleDefinitionWhitelist = 4;
  bool disableParticleCulling = 5;
}

FrameSequence / Frame

Each FrameSequence contains one or more frames. Each Frame carries a delta patch (binary state diff), an optional reverse patch for backward navigation, game events, commands, and performance metrics.

message FrameSequence {
  repeated Frame frame = 1;
  uint32 sendingWorldTime = 2;
  uint32 numberOfFramesQueued = 3;
}

message Frame {
  uint32 time = 1;
  bytes patch = 2;
  repeated Event event = 3;
  bytes reversePatch = 4;
  uint32 timeStepsSkipped = 7;

  repeated MetricEntry metrics = 5;
  message MetricEntry {
    Region key = 1;
    enum Region {
      ALL = 0;
      ENTITIES = 1;
      SLEEPING_ENTITIES = 2;
      MAP_TILES = 3;
      UNIFIED_VISIBLE_MAP = 4;
      PARTICLES = 5;
      MASTER_ENTITIES = 6;
      RESEARCH_STATES = 7;
      VICTORY_POINTS = 8;
      APPLY_PATCH = 9;
      GAME_OPTIONS = 10;
    }

    uint32 timeMeasured = 2;
    uint32 count = 3;
  }

  repeated Command command = 6;
}

Event

Game events are delivered as a oneof union:

message Event {
  oneof event {
    EntityKilled entityKilled = 1;
    MarketTransaction marketTransaction = 2;
    Tribute tribute = 3;
    PlayerChat playerChat = 4;
    CombatNotificationSound combatNotificationSound = 5;
  }

  message EntityKilled {
    int32 id = 1;
    int32 killerId = 2;
  }

  message MarketTransaction {
    uint32 playerId = 1;
    uint32 attributeType = 2;
    float attributeBefore = 3;
    float goldBefore = 4;
    float attributeExchanged = 5;
    float goldRate = 6;
    float goldExchanged = 7;
  }

  message Tribute {
    uint32 senderId = 1;
    uint32 receiverId = 2;
    uint32 attributeType = 3;
    float senderValueBefore = 4;
    float senderValueChange = 5;
    float receiverValueBefore = 6;
    float receiverValueChange = 7;
  }

  message PlayerChat {
    int32 playerId = 1;
    int32 commPlayerId = 2;

    Channel channel = 3;
    enum Channel {
      Default = 0;
      AllChat = 1;
      TeamChat = 2;
      EnemyChat = 3;
    }

    string text = 4;
    int32 taunt = 5;
  }

  message CombatNotificationSound {
    int32 receiverId = 1;

    Type type = 2;
    enum Type {
      Normal = 0;
      Wolf = 1;
      Town = 2;
    }

    int32 attackedObjectId = 3;
  }
}

Command

Game commands represent player actions. Delivered as a oneof union with 50+ command types covering unit control, building, production, economy, diplomacy, and more.

message Command {
  oneof command {
    Interact interact = 1000;
    Stop stop = 1001;
    Work work = 1002;
    Move move = 1003;
    Create create = 1004;
    AddAttribute addAttribute = 1005;
    AiOrder aiOrder = 1010;
    Resign resign = 1011;
    AddWaypoint addWaypoint = 112;
    Pause pause = 1013;
    GroupWaypoint groupWaypoint = 1016;
    GroupAiOrder groupAiOrder = 1017;
    UnitAiState unitAiState = 1018;
    Guard guard = 1019;
    Follow follow = 1020;
    Patrol patrol = 1021;
    Scout scout = 1022;
    FormFormation formFormation = 1023;
    MultiplayerSave multiplayerSave = 1027;
    GroupMultiWaypoints groupMultiWaypoints = 1031;
    Chapter chapter = 1032;
    AttackMove attackMove = 1033;
    AttackMoveTarget attackMoveTarget = 1034;
    Retreat retreat = 1035;
    UnitTypeAiState unitTypeAiState = 1037;
    AutoScout autoScout = 1038;
    StopAll stopAll = 1039;
    MoreTechs moreTechs = 1040;
    TransformObject transformObject = 1041;
    Make make = 1100;
    Research research = 1101;
    Build build = 1102;
    Game game = 1103;
    Explore explore = 1104;
    BuildWall buildWall = 1105;
    CancelBuild cancelBuild = 1106;
    AttackGround attackGround = 1107;
    GiveAttribute2 giveAttribute2 = 1108;
    TradeAttribute tradeAttribute = 1109;
    Repair repair = 1110;
    Unload unload = 1111;
    Gate gate = 1114;
    Flare flare = 1115;
    UnitOrder unitOrder = 1117;
    Diplomacy diplomacy = 1118;
    Queue queue = 1119;
    SetGatherPoint setGatherPoint = 1120;
    SellCommodity sellCommodity = 1122;
    BuyCommodity buyCommodity = 1123;
    UnitTransform unitTransform = 1125;
    DropRelic dropRelic = 1126;
    TownBell townBell = 1127;
    GoBackToWork goBackToWork = 1128;
    MultiQueue multiQueue = 1129;
    SetGatherState setGatherState = 1130;
    DeleteObjects deleteObjects = 1131;
    ResetBuildings resetBuildings = 1132;
    MultiGate multiGate = 1133;
    GoBackToWork2 goBackToWork2 = 1134;
    ChangePlayerName changePlayerName = 1135;
    UnknownCommand unknownCommand = 2000;
  }

Shared Point Types

  message XyzUintPoint {
    uint32 x = 1;
    uint32 y = 2;
    uint32 z = 3;
  }

  message XyzFloatPoint {
    float x = 1;
    float y = 2;
    float z = 3;
  }

  message XyUintPoint {
    uint32 x = 1;
    uint32 y = 2;
  }

  message XyFloatPoint {
    float x = 1;
    float y = 2;
  }

Unit Action Commands

  message Interact {
    uint32 commPlayerId = 1;
    int32 targetId = 2;
    XyFloatPoint location = 4;
    bool extend = 5;
    bool instant = 6;
    bool humanOrder = 7;
    bool controlHeld = 8;
    repeated int32 unitIds = 9;
  }

  message Stop { repeated int32 unitIds = 2; }

  message Work {
    uint32 commPlayerId = 1;
    int32 targetId = 2;
    XyFloatPoint location = 4;
    bool extend = 5;
    bool instant = 6;
    bool humanOrder = 7;
    bool controlHeld = 8;
    repeated int32 unitIds = 9;
  }

  message Move {
    uint32 commPlayerId = 1;
    int32 targetId = 2;
    XyFloatPoint location = 4;
    bool extend = 5;
    bool instant = 6;
    bool humanOrder = 7;
    bool controlHeld = 8;
    repeated int32 unitIds = 9;
  }

  message Create {
    int32 objCategory = 1;
    uint32 playerId = 2;
    XyzFloatPoint location = 3;
  }

  message AddAttribute {
    uint32 playerId = 1;
    uint32 attrId = 2;
    float attrAmount = 3;
  }

AI Commands

  message AiOrder {
    uint32 playerId = 2;
    uint32 issuer = 3;
    int32 recipient = 4;
    int32 orderType = 5;
    uint32 orderPriority = 6;
    uint32 targetOwner = 8;
    XyzFloatPoint location = 9;
    float range = 10;
    bool immediate = 11;
    bool inFront = 12;
    repeated int32 unitIds = 13;
  }

  message GroupAiOrder {
    uint32 playerId = 1;
    uint32 issuer = 2;
    int32 orderType = 4;
    uint32 orderPriority = 5;
    int32 targetId = 6;
    uint32 targetOwner = 7;
    XyzFloatPoint location = 8;
    float range = 9;
    bool immediate = 10;
    bool inFront = 11;
    repeated int32 unitIds = 12;
  }

  message UnitAiState {
    uint32 state = 2;
    repeated int32 unitIds = 3;
  }

  message UnitTypeAiState {
    uint32 state = 2;
    int32 unitType = 3;
    int32 playerId = 4;
  }

Movement & Formation Commands

  message Resign {
    uint32 playerId = 1;
    uint32 commPlayerId = 2;
    bool dropped = 3;
  }

  message AddWaypoint {
    uint32 playerId = 1;
    int32 recipient = 2;
    repeated XyzUintPoint waypoints = 4;
  }

  message Pause { repeated int32 unitIds = 2; }

  message GroupWaypoint {
    uint32 commPlayerId = 1;
    XyUintPoint location = 3;
    repeated int32 unitIds = 4;
  }

  message Guard {
    int32 targetId = 2;
    repeated int32 unitIds = 3;
  }

  message Follow {
    int32 targetId = 2;
    repeated int32 unitIds = 3;
  }

  message Patrol {
    bool reset = 3;
    repeated XyFloatPoint wayPoints = 4;
    repeated int32 unitIds = 5;
  }

  message Scout {
    XyFloatPoint location = 2;
    repeated int32 unitIds = 3;
  }

  message FormFormation {
    uint32 playerId = 2;
    int32 formationType = 3;
    repeated int32 unitIds = 4;
  }

  message GroupMultiWaypoints {
    repeated int32 unitIds = 3;
    repeated XyUintPoint waypoints = 4;
  }

  message AttackMove {
    bool reset = 3;
    repeated XyFloatPoint waypoints = 4;
    repeated int32 unitIds = 5;
  }

  message AttackMoveTarget {
    int32 targetId = 2;
    repeated XyFloatPoint waypoints = 4;
    repeated int32 unitIds = 5;
  }

  message Retreat {
    uint32 commPlayerId = 1;
    int32 targetId = 2;
    XyFloatPoint location = 4;
    bool extend = 5;
    bool instant = 6;
    bool humanOrder = 7;
    bool controlHeld = 8;
    repeated int32 unitIds = 9;
  }

  message AutoScout { repeated int32 unitIds = 2; }

  message StopAll { uint32 playerID = 1; }

Building & Production Commands

  message Make {
    int32 unitId = 1;
    uint32 unitPlayerId = 2;
    int32 objId = 3;
    int32 uniqueId = 4;
  }

  message Research {
    int32 unitId = 1;
    uint32 unitPlayerId = 2;
    int32 techId = 4;
    int32 uniqueId = 5;
    bool extend = 6;
    repeated int32 buildingIds = 7;
  }

  message Build {
    uint32 unitPlayerId = 2;
    XyFloatPoint location = 3;
    int32 objId = 4;
    int32 uniqueId = 5;
    uint32 frame = 6;
    bool extend = 7;
    bool instant = 8;
    int32 spriteOverrideId = 9;
    repeated int32 unitIds = 10;
  }

  message BuildWall {
    uint32 unitPlayerId = 2;
    XyUintPoint location1 = 3;
    XyUintPoint location2 = 4;
    int32 objId = 5;
    int32 uniqueId = 6;
    bool extend = 7;
    bool instant = 8;
    repeated int32 unitIds = 9;
  }

  message CancelBuild {
    int32 unitId = 1;
    int32 unitPlayerId = 2;
  }

  message Queue {
    int32 buildingId = 1;
    int32 trainId = 2;
    int32 trainCount = 3;
  }

  message MultiQueue {
    uint32 playerId = 1;
    int32 selectedBuildingId = 2;
    int32 trainId = 4;
    int32 trainCount = 5;
    repeated int32 buildingIds = 6;
  }

Economy & Diplomacy Commands

  message GiveAttribute2 {
    uint32 playerId = 1;
    uint32 toPlayerId = 2;
    uint32 attrId = 3;
    float attrAmount = 4;
    float attrCost = 5;
  }

  message TradeAttribute {
    int32 attribute = 2;
    repeated int32 unitIds = 3;
  }

  message SellCommodity {
    uint32 playerId = 1;
    uint32 attrId = 2;
    uint32 lotCount = 3;
    int32 unitId = 4;
  }

  message BuyCommodity {
    uint32 playerId = 1;
    uint32 attrId = 2;
    uint32 lotCount = 3;
    int32 unitId = 4;
  }

  message Diplomacy {
    uint32 playerId1 = 1;
    uint32 playerId2 = 2;
    uint32 sequence = 3;
    uint32 status = 4;
    uint32 declare = 5;
    uint32 diplomacy = 6;
    uint32 intelligence = 7;
    uint32 trade = 8;
    uint32 demand = 9;
    int32 gold = 10;
    string message = 11;
  }

Misc Commands

  message Game {
    uint32 gameCommandId = 1;
    int32 var1 = 2;
    int32 var2 = 3;
    float var3 = 4;
    uint32 var4 = 5;
  }

  message Explore {
    uint32 unitPlayerId = 2;
    XyFloatPoint location = 3;
    repeated int32 unitIds = 4;
  }

  message Repair {
    int32 targetId = 2;
    bool extend = 3;
    bool instant = 4;
    repeated int32 unitIds = 5;
  }

  message Unload {
    XyFloatPoint location = 2;
    uint32 unloadFlag = 3;
    int32 unloadUnitType = 4;
    repeated int32 unitIds = 5;
  }

  message AttackGround {
    XyFloatPoint location = 2;
    bool extend = 3;
    bool instant = 4;
    bool humanOrder = 5;
    repeated int32 unitIds = 6;
  }

  message Gate { int32 unitId = 1; }

  message Flare {
    int32 unitId = 1;
    bytes flareFlags = 2;
    XyFloatPoint location = 3;
    uint32 playerId = 4;
    uint32 commPlayerId = 5;
  }

  message UnitOrder {
    int32 targetId = 2;
    uint32 action = 3;
    uint32 param = 4;
    XyFloatPoint location = 5;
    int32 unique_id = 6;
    bool extend = 7;
    bool instant = 8;
    bool humanOrder = 9;
    repeated int32 unitIds = 10;
  }

  message SetGatherPoint {
    int32 targetId = 2;
    int32 targetMasterId = 3;
    XyFloatPoint location = 4;
    repeated int32 unitIds = 5;
  }

  message SetGatherState {
    uint32 state = 2;
    repeated int32 unitIds = 3;
  }

  message UnitTransform {
    uint32 unitPlayerId = 2;
    int32 objId = 3;
    int32 uniqueId = 4;
    repeated int32 unitIds = 5;
  }

  message TransformObject {
    uint32 playerID = 1;
    int32 masterId = 2;
    int32 objId = 3;
  }

  message MoreTechs { uint32 playerID = 1; }

  message DropRelic { int32 unitId = 1; }

  message TownBell {
    int32 unitId = 1;
    uint32 activateFlag = 2;
  }

  message GoBackToWork { int32 unitId = 1; }

  message GoBackToWork2 { repeated int32 unitIds = 2; }

  message DeleteObjects {
    uint32 playerId = 2;
    repeated int32 unitIds = 3;
  }

  message ResetBuildings {
    uint32 state = 2;
    repeated int32 unitIds = 3;
  }

  message MultiGate {
    uint32 state = 1;
    repeated int32 unitIds = 3;
  }

  message MultiplayerSave {
    bool exitAfterSave = 1;
    uint32 commPlayer = 2;
  }

  message Chapter { uint32 commPlayerId = 1; }

  message ChangePlayerName {
    uint32 playerId = 1;
    string newName = 2;
  }

  message UnknownCommand { uint32 commandId = 1; }
}