DDL - Tkachov/ALERT GitHub Wiki
Insomniac's DDLParser | rivet's docs
Summary
Insomniac's "Data Description Language". Structures described are used to generate C++ code that can work with such structures, supporting reflection, versioning and serializing. rivet project descibes a way of dumping such structures from game's memory while it runs.
In a lot of assets' DAT1 sections, we encounter serialized data, somewhat like binary JSON. Based on type numbers matching types in that data, we can assume this data is produced by serialization of DDL structures. The fact that .config types can also be found within dumped structures (by name) supports this theory.
In ALERT and Overstrike, this serialized data is read in a generic way, without using types structures. This way seems to contradict what's described in DDLParser repo, because serialized data met in assets can be missing fields that are described in the dumped structure. Either described is a simplified example, or the way data is serialized has changed since. Because of that, DDL structures might not be really necessary in order to (de)serialize assets' data.
See also: SerializedSection
| Overstrike: SerializedSection.cs
Examples
DDL structures example from DDLParser repo:
select Weapon, author( "Andre de Leiradella" ), description( "Weapons available to the player" ), label( "Weapon" )
{
kFist, description( "Bare hands" ), label( "Fist" );
kChainsaw, description( "A la Chainsaw Massacre" ), label( "Chainsaw" );
kPistol, description( "Simple pistol" ), label( "Pistol" ), default;
kShotgun, description( "A single-barrel shotgun" ), label( "Shotgun" );
kChaingun, description( "A machine gun" ), label( "Chaingun" );
kRocketLauncher, description( "Portable rocket launcher" ), label( "Rocket launcher" );
kPlasmaGun, description( "Plasma gun" ), label( "Plasma gun" );
kBFG9000, description( "*The* BFG 9000" ), label( "BFG 9000" );
}
bitfield Powerup, author( "Andre de Leiradella" ), description( "Powerup pickups" ), label( "Powerup" )
{
kNone, description( "Help me!" ), empty;
kRadiationSuit, description( "Makes the player immune to radiation for a limited time" ), label( "Radiation suit" );
kPartialInvisibility, description( "Makes the player almost invisible to enemies for a limited time" ), label( "Partial invisibility" );
kInvulnerability, description( "Makes the player invulnerable for a limited time" ), label( "Invulnerability" );
kComputerMap, description( "Gives the complete map of the level to the player" ), label( "Computer map" );
kLightVisor, description( "Allows the player to see in the dark for a limited time" ), label( "Light visor" );
kBerserk, description( "Gives the player the ability to quickly kill enemies with his fists" ), label( "Berserk" );
kAll, value( kRadiationSuit | kPartialInvisibility | kInvulnerability | kComputerMap | kLightVisor | kBerserk );
}
struct Position
{
f32 m_X, value( 0 );
f32 m_Y, value( 0 );
f32 m_Angle, value( 0 ), description("The direction the player is looking at (degrees)");
}
struct Mariner, author( "Andre de Leiradella" ), description( "The player character" ), label( "Player" )
{
u32 m_Health, value( 100 ), description( "The player's health" );
Weapon m_Weapon, value( kPistol ), description( "The player's current weapon" );
Powerup m_Powerup, value( kBerserk ), description( "The player's powerups" );
i32[ 8 ] m_Ammunition, value( { 0, 0, 20, -1, -1, -1, -1, -1 } ), description( "The ammunition of each weapon, -1 means the player doesn't have it" );
string m_Name, value( "Mariner" ), description( "The player's name for multiplayer sessions" );
Position m_Position, value( { m_X = 100, m_Y = 120 } ), description( "The player's position" );
Position[] m_Deaths, description( "Places the player has died in" );
}
Dumped DDL structure for one of the types, taken from rivet's mm516_ddl_dump.json:
{
"allocation_size" : 48,
"fields" : [
{
"array_type" : 0,
"clamp_type" : "",
"default_value" : 1,
"description" : "",
"enum_id" : 0,
"id" : 3761771005,
"name" : "",
"offset" : 8,
"serialized_name" : "Description",
"tag_type" : 14,
"type" : 10,
"type_id" : 2808805880
},
{
"array_type" : 0,
"clamp_type" : "",
"default_value" : 0,
"description" : "AUtomatically make each item reqiure the previous one",
"enum_id" : 0,
"id" : 2885068954,
"name" : "",
"offset" : 24,
"serialized_name" : "DependentChain",
"tag_type" : 14,
"type" : 15,
"type_id" : 1154667212
},
{
"array_type" : 2,
"clamp_type" : "",
"default_value" : 0,
"description" : "",
"enum_id" : 0,
"id" : 1179903049,
"name" : "",
"offset" : 32,
"serialized_name" : "TechWebItems",
"tag_type" : 14,
"type" : 13,
"type_id" : 821858917
}
],
"function_id" : 0,
"name" : "TechWebList",
"parent_id" : 0,
"type_id" : 1636429274
}