AOM Data File Converter
created by Ykkrosh

This program is frequently changing and many features are not fully tested. It should mostly be fine, but don't expect everything to work!
Quick instructions | General documentation | Trigger editing | Miscellaneous information



Quick instructions:
  BAR file extraction: Click "Set input data file" and choose a BAR file from wherever you installed AOM. The second textbox says where to extract the files into; it's usually best to change this to somewhere other than the default (e.g. if you were extracting from "c:\aom\data\data.bar", you could try changing the output path to "c:\aom\data\extracted"). Click "Read data file" to perform the conversion (and wait a little while, especially for larger BARs).
  XMB/XML and DDT/BMP conversion: Click on "Direct file conversion", select an existing data file, agree that it'll be converted to some other format, then select a new filename for the resulting file.
There are many possible data formats for DDT images, and their differences are not yet fully understood; once you've converted a DDT to BMP you'll be told which format it uses and how many mip-map levels it includes, and it's best to stick to these values unless you know what you're doing. Only 24-bit uncompressed BMPs are understood as input. Conversion of paletted images is unbelievably slow and rubbish. The DXTC compression (used in all the non-paletted/greyscale formats) is not great, but it's adequate.

  To make use of altered files, simply copy them into the same place as the BAR from which they came (e.g. "flying purple hippo_anim.txt" from "c:\aom\anim\anim.bar" should be moved to "c:\aom\anim\flying purple hippo_anim.txt") so that they will be used by AOM instead of the ones inside the BAR. Also, AOM often looks for XMLs before XMBs, so it's not always necessary to convert them back into XMB.

  The program ought to work for all of AOM's BAR/XMB/DDT files - if it doesn't, please let me know.



General documentation
  The AOM Data File Converter converts AOM data files to/from other formats. The main part of the program can handle many different file types, converting to a text file (and often some additional text, graphic or other files). You specify an input file, and a place to store the output file(s), then press "Read data file" and it'll do the conversion. You can edit these files then use the "Write data file" section to create a new data file with your alterations. It's not particularly efficient or useful, but it works for most files.
  The second part performs direct conversions from one file into another. Click the button, choose an input file and an output file, and it should do the conversion.

  The Direct File Conversion can handle the following translations:
  XMB <-> XML
  DDT <-> BMP
  BRG --> 3DS

  The Read/Write Data File method is generally useful for the following files:
  *.bar
  *.scn
  materials.lib


  The actual implementation is completely different for both parts; the first uses a format definition file to decide how to read/write the data, which makes it much faster for me when adding new file formats. The second part is written directly into the code, giving much more flexibility in the output but only working one way and taking longer to program. Almost everything which can be converted directly is also usable through the normal method, but the output is often far from useful (look at the conversion of an XMB file for an example of this).



Trigger editing
  SCN files can be handled similarly to BARs through the Read/Write Data File method, creating several .dat files (which are mostly useless) and triggers.xml.
  Triggers.xml contains data about all the triggers in the scenario, converted into an XML format. XML is used throughout AOM; it is text-based, with a structure similar to HTML, and is generally readable to both humans and computers. It's best to edit the XML files in a plain text editor like Notepad; avoid Word since it often adds lots of formatting commands to what ought to be plain text. Like in HTML, be careful to write " as &quot;, < as &lt; and > as &gt; inside parameter text (e.g. <Effect Type="Message" Message="$$0$$Arkantos says &quot;Hello!&quot;">) to avoid confusing the XML reader.

  As an example of the structure of triggers.xml, the first couple of triggers from Tevious's King of Titans scenario look like:
<?xml version="1.0" encoding="UTF-8"?>

<Triggers Unknowns="33, 25">
  <Group Name="Ungrouped">
    <Trigger Name="_KOT_Intro_1" Priority="High" Loop="No" RunImmediately="Yes" Active="No">
      <Condition Type="Timer" Value="8"/>
      <Effect Type="Play Dialog" Sound="default" TriggerName="(none)" IgnoreEventOnAbort="False" Subtitle="$$0$$A King of Towers Scenario by Tevious" Portrait=""/>
      <Effect Type="Fire Event" TriggerName="_KOT_Intro_2"/>
    </Trigger>
    <Trigger Name="_KOT_Intro_2" Priority="High" Loop="No" RunImmediately="Yes" Active="No">
      <Condition Type="Timer" Value="8"/>
      <Effect Type="Play Dialog" Sound="default" TriggerName="(none)" IgnoreEventOnAbort="False" Subtitle="$$0$$K I N G  O F  T I T A N S" Portrait=""/>
      <Effect Type="Fire Event" TriggerName="_KOT_Intro_3"/>
    </Trigger>
  </Group>
</Triggers>
  All the XML files produced by AOMEd begin by stating that their contents are UTF-8 encoded (so you'll sometimes see funny characters in Notepad, most commonly where you have apostrophes in text). Everything else is contained within a single <Triggers> tag, with the Unknowns="..." storing currently-unknown numbers - it's probably best not to change them unless you have a good reason.
  There can be multiple Group tags; they simply provide a way to organise the triggers. Each group contains multiple Trigger tags, which each have several parameters: a Name, which should only contains letters, digits and underscores; a Priority, which can be one of Low, MedLow, Medium, MedHigh and High; and Loop, RunImmediately and Active which can be either Yes or No.
  The triggers then contain any number of Condition and Effect tags. Each has a Type parameter, and all the other parameters depend on the type of condition/effect. TriggerName parameters must be either the name of a trigger (which has to exist in the scenario) or (none). Some other parameters (such as Subtitle in the example above) contain text in the format $$number$$text - the number is an ID in language.dll so that the appropriate text can be found for the player's language. If you leave it as 0, the text after the second $$ will always be used instead.
  Fields such as SourceUnits (e.g. in <Effect Type="Flash Units" SourceUnits="1926;1927;1928;1929" Duration="5"/>) can often contain multiple values split by semicolons. Some fields are boolean values and should contain only True or False. To avoid conflicts with XML tags, Operator values are converted to Less, LessEqual, Equal, GreaterEqual and Greater.

  One of the main advantages of XML trigger editing over AOM's scenario editor is the ability to quickly copy-and-paste triggers. Multiplayer scenarios which have the same triggers for every player can be built much faster by creating the triggers for one player (most likely in AOM's scenario editor), then converting to XML and copying the data for every other player with a few modifications.
  King of Titans includes lots of triggers which can benefit from this:
  <Trigger Name="P1_G1_Minotaur" Priority="High" Loop="Yes" RunImmediately="Yes" Active="No">
    <Condition Type="Distance to Unit" SourceUnits="8" TargetUnit="1619" Operator="LessEqual" Distance="3"/>
    <Condition Type="Timer" Value="10"/>
    <Effect Type="Army Deploy" SourceArmy="1,10" ProtoName="Minotaur" Location="127.88, -2.14, 296.28" Count="1" Heading="130" ClearExistingUnits="False"/>
    <Effect Type="Change Unit Type" SourceUnits="14" ProtoUnit="Healing SFX"/>
  </Trigger>
  <Trigger Name="P1_G1_Cyclops" Priority="High" Loop="Yes" RunImmediately="Yes" Active="No">
    <Condition Type="Distance to Unit" SourceUnits="8" TargetUnit="1624" Operator="LessEqual" Distance="3"/>
    <Condition Type="Timer" Value="10"/>
    <Effect Type="Army Deploy" SourceArmy="1,10" ProtoName="Cyclops" Location="127.89, -2.14, 296.28" Count="1" Heading="130" ClearExistingUnits="False"/>
    <Effect Type="Change Unit Type" SourceUnits="1622" ProtoUnit="Healing SFX"/>
  </Trigger>
  <Trigger Name="P1_G1_Hoplite" Priority="High" Loop="Yes" RunImmediately="Yes" Active="No">
    <Condition Type="Distance to Unit" SourceUnits="8" TargetUnit="1625" Operator="LessEqual" Distance="3"/>
    <Condition Type="Timer" Value="3.5"/>
    <Effect Type="Army Deploy" SourceArmy="1,10" ProtoName="Hoplite" Location="127.90, -2.14, 296.29" Count="1" Heading="130" ClearExistingUnits="False"/>
    <Effect Type="Change Unit Type" SourceUnits="1623" ProtoUnit="Healing SFX"/>
  </Trigger>
repeated dozens of times per player, for every player. By copying XML code rather than creating every trigger in the game's scenario editor, it is possible to make repetitive triggers in much less time and with fewer errors.
  There are, however, several points which may cause problems. Because of these, the scenario will tend to be converted between SCN and XML fairly frequently since some changes can only be made in the game's editor. This shouldn't be too much of a problem, since AOMEd ought not to destroy any useful information (unless asked to, as described below) and the SCNs it generates should (hopefully) work perfectly in AOM's editor.
  Numerical unit IDs have little meaning - it is usually necessary to select the units in AOM's graphical editor after copying the triggers. This can be less of a problem if you create several units consecutively in the editor, since their IDs should also be consecutive and you only need to manually select the first in order to find its ID.
  A similar problem occurs with locations, where you have to specify X, Y and Z coordinates. AOM's editor is the only way to get correct numbers.
  You must also be careful to give each new trigger a unique name and, if the trigger is referenced by other triggers, to update all these references.
  There are also many more ways to mess things up, since no checks are made on the contents of parameters. Invalid unit IDs, ProtoUnit names, locations, etc, can all be entered, and will confuse AOM. However, this does allow you to do things which the game allows but the editor doesn't, such as changing PlayerID to 0 in order to apply any player-related trigger to Gaia.

  AOMEd also provides the ability to make scenarios 'uneditable', destroying all trigger, condition and effect names in order to make it much harder to edit the scenario. It's not guaranteed to stop any editing, but it should help to prevent people putting their names on others' scenarios and taking credit for it.   Simply add Uneditable="True" into the Triggers line of the XML (e.g. <Triggers Unknowns="33, 25" Uneditable="True">) and generate the SCN. Be careful to have a backup of the scenario, since there's no known way to recover the data from an uneditablised SCN file!



Miscellaneous information
  The program is written entirely in Perl, using Tk for the GUI, coming to a bit over four thousand lines. It's converted to an EXE with PerlApp (which includes a copy of the entire Perl interpreter, leading to rather large files). If you want to do something with the source code, hold down ctrl+alt+shift and quadruple-click on the main window. It'll create lots of files; read readme.txt for subsequent information.

  The program is freeware (although donations will be gratefully accepted, and go towards buying me a graphics card that can actually run AOM...) and you can do whatever you want with it (otherwise I'd have kept the source code hidden) if you keep some credits to me.

  For further information on most things mod-related, and to ask questions about this program, visit mods.dgdn.net.

  Many thanks go to Ensemble Studios for obvious reasons, to Enrique Orduno for giving me lots of stuff to do, and to Tevious for helping with the trigger XML.


Lots of things are trademarks of Microsoft. This program is not supported, endorsed by or associated with Microsoft or Ensemble Studios. Mostly copyright 2003 Philip Taylor.