-
Notifications
You must be signed in to change notification settings - Fork 1
Object Definitions
You can declare new object archetypes with def_object:
def_object {
name = "my_mod.monastery_distillery",
model = "my_mod/models/monastery_distillery.fbx",
flags = F_BLOCK_ALL,
tags = { "my_mod", "monastery" },
}
Once declared, the object archetypes show up in editor's Asset Browser. From scripts, instances can be spawned with spawn function:
function on_init_map(map)
local x, y, facing = 10, 12, 0
local distillery = spawn("my_mod.monastery_distillery", map, x, y, facing)
-- do something with the distillery...
end
If you have a reference to an object instance, the archetype can be accessed through it's arch property.
function on_battle_start(map)
for _,obj in all_map_objs(map) do
if obj.arch.name == "my_mod.monastery_distillery" then
-- do something with all the distilleries on the map...
end
end
end
A string that defines the technical name for the object shown in Asset Browser. This name is used when referring to the object archetype when spawning, finding objects etc. The UI name is derived from this by replacing _ underscores with spaces and title casing the result. If that does not produce acceptable results, the UI name can be overridden with ui_name.
TODO naming rules?
def_object {
name = "my_mod.my_asset",
...
}
A string that defines an optional override for the UI name.
def_object {
name = "my_mod.my_asset",
ui_name = "Asset of Mine.",
...
}
A number that dedines optional flags for the object.
def_object {
...
flags = F_BLOCK_MOVE + F_HIDE_CLOSEUP,
...
}
See object flags from Flags.
A number that defines the width (i.e. number of squares occupied on the map's x-axis) of the object in squares. Defaults to 1.
For mobs, the width and height must be equal.
A number that defines the height (i.e. number of squares occupied on the map's y-axis) of the object in squares. Defaults to 1.
For mobs, the width and height must be equal.
def_object{
...
width = 2,
height = 1,
...
}
An optional boolean that specifies whether to destroy the object when the battle ends. This is used to clear certain objects away before victory cams, outro etc.
An array of strings that defines the Asset Browser categories for the object.
def_object{
...
tags = { "swamp", "rock" },
...
}
An optional string that defines the layer of the object. Mostly used by editor tools for determining whether to replace existing objects in a square when a new object is placed, but "floor"
and "grass"
layer objects get special treatment when picking with mouse.
Layers used by built-in assets: "ceiling"
, "dungeon_clutter"
, "floor"
, "grass"
, "liquid"
, "plant"
, "tree"
, "wall"
, "whitebox"
An optional string that defines how to position the object within a square.
snap_to | Description |
---|---|
"center", nil | Default: snap to center of the square. |
"vertex" | Snap to the corner of the square. The corner is determined by the facing of the object. |
"edge" | Snap to the edge of the square. The edge is determined by the facing of the object. |
def_object{
name = "dungeon_pillar",
flags = F_IGNORE_HEIGHT + F_PLACE_CORNER_BLOCKER,
snap_to = "vertex",
...
}
Warning! Using F_PLACE_CORNER_BLOCKER in combination with F_FREE_TRANSFORM, i.e. objects not locked to grid, can cause unpredictable results. So either declare separate objects for gameplay and decorative purposes, or remember to clear F_PLACE_CORNER_BLOCKER afterwards.
Defines the pattern the object creates when updating the fog of war. It can be either an integer or an array of integers. In case of just a single integer, the only option is used when updating the fog. In case of multiple values, object's facing + 1 is used as index to the table. See facing from Concepts.
fog_tile | Description |
---|---|
FOG_DOOR_NS | North or south facing door |
FOG_DOOR_EW | East or west facing door |
FOG_SECRET_DOOR_NS | North or south facing secret door |
FOG_SECRET_DOOR_EW | East or west facing secret door |
FOG_SOFT | Trees, rocks etc. |
FOG_WALL | Hard objects such as walls covering the whole square. |
def_object{
name = "castle_ceiling",
fog_tile = FOG_WALL,
flags = F_BLOCK_ALL,
...
}
def_object{
name = "dungeon_door",
fog_tile = { FOG_DOOR_NS, FOG_DOOR_EW, FOG_DOOR_NS, FOG_DOOR_EW },
...
}
An optional integer that defines the sampling radius in meters to use when placing the object on a heightmapped ground. If not defined, a single point at the center of the square is used.
def_object {
...
heightmap_sample_radius = 1.5,
...
}
TODO
TODO
TODO
TODO
TODO
A string that defines a path to the file containing the mesh for the model. The extension is a bit weird for modding purposes; it must be .fbx in this declaration although at runtime it will be mapped to .model.
When defined, makes the object to have a model component. If left out, the object won't have a model component, but can have other components such as particles or lights.
The model fileformat is described here.
def_object{
name = "my_mod.dungeon_wall",
model = "my_mod/models/dungeon_wall_01.fbx",
...
}
An optional vector that defines an offset for the model from the root node location.
def_object{
name = "action_point",
model_position = vec(0.0, 0.3, 0.0), -- raises the model 0.3 meters higher from the floor/ground
...
}
An optional vector that defines the Euler angles (xyz) in radians for the model.
def_object{
name = "spear",
model_rotation = vec(math.rad(90), math.rad(45), 0.0),
...
}
An optional value that can be:
- a float for defining an uniform scaling factor for the model
- a vec for defining non-uniform scaling factors for the model
def_object{
name = "my_mod.uniform",
model = "my_mod/models/box.fbx",
model_scale = 2.0,
...
}
def_object{
name = "my_mod.nonuniform",
model = "my_mod/models/box.fbx",
model_scale = vec(3.0, 0.5, 3.0),
...
}
An optional vec that defines custom bounding box for the object.
An optional string that defines the name of the material override to use instead the material defined by the model.
An optional hash map that defines material overrides for multiple meshes in the model.
def_object{
name = "beacon_fire_unlit",
model = "data/models/spawnling_bonfire.fbx",
model_material_overrides = { bonfire = "bonfire_unlit" },
...
}
An optional boolean that defines whether to create an instance specific copy of the material. Used for e.g. animating materials.
An optional string that defines how the model should be rendered.
model_render_mode | |
---|---|
nil | default |
editor | |
heightmap | The model is bent using the heightmap. Use for ground objects. |
hidden | Hide the model during rendering. |
warp | |
water | |
wireframe | Only rendered in the editor! |
An optional boolean that defines if the model casts shadows. Defaults to true.
TODO
Defines the AI routine for the mob.
AI routine for skeleton_archer
looks like this:
ai_routine = {
-- first the archer tries a ranged attack with the special attack "arrow_attack", defined below.
-- The probability is 1.0.
{ ai_ranged_attack, "arrow_attack", 1.0 },
-- if ai_ranged_attack did nothing, the AI moves on and tries a melee attack next
ai_melee,
},
arrow_attack = {
flags = IF_ACTION + IF_OFFENSIVE + IF_PRIMARY_ATTACK,
projectile_type = "arrow_projectile",
on_use_item = use_ranged_weapon,
range = 6,
pierce = 1,
damage = "b",
attack_sound = "bow",
description = "Deal %damage damage to a target within %range squares.",
},
Mandatory integer values that define the maximum HP for the mob on different difficulty levels.
Mandatory flags for the mob. See mob flags from Flags.
Mandatory integer values that define the armor of the mob on different difficulty levels.
On mob instances, you can define mob_armor_bonus to increase instance specific armor.
A mandatory integer that defines how many XP the heroes receive when the mob is defeated.
A mandatory integer that defines the movement speed of the mob, i.e. how many movement_points it receives on each round.
A mandatory integer that defines how much damage the mob does with its basic melee attack on different difficulty levels.
A mandatory float that defines how fast the game should move the mob's root node in the world space when the mob is moving.
TODO formula to calculate this
A mandatory integer that defines the immunities for the mob. This applies only to conditions; there are other immunity-kind qualities, which can be set using mob flags. See above.
def_object{
name = "my_mod.my_monster",
immunities = IMMUNE_POSSESSED+IMMUNE_BURN,
...
}
immunities |
---|
IMMUNE_POISON |
IMMUNE_INVISIBILITY |
IMMUNE_FREEZE |
IMMUNE_BURN |
IMMUNE_CHARGED |
IMMUNE_PROTECT |
IMMUNE_PROTECT_FULL |
IMMUNE_SLEEP |
IMMUNE_FOCUS |
IMMUNE_CONFUSED |
IMMUNE_SLOWED |
IMMUNE_RALLIED |
IMMUNE_GUARDING |
IMMUNE_DODGING |
IMMUNE_BLEEDING |
IMMUNE_STUNNED |
IMMUNE_ENRAGED |
IMMUNE_PHASED_OUT |
IMMUNE_PETRIFY |
IMMUNE_STRENGTHENED |
IMMUNE_STOPPED |
IMMUNE_DAZED |
IMMUNE_WEAKENED |
IMMUNE_POSSESSED |
IMMUNE_SHIELDED |
IMMUNE_REGENERATE |
IMMUNE_DISEASED |
IMMUNE_POWER_ATTACK |
IMMUNE_CHARMED |
IMMUNE_COMMANDED |
IMMUNE_SUFFOCATING |
IMMUNE_DEFENDED |
IMMUNE_GUARDED |
IMMUNE_IMMOBILIZED |
IMMUNE_DEFENDING |
IMMUNE_OILED |
IMMUNE_LEECH_FOREST |
IMMUNE_ALL |
An optional boolean that determines whether the mob is a thing or just a mob. All things are mobs, but not all mobs are things.
An optional string that defines the name of the object to spawn when the mob dies.
An optional string that defines the effect to spawn when the mob dies.
mob_death_effect | description |
---|---|
default | Spawn the default particle effect. |
none | No spawns. |
any_other_value | Spawn "any_other_value"
|
An optional string that defines the name of the effect to spawn when the mob is hit.
TODO
An optional string that defines the short description of the mob, which is shown when hovering the mob with the mouse.
TODO lore text
An optional integer that defines whether to drop loot or not.
loot_class | value |
---|---|
0 | Don't drop loot |
1 | Drop loot when killed |
TODO
TODO
When this property is defined on an object, the animator component is created for it. The anims property defines a mapping between wellknown animation names and the corresponding animation files, as defined in the file formats doc. Again, the extension is a bit weird for modding purposes; although the file extension must .animation, here the extension needs to be .fbx.
Example:
def_object{
name = "my_mod.my_door",
model = "my_mod/models/my_door.fbx",
anims = { open = "my_mod/anims/my_door_open.fbx" },
}
Here is a non-exhaustive list of wellknown animation names for different kinds of objects. You can investigate the animations with the editor. First select the object you want to investigate, then expand the Animator panel and States. You can click individual animation states to play them.
Object type | Animation name | Description |
---|---|---|
doors | open | |
portcullis | open | |
portcullis | close | |
mobs | idle | Idle animation is played in a loop by default when the object is spawned. |
mobs | move1 | Move loop fragment where the left leg leads |
mobs | move2 | Move loop fragment where the right leg leads |
mobs | move | When move1 and move2 are not defined, this is used when moving. Intended for defining the entire move loop for moving one square. |
Randomize the location in the idle animation when the object is spawned. This is to prevent e.g. all trees moving in sync.
An optional string that defines which animation to play when the object is initialized after spawning. For non-temporary objects you may need to do some housekeeping after a savegame has been loaded in order to prevent the animation from playing.
def_object{
name = "egg_sack_destroyed",
anims = {
burst = "data/anims/egg_sack_destroyed_burst.fbx",
},
anim_play_on_init = "burst",
on_game_loaded = function(obj)
-- sample the animation @ 100s when a savegame is loaded. This also stops the animator:
sample_anim(obj, "burst", 100.0)
end,
}
TODO
def_object{
name = "acid_bolt",
particle_system = "acid_bolt",
particle_auto_destroy = true,
trail_type = "swipe",
trail_max_segments = 20,
trail_offset1 = vec( 0.5, 0.0, 0.0),
trail_offset2 = vec(-0.5, 0.0, 0.0),
trail_texture = load_texture("data/textures/spell_trail.png", "rgba8_srgb"),
trail_color = 0x00ff00ff,
trail_intensity = 5.0,
projectile_speed = 25.0,
projectile_trajectory_height = 0.0,
projectile_noise = 0.05,
flags = F_TEMPORARY,
tags = { "effect" },
}
Must be "swipe"
to declare the trail component.
An optional string that defines how the object can be interacted with.
You can define this also on the object instances to create instance specific overrides.
interaction_type | Description |
---|---|
nil | |
"none" | Prevent interaction. TODO document how F_INTERACTIVE and this one co-operate. |
"move_to" | The object is interacted with by stepping on it: pressure plates, triggers etc. See trigger_flags below. |
"directed" | The object can be interacted only from one direction. Only supported for objects with snap_to = "edge" . |
An optional boolean that lets you turn of the mesh outline when hovering the interactive object. Defaults to true.
An optional integer that lets you set the color of the mouse "tick" when the object is hovered.
def_object{
name = "water_tile",
interaction_type = "move_to",
interaction_draw_outline = false,
interaction_tick_color = 0x0088ffff,
on_init = function(obj)
if get_cell_flag(obj.map, obj.x, obj.y, CF_WATER) then
set_flag(obj, F_INTERACTIVE)
end
end,
...
}
An optional integer that defines the priority of the tooltip of the interactive object. Smaller priority is shown first. Supported range is [0..2].
This property is mandatory when you define an interactive object with interation_type of "move_to".
trigger_flags | Description |
---|---|
TRIGGER_WALKING | Trigger the object when a mob walks on it. |
TRIGGER_FLYING | Trigger the object when a mob flies on it. |
TRIGGER_DEAD | Trigger the object even when the mob is dead. |
Called before the object is activated. For pressure plates and such.
Called before the object is deactivated. For pressure plates and such.
An optional string that defines the loot item type in question. This used for preventing multiple loot drops of the same kind in the same square. E.g. a single square may contain gold and a heart, but not a heart + action point.
At the time of writing, the game uses values "floor" for gold and "orb" for action points and hearts.
Defining this property creates the light component for the object.
light_type | Description |
---|---|
ambient | |
directional | |
point | |
spot |
An optional vector that defines an offset for the light from the light's parent node, which is either the object's root node or whatever defined by light_parent.
def_object{
...
light_position = vec(0.0, 2.29, 0.7),
...
}
An optional vector that defines the Euler angles (xyz) in radians for the light.
def_object{
name = "spellbook",
light_type = "spot",
light_rotation = vec(math.pi * 0.5, 0.0, 0.0),
...
}
An optional string that defines the name of the parent node of the light. This lets you attach lights to specific bones on the skeleton.
Use Model->Nodes in editor to look up the names.
def_object{
...
light_parent = "light_null",
...
}
An optional vector that defines the color of the light for directional, point and spot lights. For ambient lights, sets the positive zenith color. Defaults to white.
def_object{
...
light_color = vec(1.0, 0.5, 0.25),
...
}
An optional vector that defines the horizon color for ambient lights. Defaults to white.
An optional vector that defines the negative zenith color for ambient lights. Defaults to white.
def_object{
...
light_type = "ambient",
light_color = shb_color_to_vec(0x67A6F6FF),
light_color2 = shb_color_to_vec(0x9BCFFFFF),
light_color3 = shb_color_to_vec(0x3078C3FF),
...
}
An optional float that defines the intensity of a light. Defaults to 1.0.
An optional float that defines the range of a light in meters. Defaults to 10.0.
An optional float that defines the flickering frequency of the light.
An optional float that defines the flickering amplitude of the light.
An optional boolean that defines whether the light casts shadows.
An optional boolean that defines whether the shadow map is blurred.
An optional integer that defines the dimensions of the shadow map for the light.
An optional boolean, which determines whether the light is a sun. Direction of the suns - unless free-transformed - is controlled by the game. Lights declared as suns are accessible from map.suns.
When set to true, the game will destroy the object in question when the light has faded out. See light_fade_out.
An optional float that defines the spot angle in radians.
An optional boolean that determines whether the object receives shadows. Set to false for e.g. skydomes. Defaults to true.
An optional boolean that determines the fade out duration in seconds. The fade starts immediately when the object is spawned. Use in conjunction with light_auto_destroy = true
and flags = F_TEMPORARY
to create short flash effects.
Mutually exclusive with light_fade_in.
An optional boolean that determines the fade in duration in seconds for the light. The fade starts immediately when the object is spawned.
Mutually exclusive with light_fade_out.
Valid for directional lights only.
An optional boolean that determines whether to use "more robust" algorithm for shadow map generation. Defaults to false. Valid for directional lights only.
A string that defines the name of the particle system associated with the object in question. When set, creates the particle system component.
def_particles {
name = "my_mod.stars",
...
}
def_object {
name = "my_mod.object_that_has_particles",
...
particle_system = "my_mod.stars",
...
}
An optional string that defines the name of the parent node of the particle system. This lets you attach particle systems to specific bones on the skeleton.
Use Model->Nodes in editor to look up the names.
def_object{
...
particle_parent = "light_null",
...
}
An optional vector that defines an offset for the particle system from the particle system's parent node, which is either the object's root node or whatever defined by particle_parent.
def_object{
...
particle_position = vec(0.0, 2.29, 0.7),
...
}
When set to true, the game will destroy the object in question when the particle system is dead:
- opacity of the particle system is 0.0
- or the particle system has been stopped and the number of particles in the system is 0
An optional float, which defines the number of seconds to warm up the particle system when spawned.
An optional boolean, which defines whether the particle system will follow the camera. Useful for e.g. spawning fog particles.
An optional float that lets you add an offset to depth in order to tweak the render order of transparent objects.
An optional boolean that determines whether the particle system is unbounded or a bounding box is used for culling. Defaults to false.
An optional float that specifies the opacity of the particle system.
An optional string the defines the sound set to be played when the heroes walk on the object.
footstep_sound |
---|
"hard" |
"soft" |
An optional string the defines the name of the sound to be played when the object is spawned.
def_sound("my_mod.my_spawn_sound", "my_mod/sounds/my_spawn_sound.wav", 1.0, 1.0)
def_object{
...
spawn_sound = "my_mod.my_spawn_sound",
...
}
If you are creating a door of your own, wiring on_interact to interact_door may be beneficial. This documentation refers to doors supported by interact_door.
A mandatory string that defines the details of opening the door.
door_type | Description |
---|---|
generic | A normal door. The object must have "open" and "close" animations. |
fence | A fence gate. The object must have "open" and "close" animations. |
portcullis | A portcullis. The object must have "open" and "close" animations. |
portcullis_downwards | A portcullis. The object must have "open" and "close" animations. |
An optional string the defines the name of the sound to be played when the door is opened.
def_sound("my_mod.door_creak", "my_mod/sounds/door_creak.wav", 1.0, 1.0)
def_object{
...
door_open_sound = "my_mod.door_creak",
...
}
Allows you to define a function that gets called on each frame before rendering.
def_object{
name = "torch_attachment",
...
timer = function(obj, time)
-- turn the particle system so that points towards positive y-axis
shb_look_at_dir(obj.particle_node, 0.0, 1.0, 0.0)
shb_rotate_node_about(obj.particle_node, 0, -math.rad(90))
end,
}
Allows you to create dynamic geometry. The function will be called on each frame during rendering.
TODO minimal example