Skip to content

Instantly share code, notes, and snippets.

@ericoporto

ericoporto/README.md

Last active Jul 3, 2020
Embed
What would you like to do?
Building an AGS game

Building an AGS game

Ideally, while the project files holds the game information in the form that is the most convenient by the Editor used by the game developer, the game data represents this information in the most convenient form for the Engine.

Building a game is to transform information that describes the game to the form convenient for the Engine. This document describes how a platform agnostic AGS game is built.

At the time of writing, some relevant information is in different source code files, mainly:

  • Editor/AGS.Editor/BuildTargets/BuildTargetDataFile.cs
  • Editor/AGS.Editor/DataFileWriter.cs
  • Engine/main/game_file.cpp
  • Common/game/main_game_file.cpp
  • Common/ac/gamesetupstruct.cpp

What is an AGS game ?

Many people know an AGS game as simply the following:

game.exe
audio.vox #optional

This game executable is roughly (but not exactly!) the same as:

acwin.exe
game.ags
audio.vox #optional

Where acwin.exe is the engine and game.ags is the game, and audio.vox is the speech assets that may or may not be there.

To make it easier in this document, we are going to ignore platform specifics in the engine and consider only the data file game.ags and external assets like audio.vox. So in this document, when we talk about an AGS game, this is what is on mind.


Stream and MultiFileLib

A stream is a sequence of bytes with a beginning and an end, where the beginning and end may or may not match the beginning and end of a file. We can define an order in which bytes are stored, an assign meaning to ordered groups of ordered bytes to serialize or deserialize information.

[[0 1 [2 3] 4] 5 6 7]

if we consider 0-7 above as each a byte, we can consider any opening and closing bracket as a stream

A stream can then be defined in this way as holding:

  • Offset, the position where the stream starts in a group of sequential bytes
  • Length, which tells us the end of the stream
  • Byte array, the actual bytes in the stream

MultiFileLib is a library that is replicated in both DataFileWriter on the Editor, and on the Common library in the Engine, that enables assigning meaning to a group of bytes in a file as a stream with the following information:

  • Filename, used to identify the group of bytes;
  • Offset, the location of this stream in the biggest possible stream of the file.
  • Length, the byte size of this stream;
  • Datafile, the bytes of this stream;

We can use MultiFileLib to abstract the contents of the game.ags file in a streamed filesystem (note: if there's a proper name here, please some fix this).

We can assume a file in the regular filesystem with name "name.extension" holds the same "name.extension" and same bytes in it's resulting stream in the streamed filesystem. Because of this, I am not going to make a distinction from the filesystem and streamed filesystem, unless required to reinforce a point.


Assets and Logic

In the streamed filesystem that the AGS Engine reads to run a game, it can find files that define logic to run or logic states and also asset files, which do not define logic by itself, mostly image and sound files.

  • Initial state of game objects
  • Initial state of game rooms
  • Bytecode to run in the script engine
  • Metadata for the script engine
  • Game sprites
  • Game audio
  • ...

Logic files and asset files have no difference between themselves that are not specifics on how their bytes should be interpreted, so they can all be considered files in the streamed filesystem.

I am going to arbitrarily assign a category as Asset or Logic to group files read by the engine here. We can assume that there are no audio, image (including font files) mixed in the logic files, and that there are only references there, unless otherwise noted.

Logic

game28.dta

The Game DTA file, named currently as game28.dta, has most of the logic information required for an AGS game. The following is included in order, with examples or comments:

  • Game Metadata
    • Game file signature, "Adventure Creator Game File v2"
    • Game data version, integer identifier of this data format
    • AGS Editor version, "3.5.0.24"
  • Game options and initial setup data
    • AGS Game options (mostly configured in Global Settings)
    • AGS game variable
  • Initialize GUI IDs
  • Additional game settings
    • Save game extension
    • Seve game directory
  • AGS Font configuration (not the actual font)
  • Sprite alpha channel setting (for each sprite)
  • Inventory Item information
    • Number of items
    • Data: Description, ID of Image, ID of CursorImage, Hotspot, ...
  • Cursors information
    • Number of Cursors
    • Data: ID of Image, Hotspot, ...
  • Compiled scripts (bytecode and metadata)
    • Global script
    • Dialog scripts
    • Other scripts
  • View information
    • Number of views
    • Loop information per loop, frame information per frame
  • Characters information
    • Number of Characters
    • All information required for a character (it's a lot!)
  • GUI information
    • Number of GUIs
    • All information related to each GUI control per GUI and required to initialize each GUI
  • Plugin related information
  • Custom properties information
    • Custom properties for Characters
    • Custom properties for Inventory Items
  • Dialog names
  • AudioClip Type information
    • Number of AudioClip Types
    • Data: AudioClip Type max channel, cross fade configuration, ...
  • AudioClip information
    • Number of AudioClips
    • AudioClip metadata

Room .crm files

Room .crm files are stored as room*.crm files directly, and they include the compiled rooms script objects.

Assets

Sprites

All sprites are stored contiguously in a file and it's index is stored in separate file.

  • sprindex.dat, the sprite index file
    • it holds the sprite IDs and the byte offset of each sprite in the the sprite data file and their length in bytes.
  • acsprset.spr, the actual sprite data
    • sprites are stored contiguously as bitmaps.

Audio

Audio files are stored with the same names used in the AudioCache directory, and they can also optionally be stored outside the game.ags in a audio.vox file.

Fonts

Fonts are stored as agsfnt*.ttf or agsfnt*.wfn depending of the original format of the font, with the names including a number index that will be corresponded to the index of the font metadata stored in the Game DTA file.

Other assets

Additionally, an AGS game data holds video files in flic.fl? and *.ogv, and a loading image for the game boot as preload.pcx.


AGS Project files

The project files can be changed with less regard to form, as long as the tool used to build the game (the AGS Editor) accommodates this change and still outputs the files compatible with the Engine. This is why the project file and Editor versions are different than the game dta versions, allowing easier management of changes.


The build steps

Generate the AudioCache

This step simply copies the audio files from their original sources to a flat directory named AudioCache/ at the root of the project.

< input

List of audio files with any name and supported extensions and ID to use per file, and the audio files.

> output

The audio files in a flat directory with names as au0X.Y, where X is the original audio ID as hexadecimal with fixed 6 digits in size and Y being the original file extension.


Generate the Sprite data and index

< input

> output


Update room crm files

< input

> output


Generate Dialog Scripts from Dialogs

< input

All game dialogs.

> output

Script files


Preprocess Script file

< input

*.asc
*.ash
scipt files generated from dialogs

> output


Generate script objects

Compiles preprocessed Script files to script objects

< input

> output


Generate the game DTA file

< input

All script objects and data to initialize and describe all game objects and options

> output

game28.dta


Pack files to DataFile

This step receives a list of files and packs the files listed in the game DataFile, using the MultiFileLib.

< input

game28.dta        # game DTA file
room*.crm         # at least one room is required
sprindex.dat  
acsprset.spr
au0*.*            # optionally, for audio files, may be stored outside in a .vox file
agsfnt*.(ttf|wfn) # font files, may or may not exist, at least one font file is required.
preload.pcx       # optionally
flic.fl?          # optionally, for videos
*.ogv             # optionally, for videos

> output

game.ags

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.