Skip to content

Instantly share code, notes, and snippets.

@goto-bus-stop
Last active May 12, 2021 01:35
Show Gist options
  • Save goto-bus-stop/ad7e104dc5619d72e20677bae33a05fb to your computer and use it in GitHub Desktop.
Save goto-bus-stop/ad7e104dc5619d72e20677bae33a05fb to your computer and use it in GitHub Desktop.

The header format changed quite significantly in 4.8+. Here's what I have so far. Mostly found by comparing headers to the Sync Logs generated by HD Edition, which log game settings & more (SteamApps/common/Age2HD/Logs/%date%/SyncLog GameType etc.txt). Still lots of unknowns :'

struct aoe2recordHeader50 {
  float thousandSomething; // I've seen 1000, 1004, 1005, not sure what for.
  int thousand;
    /* Relevant strings for this space, not sure how they work yet:
      &mrefDlcOptions
      &refGameDataSet
    */
  longbool unknownBool;
  int datasetsCount;
  int datasets[datasetsCount]; // Not sure!
  int difficulty;
  int mapSize; // Probably?
  int mapId;
  int visibility; // REVEAL_NORMAL, REVEAL_EXPLORED, REVEAL_ALLVISIBLE
  int victoryType;
  int unknown; // starting resources?
  int unknown; // strings suggest this may be starting age (1-based?)
  int unknown; // strings suggest this may be ending age (1-based?)
  int gameType; // RANDOM_MAP, DEATH_MATCH etc, i think.
  int separator;
  // Map name used to be here.
  int separator;
  float gameSpeed;
  int treatyLength;
  int popLimit;
  int numPlayers;
  /* Relevant strings:
     unusedPlayerColor ← maybe this is 8 one-byte flags?
     mVictory.getAmount() ← and this an int?
   */
  byte unknowns[16];
  int separator;
  struct {
    bool tradingEnabled;
    bool teamBonusesDisabled;
    bool randomizePositions;
    bool fullTechTreeEnabled;
    bool numberOfStartingUnits;
    bool teamsLocked;
    bool speedLocked;
    bool isMultiPlayer;
    bool cheatsEnabled;;
    bool recordGameEnabled;
    bool animalsEnabled;
    bool predatorsEnabled;
  } flags;
  int separator;
  int unknowns[2]; // playerScenarioPlayerIndecies
                   // oneBaseColorTableIndex
  /* Possibly related strings:
   scenarioPlayer
   oldExtraScenarioPlayer
   oneBasedColor
   oldGaiaColor
  */
  aoe2recordPlayer players[numPlayers];
  // Bunch of unknown stuff
  char unknowns[4]; // Looks like flags for something
  /* last 3 are:
   mFogOfWarEnabled
   mCheatNotificationsEnabled
   mColoredChatEnabled
  */
  int separator;
  bool isRanked;
  bool allowSpectators;
  int lobbyVisibility;
  int customRandomMapFileCrc;
  aoe2recordString unknown; // mCustomScenarioOrCampaignFile
  int unknowns[2];
  aoe2recordString unknown; // mCustomRandomMapFile
  int unknowns[2];
  aoe2recordString unknown; // mCustomRandomMapScenarioFile
  int unknowns[2]; // poolIndex ?
  GUID guid; // 16 bytes
  aoe2recordString gameTitle;
  aoe2recordString moddedDatasetTitle;
  int unknowns[2]; // mModdedDatasetWorkshopId?
  aoe2recordString unknown;
  int unknown;
  int unknowns[3];
};

struct aoe2recordPlayer {
  short start; // 0xFF 0x01
  int datCrc; // Hash of data f{iles
  char mpVersion; // 54 for AK 4.8, 56 for RoR
  int teamIndex; // _probably_. I've not tried a team game yet tbh
  /* or:
  
  */
  int civId;
  aoe2recordString aiBaseName; // computerAiFileName
  char aiCivNameIndex;
  aoe2recordString unknown; // Might be the configured player name for scenarios? Just a guess
    // or "aiPlayerName"
  aoe2recordString playerName;
  int unknown; // This might be a "Humanity" value (AI, Human, Spectator(?))
  uint64_t steamId;
  int playerIndex; // "worldPlayerArrayIndexIncludingGaia" internally
  int unknown; // Seems to be constant 3 among all players so far...
  int someIndex; // Maybe scenario player index? But not sure. Usually same as playerIndex.
    // Should test with a coop game.
    // May very well be "scenarioPlayerIndex"
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment