Extension Mods Reference
Extension mods allow you to tag and categorize game entities for runtime behavior, enabling features like dynamic filtering, UI enhancements, and contextual interactions.
Overview
Extension mods define tags and attributes for existing game entities. Unlike patch mods which modify files, extension mods provide metadata that OpenZT and other mods can use at runtime.
Benefits: - Tag entities for runtime identification and filtering - Enable cross-mod compatibility through shared tag systems - No file conflicts - multiple mods can tag the same entity - Foundation for advanced features like UI filtering and entity grouping
Use Cases: - Grouping entities by type (e.g., "roof" objects that can be hidden) - Categorizing items for UI organization - Providing metadata for other mods to consume - Enabling contextual behaviors based on entity properties
Tags vs Attributes
| Feature | Tags | Attributes |
|---|---|---|
| Purpose | Categorization/grouping | Named properties with values |
| Values | String names | String key-value pairs |
| Example | tags = ["roof", "decoration"] |
attributes = { height = "large" } |
| Use Case | Boolean membership (has/doesn't have) | Configuration data |
Creating an Extension Mod
Extension Definition Format
Extensions are organized by entity type in your .toml files:
[scenery.vondel_greenhouse_roof]
base = "legacy.scenery.vogrhrf1"
tags = ["roof"]
[animals.elephant]
base = "legacy.animals.elephant"
tags = ["big"]
attributes = { size = "large" }
The base Field
The base field identifies which game entity you're extending:
legacy.{entity_type}.{entity_name}
Examples:
- legacy.scenery.statue - Scenery object named "statue"
- legacy.animals.elephant - Animal named "elephant"
- legacy.buildings.restaurant - Building named "restaurant"
Entity Type Sections
| Section | Entity Type |
|---|---|
[scenery.xxx] |
Scenery objects |
[animals.xxx] |
Animals |
[buildings.xxx] |
Buildings |
[fences.xxx] |
Fences |
[walls.xxx] |
Tank walls |
[paths.xxx] |
Paths |
[food.xxx] |
Food items |
[staff.xxx] |
Staff |
[guests.xxx] |
Guests |
[items.xxx] |
Items |
Concrete Example: The Roof Tag System
The roof system is a real, working example of extensions in OpenZT. It allows hiding/showing roof objects with Ctrl+R.
What It Does
- Tags scenery objects as "roof" entities
- Provides Ctrl+R keyboard shortcut to toggle roof visibility
- Auto-hides newly placed roofs when roofs are currently hidden
Mod Author Side (TOML)
To tag your scenery objects as roofs, add this to your mod's defs/extensions.toml:
[scenery.vondel_greenhouse_roof]
base = "legacy.scenery.vogrhrf1"
tags = ["roof"]
[scenery.my_custom_roof]
base = "legacy.scenery.myroof"
tags = ["roof"]
How It Works
When you tag an object with the "roof" tag:
- Loading: Your mod's extensions are loaded and stored
- Identification: When you place an object in-game, OpenZT identifies its base string
- Matching: The object's base is matched against registered extensions
- Behavior: Tagged roofs respond to Ctrl+R and auto-hide when roofs are hidden
Entity Type Reference
Entity Types and Their Properties
| Type | Section Name | Has Subtypes | Default Subtype | Base Format Example |
|---|---|---|---|---|
| Scenery | objects |
No | - | legacy.scenery.statue |
| Animals | animals |
Yes | m (male) | legacy.animals.elephant |
| Buildings | building |
No | - | legacy.buildings.restaurant |
| Fences | fences |
Yes | f (fence) | legacy.fences.wood |
| Walls | tankwall |
Yes | f (fence) | legacy.walls.acrylic |
| Paths | paths |
No | - | legacy.paths.grass |
| Food | food |
No | - | legacy.food.burger |
| Staff | staff |
Yes | m (male) | legacy.staff.keeper |
| Guests | guests |
No | - | legacy.guests.adult |
| Items | items |
No | - | legacy.items.icecream |
Finding Entity Base Strings
To find the correct base string for an entity:
- Check existing mods: Look at other extension mods or the game's
.cfgfiles - Use the console: Run
list_entities()in the Lua console to see all entities - Check entity files: Look at the entity's
.cfgfile in the game resources - For UCA, UCS and UCB files: Use the UCA/UCS/UCB filename without the extensions so
vogrhrf1.ucsbecomeslegacy.scenery.vogrhrf1
Example from an animal .cfg file (animal01.cfg):
[animals]
blckbuck = animals/blckbuck.ai
...
legacy.animals.blckbuck
Hypothetical Examples
Note: The following examples are illustrative only. They demonstrate what COULD be done with extensions, but these specific tags and attributes are not implemented in the base OpenZT system.
Example 1: Decorative Items (Hypothetical)
# HYPOTHETICAL EXAMPLE - "decoration" tag is not implemented
[scenery.statue]
base = "legacy.scenery.statue"
tags = ["decoration"] # illustrative - tag doesn't exist
Example 2: Animal Size Categories (Hypothetical)
# HYPOTHETICAL EXAMPLE - "size" attribute is not implemented
[animals.elephant]
base = "legacy.animals.elephant"
tags = ["big"] # illustrative - tag doesn't exist
attributes = { size = "large" } # illustrative - attribute doesn't exist
Example 3: Multi-Tag Entity (Hypothetical)
# HYPOTHETICAL EXAMPLE - These tags are not implemented
[scenery.fancy_fountain]
base = "legacy.scenery.fountain"
tags = ["decoration", "water_feature"] # illustrative - tags don't exist
attributes = {
maintenance = "high", # illustrative - attribute doesn't exist
value = "500"
}
Important: To use new tags or attributes beyond "roof", you would need to modify the OpenZT source code to register them and implement their behavior. As a modder, you can currently only use the existing "roof" tag.
Extension Validation
What Gets Validated
When extensions are loaded, OpenZT validates:
- Base format: Must match
legacy.{type}.{name}pattern - Entity type: The type in the base must be valid (animals, scenery, etc.)
- Tag validity: All tags must be registered for the entity's type
- Attribute validity: All attributes must be registered for the entity's type
Error Messages
# INVALID: Tag not registered for this entity type
[fences.iron]
base = "legacy.fences.iron"
tags = ["roof"] # ERROR: "roof" tag only applies to scenery, not fences
# INVALID: Malformed base string
[scenery.myobject]
base = "scenery.myobject" # ERROR: Missing "legacy." prefix
Best Practices
Tag Naming Conventions
- Use lowercase with underscores:
roof,water_feature - Use nouns for categories:
decoration,predator - Use adjectives for properties:
big,toxic - Keep names short and descriptive
When to Use Tags vs Attributes
Use tags when: - You need simple yes/no categorization - The property doesn't need a value - Multiple mods need to check for the same thing
Use attributes when: - You need to store specific values - The property has degrees or levels - You need configuration data
Using Existing Tags
Currently, the roof tag is the only tag implemented in base OpenZT. When creating mods:
- Use the "roof" tag: Apply it to scenery objects that should hide with Ctrl+R
- Test your extensions: Always validate that your extensions load correctly
- Coordinate with other modders: If you're working on an OpenZT fork with custom tags, communicate with the community
Complete Example: Roof Extension Mod
Here's a complete example of a mod that tags objects as roofs:
# meta.toml
name = "Roof Pack"
description = "Adds roof objects that can be hidden with Ctrl+R"
authors = ["Your Name"]
mod_id = "author.roof_pack"
version = "1.0.0"
ztd_type = "openzt"
# defs/extensions.toml
[scenery.japanese_temple_roof]
base = "legacy.scenery.japanroof"
tags = ["roof"]
[scenery.castle_turret_roof]
base = "legacy.scenery.turret"
tags = ["roof"]
Users can now: - Press Ctrl+R to toggle all roof visibility - Place roof objects and they'll respect the hidden state - Other mods can check for the "roof" tag to include/exclude these objects
Related Topics
- Patch Mods - For modifying game files
- Getting Started - OpenZT basics
- Habitats and Locations - Custom biomes and maps