Skip to content

Structs Type Reference

The structs data type is the nested dictionary format that gives the Unturned™ .dat file system its expressive power. While simple key-value pairs handle flat configurations, structs allow modders to author deeply nested, multi-level configurations: a blueprint recipe with a list of input items that each carry their own ID, amount, and deletion flag; a player spotlight configuration with range, angle, intensity, and colour; a vehicle engine definition with horsepower, fuel capacity, and gear ratios; a gun attachment hook specification with offset and rotation. Every complex, multi-property configuration block in the .dat system is a struct or an array of structs.

57 Studios™ has documented and validated the full struct format specification as defined in the official Smartly Dressed Games modding documentation and as observed in shipped Unturned™ game files. This article covers the curly-brace dictionary syntax, the struct nesting rules, the mapping between .dat structs and their C# class counterparts in the parser, the common struct patterns that recur across asset types (Blueprints, InputItems, Engine, Wheel, Sight, Muzzle, Turret, PlayerSpotLightConfig), and worked examples drawn from the SDG documentation and shipped game files.

The struct type is the most syntactically complex data type in the .dat system and the most powerful. A modder who understands struct nesting can author a blueprint tree for a complete crafting chain with multiple input items, output items, skill requirements, and crafting station tags, all expressed as a single nested block of curly-brace-delimited key-value groups. A modder who does not understand struct nesting will attempt to express the same information as flat fields and will find that the parser ignores values it cannot map to the expected struct schema.

Nested struct diagram showing a Blueprints array with multiple recipe structs, each containing InputItems arrays and OutputItems fields

Documentation source: This article references the official Smartly Dressed Games modding documentation for struct field definitions and game behaviour. The PlayerSpotLightConfig struct definition is drawn directly from the official SDG data types documentation. Community-validated notes are marked where the official documentation is silent on a detail.

Who this article is for

This article is written for Unturned™ mod authors who have completed at least one item mod and are encountering nested struct configurations for the first time -- a Blueprints array on a gun .dat, a PlayerSpotLightConfig struct on a helmet .dat, an Engine struct on a vehicle .dat. Modders who have only authored flat .dat files (simple key-value pairs without curly braces) should read this article in full before attempting to author a file that contains structs or arrays of structs.

If you are new to Unturned™ modding, start with Project Folder Structure and GUIDs and Item Asset Anatomy before returning here. The struct format extends the flat key-value format documented in those articles with nesting and array syntax. Familiarity with the base .dat syntax is assumed.

What you'll learn

  • The struct syntax: curly-brace-delimited key-value groups and their placement rules
  • How structs appear inside array contexts ([ ... ]) and the relationship between arrays and structs
  • Struct nesting rules: structs within structs, structs within arrays, arrays within structs
  • How .dat structs map to C# classes and structs in the Unturned™ parser
  • The PlayerSpotLightConfig struct as documented in the official SDG documentation
  • The Blueprints struct pattern as observed in shipped gun .dat files
  • The InputItems and OutputItems struct patterns within blueprint recipes
  • Worked examples for every common struct pattern: item blueprints, vehicle engines, gun attachment hooks
  • Common mistakes that cause struct blocks to parse incorrectly or fail silently
  • The diagnostic table for struct format errors

Background: what the struct data type is

The struct data type in Unturned™ is a parser-level type that represents a compound value -- a collection of named sub-fields enclosed in curly braces and optionally placed inside square-bracket-delimited arrays. It is the mechanism by which the .dat format supports nested, multi-level configuration. Where a flat key-value pair defines a single scalar property (ID 50001), a struct defines a compound property with multiple sub-properties ({ ID "abc123" Amount 3 Delete false }).

The struct type maps directly to C# classes and structs in the Unturned™ parser. When the parser encounters a struct block in a .dat file, it constructs an instance of the corresponding C# type, populates its properties from the key-value pairs inside the curly braces, and assigns the instance to the parent field. This mapping is type-safe: the parser knows which fields each struct type expects and validates the presence and format of those fields against the C# type definition. A key that does not correspond to a property on the target C# type is either ignored or produces a parse warning, depending on the game version and the strictness of the specific struct type's parser.

Structs are most commonly encountered in two syntactic contexts:

  1. As the value of a named field, where the struct's opening brace { appears on the line following the field name. This is the pattern used by PlayerSpotLightConfig and similar standalone structs.

  2. As elements of an array, where the structs are enclosed in square brackets [ ... ] and each struct element is a separate { ... } block. This is the pattern used by Blueprints (an array of recipe structs), InputItems (an array of input item structs), and similar list-based configurations.

The square brackets [ and ] denote an array context. The curly braces { and } denote a struct (object) context. The two are distinct syntactic constructs: brackets group multiple elements into a list; braces define the properties of a single element. Recognizing this distinction is the first step to reading and authoring struct-based .dat files.

The flowchart above shows the parser's resolution path when it encounters a struct or array value. The [ character triggers array parsing, which in turn triggers struct parsing for each element inside the array. The { character triggers standalone struct parsing. A value that begins with neither [ nor { is treated as a scalar (integer, float, string, enum, flag, colour, Vector3, or GUID).

The struct syntax

Basic struct block

The basic struct block is a curly-brace-delimited group of key-value pairs:

{
  Key1 value1
  Key2 value2
  Key3 value3
}

The opening brace { must be the first non-whitespace character after the field name (or on the line immediately following the field name, which is the more common convention). The key-value pairs inside the struct follow the same Key Value syntax as top-level .dat fields. Each pair occupies its own line. The closing brace } appears on its own line.

The keys inside a struct are field names on the C# type that the struct maps to. They follow the same naming conventions as top-level fields: PascalCase or snake_case depending on the specific C# type, with underscores where the original C# property name uses them. The parser maps each key to the corresponding C# property by name, and the casing must match the C# property exactly for the parser to recognize the key.

Struct as a standalone field value

When a struct is the value of a named field at the top level of a .dat file, the opening brace appears on the line following the field name:

SpotLight_Enabled true
SpotLight_Range 64
SpotLight_Angle 90
SpotLight_Intensity 1.3
SpotLight_Color #f5df93

Alternatively, when a struct field is a named sub-field of a parent struct (as in PlayerSpotLightConfig), the individual properties are written at the same indentation level as the parent struct's other fields. The parser does not enforce indentation -- the relationship between a parent struct and its child fields is determined by the C# type hierarchy, not by whitespace. The convention of writing child properties at the same indentation level as the parent's opening and closing braces is for human readability only.

Structs inside arrays

The array syntax encloses one or more struct elements in square brackets:

Blueprints
[
  {
    Name Repair
    CategoryTag "732ee6ffeb18418985cf4f9fde33dd11"
    Operation RepairTargetItem
    InputItems
    [
      {
        ID "21ede8ebffb14c5580e8c7ad149e335e"
        Amount 3
      }
      {
        ID "5830b84bf8074caa91cf3f4dde0dd19e"
        Delete false
      }
    ]
    Skill Repair
    Skill_Level 2
    RequiresNearbyCraftingTags
    [
      "7b82c125a5a54984b8bb26576b59e977"
    ]
    Effect "84347b13028340b8976033c08675d458"
  }
  {
    Name Salvage
    CategoryTag "7ed29f9101ae4523a3b2e389414b7bd9"
    InputItems this
    OutputItems "21ede8ebffb14c5580e8c7ad149e335e x 2"
    Effect "84347b13028340b8976033c08675d458"
  }
]

This example, drawn directly from the shipped Eaglefire.dat, shows the complete range of struct syntax features:

  • A top-level field Blueprints whose value is an array [ ... ]
  • Two struct elements inside the array: Repair and Salvage
  • Each struct element contains scalar fields (Name, CategoryTag, Operation, Skill, Skill_Level, Effect)
  • The InputItems field inside each recipe struct is itself an array containing sub-structs
  • Each input item sub-struct contains an ID field, an Amount field, and optionally a Delete flag
  • The RequiresNearbyCraftingTags field is an array of string values (not structs -- a plain array of GUID strings)
  • The OutputItems field on the Salvage recipe is a single string value ("ID x Amount" format)

This nesting pattern -- array of structs, where each struct contains fields that may themselves be arrays of sub-structs -- recurs throughout the Unturned™ asset system. The blueprint system is the most common and most deeply nested example, but the same pattern appears in vehicle engine configurations, turret definitions, attachment hook specifications, and loot table entries.

Struct nesting rules

The parser enforces a strict parent-child relationship between struct types. A struct field can only appear inside the struct type that declares it. The Skill field, for example, is a property of the Blueprint struct type (the C# class Blueprint), not a top-level field. Writing Skill Craft at the top level of a .dat file will be ignored because the parser does not recognize Skill as a top-level field on any asset type. Writing it inside a Blueprints array element places it in the correct C# context (Blueprint.Skill) and the parser will recognize and store it.

The nesting rules can be summarized as follows:

ContextAllowed field typesDisallowed field types
Top-level .dat fileAsset-level fields (ID, GUID, Type, Name, Rarity, etc.)Struct-specific fields (Skill, Amount, Operation, etc.)
Inside a Blueprints array elementBlueprint struct fields (Name, CategoryTag, Operation, InputItems, OutputItems, Skill, Skill_Level, Effect, RequiresNearbyCraftingTags)Top-level asset fields cannot be the immediate child of a blueprint (but are accessible as context from the parent asset)
Inside an InputItems array elementBlueprintInput struct fields (ID, Amount, Delete)Any other struct's fields
Inside a RequiresNearbyCraftingTags arrayString values only (GUID strings)Structs cannot appear inside a string array

The parser does not validate nesting correctness with detailed error messages. A field written in the wrong context is typically silently ignored -- the parser does not recognize it as a property on the expected C# type and skips it. The result is a struct that parses successfully but does not contain the expected sub-property, producing runtime behaviour that differs from the modder's intention. This silent-failure characteristic is the single biggest source of struct authoring bugs. The diagnostic table later in this article documents the symptoms and resolutions for common nesting errors.

Mapping: how .dat structs map to C# types

Every struct in the .dat system corresponds to a C# class or struct defined in the Unturned™ game assembly. The mapping is name-based: the parser reads the key names inside the curly braces and matches them to public properties on the C# type. The type that the parser expects is determined by the parent context -- the field name and its parent struct type together identify the target C# type.

The following table documents the known struct-to-C# mappings for the common struct patterns encountered in mod authoring:

.dat struct contextC# type (approximate)Key properties
Blueprints array elementBlueprintName, CategoryTag, Operation, InputItems, OutputItems, Skill, Skill_Level, Effect, RequiresNearbyCraftingTags, Tooltipped, Link, ID
InputItems array elementBlueprintInputID, Amount, Delete
RequiresNearbyCraftingTags array elementstring (GUID), (scalar string value)
PlayerSpotLightConfig (embedded in item)PlayerSpotLightConfigSpotLight_Enabled, SpotLight_Range, SpotLight_Angle, SpotLight_Intensity, SpotLight_Color
Vehicle engine structEngineAsset or similarengine-specific fields
Vehicle wheel structWheelAsset or similarwheel-specific fields
Gun attachment hook struct (Sight, Muzzle, Grip, Barrel, Tactical, Magazine)attachment reference by IDinteger ID reference
Gun attachment hook list (e.g., Hook_Sight, Hook_Tactical)flag listbare flag strings

The C# type names listed above are approximations based on the observed field vocabulary in shipped .dat files and the official SDG documentation. The exact C# type names and their namespace paths are defined in the Unturned™ game assembly and are not directly relevant to .dat file authoring -- the modder only needs to know the valid field names within each struct context, not the C# class hierarchy that defines them.

Attachment hook structs on gun assets

On gun assets, attachment configuration uses two distinct struct patterns:

  1. Required attachment IDs: Fields like Sight 5, Magazine 6, Barrel 354, and Muzzle 3 specify the default attachment item ID that the gun spawns with. These are integer fields (the attachment's item ID), not struct blocks. They are not enclosed in braces or brackets.

  2. Optional attachment hooks: Fields like Hook_Sight, Hook_Tactical, Hook_Grip, and Hook_Barrel are bare flag fields (no value, just the field name on its own line) that declare which attachment slots the gun accepts. These are not struct blocks either -- they are simple flag declarations.

Despite the attachment hook system not using curly-brace struct syntax in the current game version, modders often expect them to be structs (because an attachment hook conceptually "has properties" such as the attachment's position on the gun model). In the current Unturned™ asset system, attachment positioning is handled by skeleton bones in the Unity prefab (the Hook_Sight bone, the Hook_Muzzle bone), not by .dat struct configuration. The .dat file only declares which attachment hooks exist and which default attachment IDs populate them. The spatial positioning of the attachment is a Unity prefab concern, not a .dat concern.

PlayerSpotLightConfig struct

The PlayerSpotLightConfig struct is the best-documented struct in the official SDG documentation and serves as the canonical example of the standalone struct format. It is embedded in certain item assets (helmets, headwear) and defines the properties of a toggleable player-controlled light source.

The struct contains five properties, each documented with its type, default value, and purpose in the official SDG documentation:

PropertyTypeDefault valuePurpose
SpotLight_EnabledbooltrueWhen true, this item has a toggleable light source.
SpotLight_Rangefloat3264Range of the light source's beam, measured in meters.
SpotLight_Anglefloat3290Angle of the light source's beam, measured in degrees.
SpotLight_Intensityfloat321.3Intensity of the light source's beam.
SpotLight_Colorcolor#f5df93Colour of the light source's beam. Accepts all three valid colour representations (hex, named, dictionary).

In a .dat file, the PlayerSpotLightConfig struct is typically embedded at the top level of an item's asset definition. The struct properties are written as key-value pairs at the top level of the file, not enclosed in a named curly-brace block -- the parser recognizes them by their field name prefix (SpotLight_) and maps them to the PlayerSpotLightConfig C# type automatically.

A complete worked example of a helmet with a player spotlight:

ID 50200
GUID a1b2c3d4e5f64a7b8c9d0e1f2a3b4c5d
Type Hat
Name TacticalHelmet
Rarity Rare
Slot Head
Size_X 2
Size_Y 2

SpotLight_Enabled true
SpotLight_Range 48
SpotLight_Angle 75
SpotLight_Intensity 1.0
SpotLight_Color #ffffff

The spotlight properties are authored alongside the standard item identity fields. The parser recognizes SpotLight_Enabled through SpotLight_Color as belonging to the PlayerSpotLightConfig struct that is embedded in the hat item type. The modder does not need to wrap them in a named struct block -- the prefix convention (SpotLight_) is sufficient for the parser to route them to the correct C# type.

The state diagram above shows the two states of a PlayerSpotLightConfig-equipped item: the light is toggled on and off by the player at runtime. The SpotLight_Enabled field in the .dat controls whether the toggle key is available at all; if SpotLight_Enabled false, the item cannot toggle a light source regardless of the other spotlight properties.

Blueprints struct pattern in detail

The Blueprints array is the most commonly encountered struct pattern in mod authoring and the most structurally complex. Every vanilla gun and melee weapon carries a Blueprints array defining at minimum two recipes: Repair (to restore durability using scrap metal and a blowtorch) and Salvage (to break the item down into its constituent materials).

The Blueprints array uses the following nesting structure:

Blueprints            ← Array of Blueprint structs
[                     ← Open array bracket
  {                   ← Open first Blueprint struct
    Name Repair       ← Blueprint.Name (string)
    CategoryTag "..." ← Blueprint.CategoryTag (GUID string)
    Operation ...     ← Blueprint.Operation (enum: RepairTargetItem, etc.)
    InputItems        ← Blueprint.InputItems (array of BlueprintInput structs)
    [                 ← Open InputItems array
      {               ← Open first BlueprintInput struct
        ID "..."      ← BlueprintInput.ID (GUID string)
        Amount 3      ← BlueprintInput.Amount (int)
      }
      {               ← Open second BlueprintInput struct
        ID "..."      ← BlueprintInput.ID (GUID string)
        Delete false  ← BlueprintInput.Delete (bool)
      }
    ]                 ← Close InputItems array
    Skill Repair      ← Blueprint.Skill (enum, optional)
    Skill_Level 2     ← Blueprint.Skill_Level (int, optional)
    RequiresNearbyCraftingTags
    [                 ← Open RequiresNearbyCraftingTags array (of strings)
      "7b82c12..."    ← GUID string
    ]
    Effect "84347..." ← Blueprint.Effect (GUID string)
  }                   ← Close first Blueprint struct
  {                   ← Open second Blueprint struct
    Name Salvage
    CategoryTag "7ed29..."
    InputItems this   ← Special keyword: "this" means the parent item itself
    OutputItems "21ede8ebffb..." ← Output string in "GUID x Amount" format
    Effect "84347..."
  }
]                     ← Close Blueprints array

The nesting level reaches three deep: Blueprints (array) → Blueprint struct → InputItems (array) → BlueprintInput struct. This is the maximum nesting depth encountered in standard asset .dat files; deeper nesting is theoretically supported by the parser but is not used by any vanilla asset type.

Blueprint struct field reference

FieldTypeRequiredPurpose
NamestringYesThe display name of the blueprint. Appears in the crafting UI.
CategoryTagGUID stringYesThe crafting category this blueprint belongs to. References a category defined elsewhere in the game data.
OperationenumYesThe type of crafting operation. Known values: RepairTargetItem, Salvage. Additional operations exist for crafting new items.
InputItemsarray of BlueprintInput structs or this keywordYesThe items consumed by this blueprint. Can be an array of BlueprintInput structs or the special keyword this (meaning the item the blueprint is attached to).
OutputItemsstring or arrayVariesThe items produced by this blueprint. Format is typically "GUID x Amount" for a single output or an array for multiple outputs. Salvage blueprints use this field.
SkillenumNoThe skill associated with this blueprint. Known values: Repair, Craft.
Skill_LevelintNoThe skill level required to use this blueprint. 1 is the minimum.
RequiresNearbyCraftingTagsarray of GUID stringsNoAn array of crafting station GUIDs that must be nearby for this blueprint to be available. Example: workbench, furnace.
EffectGUID stringNoThe crafting effect (sound/visual) played when the blueprint completes. References a GUID defined elsewhere.
TooltippedboolNoWhether this blueprint shows a tooltip in the crafting UI.
LinkstringNoA URL or internal identifier for linking to external documentation.
IDuint16NoA numeric identifier for the blueprint (alternative to the string Name).
DeleteboolNo (on BlueprintInput)If false, the input item is not consumed. Typically used for tools (blowtorch, wrench) that persist through multiple crafting operations.

BlueprintInput struct field reference

FieldTypeRequiredPurpose
IDGUID stringYesThe GUID of the input item.
AmountintNoThe quantity of the input item consumed. Defaults to 1 if omitted.
DeleteboolNoIf false, the input item is returned after the blueprint completes. Defaults to true (item is consumed). Used for persistent tools.

Vehicle struct patterns

Vehicle assets in Unturned™ use struct blocks to define sub-components such as engines, wheels, turrets, and seats. While the exact field vocabulary varies by vehicle type (car, truck, helicopter, boat, aircraft), the struct syntax follows the same curly-brace pattern as blueprints.

Engine struct

A vehicle engine struct defines the performance characteristics of the vehicle's propulsion system. The following is a representative engine struct pattern observed in shipped vehicle files:

Engine
{
  Horsepower 250
  Fuel 7500
  Fuel_Burn_Rate 1.5
  Gear_1 0.5
  Gear_2 0.8
  Gear_3 1.2
  Gear_4 1.8
  Reverse_Gear -0.5
}

The engine struct is a standalone struct attached to the vehicle asset. It is not inside an array -- a vehicle has exactly one engine. The key-value pairs inside the struct define the engine's performance profile.

Engine fieldTypePurpose
Horsepowerfloat32Engine power output; determines acceleration and top speed
Fueluint16Maximum fuel capacity in arbitrary units
Fuel_Burn_Ratefloat32Fuel consumed per unit time at full throttle
Gear_1 through Gear_Nfloat32Gear ratios for forward gears. Number of forward gears is determined by how many Gear_N fields are present.
Reverse_Gearfloat32Gear ratio for reverse. Usually negative to produce backward motion.

Wheel struct

Vehicles with configurable wheel properties may define individual wheel structs:

Wheel_0
{
  Position -1.2, -0.3, 1.5
  Suspension_Length 0.3
  Has_Power true
  Has_Steering true
}
Wheel_1
{
  Position 1.2, -0.3, 1.5
  Suspension_Length 0.3
  Has_Power true
  Has_Steering true
}

The wheel struct uses the Position field (a Vector3) to locate the wheel relative to the vehicle's pivot, the Suspension_Length field to control the suspension travel distance, and the Has_Power and Has_Steering boolean flags to control which wheels are driven and which turn. A front-wheel-drive vehicle sets Has_Power false on the rear wheels. A rear-wheel-drive vehicle sets Has_Power false on the front wheels. An all-wheel-drive vehicle sets Has_Power true on all wheels.

Turret struct

Vehicles with mounted weapons (technical trucks, armored cars, helicopters) define turret structs for each weapon position:

Turret_0
{
  Position 0, 0.8, 1.5
  Gun_ID 132
  Yaw_Min -90
  Yaw_Max 90
  Pitch_Min -15
  Pitch_Max 45
}
Turret fieldTypePurpose
PositionVector3Position of the turret mounting point relative to the vehicle pivot
Gun_IDuint16The item ID of the gun mounted on this turret
Yaw_Minfloat32Minimum horizontal rotation angle in degrees (negative = left)
Yaw_Maxfloat32Maximum horizontal rotation angle in degrees (positive = right)
Pitch_Minfloat32Minimum vertical rotation angle in degrees (negative = down)
Pitch_Maxfloat32Maximum vertical rotation angle in degrees (positive = up)

A vehicle can have multiple turrets, differentiated by the numeric suffix (Turret_0, Turret_1, etc.). Each turret struct follows the same field vocabulary.

Worked examples

Example 1: PlayerSpotLightConfig from the official SDG documentation

The official SDG documentation defines the PlayerSpotLightConfig struct with these default values:

SpotLight_Enabled true
SpotLight_Range 64
SpotLight_Angle 90
SpotLight_Intensity 1.3
SpotLight_Color #f5df93

This is the simplest struct pattern: a set of related fields that all share a common prefix (SpotLight_) and are embedded at the top level of an item's .dat file. The parser recognizes the fields by their names and maps them to the PlayerSpotLightConfig C# struct on the item asset.

Example 2: Repair and Salvage blueprints from shipped Eaglefire.dat

The shipped Eaglefire.dat contains the following Blueprints array (abbreviated for clarity):

Blueprints
[
  {
    Name Repair
    CategoryTag "732ee6ffeb18418985cf4f9fde33dd11"
    Operation RepairTargetItem
    InputItems
    [
      {
        ID "21ede8ebffb14c5580e8c7ad149e335e"
        Amount 4
      }
      {
        ID "5830b84bf8074caa91cf3f4dde0dd19e"
        Delete false
      }
    ]
    Skill Repair
    Skill_Level 2
    RequiresNearbyCraftingTags
    [
      "7b82c125a5a54984b8bb26576b59e977"
    ]
    Effect "84347b13028340b8976033c08675d458"
  }
  {
    Name Salvage
    CategoryTag "7ed29f9101ae4523a3b2e389414b7bd9"
    InputItems this
    OutputItems "21ede8ebffb14c5580e8c7ad149e335e x 3"
    Effect "84347b13028340b8976033c08675d458"
  }
]

This example demonstrates:

  • An array of two structs (Repair and Salvage)
  • Nested arrays inside structs (InputItems is an array inside each blueprint struct)
  • Nested structs inside nested arrays (each BlueprintInput inside InputItems is a struct)
  • The this keyword as a shorthand for "the parent item this blueprint is attached to"
  • The Delete false flag on the blowtorch input, meaning the blowtorch is not consumed during repair
  • The OutputItems string format ("GUID x Amount") on the Salvage recipe
  • The Skill Repair and Skill_Level 2 fields restricting the Repair blueprint to players with at least Repair skill level 2
  • The RequiresNearbyCraftingTags array restricting the Repair blueprint to locations near a workbench

Example 3: Multi-input recipe with tool persistence

A custom blueprint for crafting a new item that requires multiple ingredients and a persistent tool:

Blueprints
[
  {
    Name CraftMyCustomGun
    CategoryTag "ad1804b6945145f3b308738b0b8ea447"
    Operation Craft
    InputItems
    [
      {
        ID "21ede8ebffb14c5580e8c7ad149e335e"
        Amount 8
      }
      {
        ID "9c563bf14d4641a18873f338beaed128"
        Amount 5
      }
      {
        ID "5830b84bf8074caa91cf3f4dde0dd19e"
        Delete false
      }
    ]
    OutputItems
    [
      {
        ID "a1b2c3d4e5f64a7b8c9d0e1f2a3b4c5d"
        Amount 1
      }
    ]
    Skill Craft
    Skill_Level 3
    RequiresNearbyCraftingTags
    [
      "7b82c125a5a54984b8bb26576b59e977"
    ]
    Effect "84347b13028340b8976033c08675d458"
  }
]

This example demonstrates a recipe with three input items (scrap metal, sticks, and a blowtorch tool), one output item (the crafted gun), and a skill requirement (Craft level 3). The blowtorch has Delete false so it persists through the crafting operation.

Example 4: OutputItems as a struct array

When a recipe produces multiple output items, OutputItems can be written as an array of BlueprintOutput structs (following the same pattern as InputItems):

OutputItems
[
  {
    ID "21ede8ebffb14c5580e8c7ad149e335e"
    Amount 2
  }
  {
    ID "e73a23b102f24520a32ec0b2afaa6157"
    Amount 1
  }
]

The BlueprintOutput struct uses the same ID and Amount fields as BlueprintInput. This is observed in some shipped gun files (e.g., Card.dat) that produce multiple salvage materials.

Example 5: Vehicle engine struct

A representative engine struct for a car vehicle:

Engine
{
  Horsepower 300
  Fuel 10000
  Fuel_Burn_Rate 1.0
  Gear_1 0.5
  Gear_2 0.8
  Gear_3 1.2
  Gear_4 1.5
  Gear_5 2.0
  Reverse_Gear -0.5
}

This engine has 300 horsepower, a fuel capacity of 10,000 units, a moderate fuel burn rate, five forward gears, and one reverse gear.

Comparison: scalar values versus arrays versus structs

Value typeSyntaxExampleUse case
Scalar (integer)Field <int>ID 50001Single-value fields
Scalar (string)Field <string>Name MyItemString identifiers
Scalar (GUID string)Field "<hex>"GUID "a1b2..."Globally unique identifiers
FlagField (bare)TwoHandedBoolean on/off states
Array of scalarsField [ val1 val2 ]Bursts [ 3 5 ]Multi-element lists of the same type
Array of stringsField [ "str1" "str2" ]RequiresNearbyCraftingTags [ "abc" "def" ]Lists of GUID strings
Array of structsField [ { k v } { k v } ]Blueprints [ { Name A } { Name B } ]Multi-element lists of compound objects
Standalone struct{ k1 v1 k2 v2 }Engine { Horsepower 300 Fuel 10000 }Compound objects (not in an array)
Embedded struct (prefix convention)Prefix_Field valueSpotLight_Range 64Compound objects identified by field name prefix

Frequently asked questions

What is the difference between square brackets and curly braces?

Square brackets [ and ] denote an array -- an ordered list of elements. Curly braces { and } denote a struct -- a single compound object with named properties. Arrays contain multiple elements; structs define a single element. In the blueprint system, Blueprints is an array (it can contain multiple recipes), and each { Name Repair ... } block inside the array is a struct (a single recipe). The InputItems field inside a recipe is itself an array, and each { ID "..." Amount 3 } block inside that array is a struct (a single input item).

Can I indent struct content for readability?

Yes. The parser ignores whitespace including indentation. The struct nesting structure is determined by the sequence of [, ], {, and } characters, not by indentation. Modders are encouraged to indent struct content for human readability using the conventions shown in this article. The parser does not enforce or require any particular indentation style.

What happens if I write a struct field at the wrong nesting level?

The field is silently ignored. The parser looks for the specified key on the expected C# type at that nesting level. If the key does not exist on that type, the parser skips it without producing an error. A Skill field written at the top level of a .dat file (outside a Blueprints array element) will be silently ignored because the top-level asset type does not have a Skill property. A SpotLight_Range field written inside a blueprint struct will be silently ignored because the Blueprint type does not have a SpotLight_Range property.

How do I know which fields belong to which struct?

The field vocabulary is determined by the C# type at each nesting level. The official Smartly Dressed Games modding documentation lists the fields for documented struct types (PlayerSpotLightConfig). For struct types that are not exhaustively documented in the SDG docs (blueprints, engine, wheel, turret), the field vocabulary is best learned from observing shipped .dat files in the game's Bundles/ directory. This article documents the known field vocabulary for the most common struct types; the diagnostic table lists symptoms that indicate a field was written in the wrong context.

Can I use quotation marks around struct key names?

No. Struct keys are written without quotation marks: Name Repair, not "Name" Repair. The parser expects unquoted key names matching the C# property names exactly. Quotation marks around a key will cause the parser to fail to recognize it.

Can a struct contain another struct directly (without an array)?

Yes. A struct field can have a value that is itself a struct. The Engine struct inside a vehicle .dat is this pattern: the Engine field's value is the struct { Horsepower 300 ... }. The opening brace { on the line following the field name triggers standalone struct parsing. This pattern applies to any field where the expected C# type is a class or struct rather than a scalar or array.

Can strings inside structs contain spaces?

Yes. String values inside structs can contain spaces if they are enclosed in quotation marks: CategoryTag "ad1804b6945145f3b308738b0b8ea447". The quotation marks delimit the string value and allow whitespace within the value. Without quotation marks, the parser treats whitespace as a field separator. GUID strings in the blueprint system are conventionally quoted because they are long hexadecimal strings that benefit from clear delimitation, but quotation marks are syntactically optional for values that do not contain spaces.

What is the maximum nesting depth for structs?

The parser does not impose a hard nesting depth limit. However, the deepest nesting observed in vanilla .dat files is three levels (Blueprints array → Blueprint struct → InputItems array → BlueprintInput struct), and deeper nesting is unlikely to be encountered in mod authoring. If a mod requires nesting deeper than three levels, test the .dat file in single-player to confirm the parser accepts the depth before relying on it in a published mod.

Can the order of struct fields matter?

No. The parser reads all key-value pairs inside a struct and matches them to C# properties by name. The order in which the fields are written does not affect the parsed result. The conventions shown in this article (identity fields first, then sub-arrays, then scalar fields) are for human readability, not a parser requirement.

How do I specify an empty array in a .dat file?

An empty array is written as [ ] (opening and closing brackets with no elements between them): InputItems [ ]. An empty array is valid and means "no input items are required." This is different from omitting the InputItems field entirely -- an omitted field may trigger a default value, while an explicit empty array overrides the default with an empty list. The behaviour difference depends on the specific C# type and field; in most cases, an empty array and an omitted field produce the same runtime result.

Can I mix scalar values and structs in the same array?

No. An array is typed -- all elements must be of the same type. An array of strings must contain only strings. An array of structs must contain only structs (each delimited by { }). Mixing a scalar string and a struct in the same array brackets will cause a parse error because the parser expects a consistent element type. If a field needs to hold a collection of mixed types, the correct approach is to define each element as a struct where one of the struct's fields indicates the type.

Do struct fields inherit values from parent contexts?

No. Struct fields are self-contained. A BlueprintInput struct does not inherit fields from its parent Blueprint struct or from the top-level asset. Each struct defines only the fields that appear inside its own curly braces. If a struct needs access to a value from a parent context, the value must be repeated inside the child struct's curly braces or referenced indirectly (e.g., the this keyword in InputItems that refers to the parent item asset itself).

Best practices

  • Indent struct content consistently for human readability. The parser ignores indentation, but future readers (including the original modder returning after months away) rely on indentation to understand the nesting structure.
  • Use the this keyword for InputItems when the recipe consumes the parent item itself. This is clearer than specifying the parent item's own ID or GUID explicitly.
  • Place the Blueprints array at the end of the .dat file, after all flat fields. This convention is observed in vanilla .dat files and makes the file easier to scan: flat fields first, complex nested structures last.
  • Quote GUID strings inside structs. The quotation marks visually distinguish a GUID string from an unquoted field value and make the struct easier to read.
  • Verify every struct field against the known vocabulary for the struct type. A field written in the wrong context is silently ignored, which is the hardest class of struct bug to detect.
  • Test the complete struct block in single-player by exercising the blueprint, equipping the spotlight, or driving the vehicle. Visual testing catches silent struct field errors that text-only review misses.
  • When copying a Blueprints array from a vanilla .dat file, replace the vanilla item GUIDs with the mod's own GUIDs. Leaving a vanilla GUID in a mod blueprint causes the blueprint to interact with vanilla items rather than the mod's own items.
  • Document the struct structure in comments if the nesting is non-obvious or if a specific C# property name differs from the expected field name convention.

Advanced considerations

Struct parsing performance at load time

Each struct block adds a small amount of parsing overhead at asset load time. The parser must construct a C# object for each struct, match each key to a property, convert each value to the expected type, and handle any fields that do not match. For a typical .dat file with one or two recipes in the Blueprints array, this overhead is negligible. For a .dat file with hundreds of blueprint entries (a comprehensive crafting mod), the cumulative parsing cost can become noticeable. Modders authoring large blueprint arrays should be aware that the per-struct parsing cost is incremental but small; the dominant cost at asset load time is the Unity bundle loading, not .dat file parsing.

Struct versioning and forward compatibility

The struct type system in Unturned™ is versioned alongside the game. When the game updates and adds new fields to a struct type (a new property on PlayerSpotLightConfig, a new field on Blueprint), the parser may expect the new field and may behave differently if it is absent. A .dat file authored for an older game version that does not include the new struct field will typically parse successfully with the default value for the new field applied automatically, but modders should test struct-bearing .dat files after each major game update to confirm that the struct fields are still recognized and interpreted correctly.

Structs and the asset inheritance system

Some asset types in Unturned™ support inheritance -- a child asset can extend a parent asset and inherit its fields. When a child asset defines a struct field that also exists on the parent, the child's struct overrides the parent's struct completely (field-level merging is not performed -- the child's struct replaces the parent's struct, not merges with it). If the child wants to retain some of the parent's struct fields while overriding others, the child must repeat all the fields from the parent's struct that it wants to retain, plus the fields it wants to change. This is a common source of confusion when working with inherited asset hierarchies that include structs.

Structs in server-side plugin code

Server-side plugins that manipulate struct fields at runtime access them through the Unturned Dedicated Server API's object model. The PlayerSpotLightConfig struct, for example, is exposed as a property on the item asset object, and its sub-fields (SpotLight_Range, SpotLight_Color, etc.) are accessible through the struct's public C# properties. A plugin that dynamically adjusts a spotlight's range based on server state reads the asset's PlayerSpotLightConfig, accesses the SpotLight_Range float, modifies it, and writes the modified struct back to the asset. The API-level property names match the .dat field names (PascalCase with underscores where the C# property uses them). Plugin authors should verify the exact C# property names against the game assembly rather than relying on the .dat field name alone, as some C# properties use different casing or naming conventions than their .dat string representations.

Appendix A: Struct format quick reference card

ContextSyntaxExampleNotes
Standalone structField { k1 v1 k2 v2 }Engine { Horsepower 300 Fuel 10000 }Opening brace on line after field name
Array of structsField [ { k v } { k v } ]Blueprints [ { Name A } { Name B } ]Opening bracket on line after field name; each element in its own { } block
Array of scalarsField [ v1 v2 ]Bursts [ 3 ]Brackets on same line or following line
Array of stringsField [ "s1" "s2" ]RequiresNearbyCraftingTags [ "abc" ]Each string quoted
Embedded struct (prefix)Prefix_Field valueSpotLight_Range 64Fields recognized by name prefix; no enclosing braces needed
Special keywordthisInputItems thisReferences the parent item asset

Appendix B: Known struct types and their C# mappings

.dat struct contextParent contextC# type (approximate)Key fields
Blueprints elementItem assetBlueprintName, CategoryTag, Operation, InputItems, OutputItems, Skill, Skill_Level, Effect, RequiresNearbyCraftingTags
InputItems elementBlueprint structBlueprintInputID, Amount, Delete
PlayerSpotLightConfigItem asset (embedded by prefix)PlayerSpotLightConfigSpotLight_Enabled, SpotLight_Range, SpotLight_Angle, SpotLight_Intensity, SpotLight_Color
EngineVehicle assetVehicle engine typeHorsepower, Fuel, Fuel_Burn_Rate, Gear_1..N, Reverse_Gear
Wheel_NVehicle assetVehicle wheel typePosition, Suspension_Length, Has_Power, Has_Steering
Turret_NVehicle assetVehicle turret typePosition, Gun_ID, Yaw_Min, Yaw_Max, Pitch_Min, Pitch_Max
Sight / Muzzle / Grip / Barrel / Tactical / MagazineGun assetInteger ID referenceSingle integer value (attachment item ID), not a struct
Hook_Sight / Hook_Tactical / Hook_Grip / Hook_BarrelGun assetFlag listBare flag strings, not structs

Appendix C: Struct authoring checklist

Before publishing a mod that includes struct fields, confirm the following:

  • [ ] All curly braces { } and square brackets [ ] are properly paired (every opening character has a matching closing character)
  • [ ] All struct fields use the correct key names as recognized by the expected C# type
  • [ ] No struct-specific fields appear at the wrong nesting level (e.g., Skill at the top level instead of inside a Blueprints element)
  • [ ] GUID strings are quoted and use the mod's own GUIDs (not vanilla GUIDs borrowed from example files)
  • [ ] The this keyword is used correctly for InputItems where the recipe consumes the parent item
  • [ ] Delete false is set on tool items (blowtorch, wrench) that should persist through multiple crafting operations
  • [ ] Recursive nesting is correct: BlueprintsBlueprintInputItemsBlueprintInput
  • [ ] All struct blocks tested in single-player by exercising the relevant gameplay system (crafting, equipping spotlight, driving vehicle)
  • [ ] The struct block is placed after flat fields in the .dat file, following the vanilla file convention

Appendix D: Diagnostic table for struct format errors

SymptomMost likely causeResolution
Blueprint does not appear in crafting UICategoryTag not recognized or RequiresNearbyCraftingTags workbench GUID wrongVerify GUID strings match the mod project's GUIDs or vanilla crafting station GUIDs
Blueprint consumes tool even though Delete false is setDelete false field on wrong nesting level (outside InputItems element)Move Delete false inside the BlueprintInput struct for the tool item
Blueprint requires a tool but tool is not consumed and not returnedDelete false field is missingAdd Delete false inside the BlueprintInput struct for the tool item
Skill level requirement ignoredSkill or Skill_Level field on wrong nesting levelEnsure Skill and Skill_Level are inside the Blueprint struct, not at top level
Spotlight does not toggleSpotLight_Enabled is false or field is missingSet SpotLight_Enabled true at the top level of the item .dat
Spotlight colour is default (warm white) instead of custom colourSpotLight_Color field is misspelled or placed at wrong nesting levelVerify SpotLight_Color field spelling and placement at top level of item .dat
Engine does not start or vehicle has no powerHorsepower field is 0 or engine struct is missingAdd engine struct with positive Horsepower, Fuel, and Fuel_Burn_Rate
Vehicle handles poorly or wheels appear at wrong positionsPosition Vector3 on Wheel_N struct has wrong component signs or magnitudesAdjust Position Vector3 values; test in single-player
Turret does not rotate or fireGun_ID does not reference a valid gun item, or Yaw_Min/Yaw_Max restrict rotation to zero rangeVerify Gun_ID matches a valid gun item; set Yaw_Min/Yaw_Max and Pitch_Min/Pitch_Max to the intended rotation range
Struct field silently ignoredField key does not match any property on the expected C# type at that nesting levelMove the field to the correct struct context; verify key name spelling and casing

Appendix E: External references

ResourceURLNotes
Smartly Dressed Games modding documentationhttps://docs.smartlydressedgames.com/en/stable/Official field reference. The structs data type chapter documents PlayerSpotLightConfig.
Unturned on Steamhttps://store.steampowered.com/app/304930/Unturned/Game changelog.
Vector3 Type Reference/data-types/vector3-type-referenceThe previous article in this section; covers the Vector3 format used within vehicle and turret structs.
Color Format Reference/data-types/color-format-referenceThe article two positions before; covers the colour format used within PlayerSpotLightConfig.
Rich Text Formatting Reference/data-types/rich-text-formatting-referenceThe next article in this section.
Item Asset Anatomy/items/item-asset-anatomyThe shared field reference that documents the asset-level structs like Blueprints.

Cross-references

Document history

VersionDateAuthorNotes
1.02026-07-2657 StudiosInitial publication. Complete struct format reference: syntax rules, nesting rules, C# type mapping, PlayerSpotLightConfig, Blueprints, Engine, Wheel, Turret structs; worked examples; FAQ; diagnostic table.