AoE Zone Configuration

Configure timed area-of-effect attack zones for mobs, with a telegraph warning phase followed by a damaging active phase.

AoE (area-of-effect) zones are timed attack areas that mobs can create — a warning outline followed by an active area, useful for boss telegraphs, ground slams, shockwaves, and similar attacks. Each zone has a telegraph phase (warning, no effect) followed by an active phase. During the active phase a zone can deal damage, apply a continuous force (updraft / wind / suction), or both.


File Location

Register the file in your mod’s manifest (mods/<YourMod>/<YourMod>.yaml):

aoe-zone-config: aoe-zone-config.yaml

Then create the file it points to, relative to your mod’s folder:

# mods/<YourMod>/aoe-zone-config.yaml
aoe-zones:
  - name: my_boss_slam
    # ... zone fields, see below

Zone names are automatically prefixed with your mod name unless you write one already containing a colon, so my_boss_slam becomes YourMod:my_boss_slam — this full name is what you use to trigger the zone from Lua.

Zones are registered per mod, not per mob: a zone belongs to no particular entity, and any entity can trigger any zone by name (see Triggering from Lua). Naming a zone after the boss that uses it is a helpful convention, nothing more.


Minimal Example

aoe-zones:
  - name: my_boss_slam
    shape:
      type: circle
      start-radius: 0.5
      end-radius: 5.0
    damage-mode:
      type: one_shot
      damage: 1.0

This declares a zone that telegraphs for 500ms (the default), then instantly deals 1.0 damage to anything within a 5-block radius. The top-level aoe-zones: wrapper is required — the file is a mapping with an aoe-zones list, not a bare list, and a file that omits the wrapper fails to load.


Fields

Timing

FieldTypeDefaultDescription
telegraph-duration-msinteger500How long the warning outline is shown before the zone becomes active
active-duration-msinteger300How long the zone deals damage after the telegraph ends

Shape

All shapes animate from their start size to their end size over the active phase. The telegraph always displays the end size so players can see the full danger zone before it activates.

Circle

shape:
  type: circle
  start-radius: 0.5   # radius in blocks at the start of the active phase
  end-radius: 5.0      # optional, defaults to start-radius

Rectangle

shape:
  type: rectangle
  start-width: 1.0     # required
  start-height: 1.0    # required
  end-width: 8.0       # optional, defaults to start-width
  end-height: 6.0      # optional, defaults to start-height

Rectangles are centered horizontally on the spawn point and extend upward from it.

Ring

An annulus (donut) defined by an inner and outer radius. Entities between the two radii are inside the zone.

shape:
  type: ring
  start-outer-radius: 2.0   # required
  end-outer-radius: 9.0     # optional, defaults to start-outer-radius
  start-inner-radius: 0.0   # optional, defaults to 0
  end-inner-radius: 7.0     # optional, defaults to start-inner-radius

The telegraph outline shows the full sweep range — from start-inner-radius to end-outer-radius — so players can see the entire area the ring will travel through. An inner radius of 0 makes the ring a solid circle at that point in time.


Damage Mode

One-Shot

Deals damage once to all entities in the full end-size area, the moment the active phase begins.

damage-mode:
  type: one_shot
  damage: 1.0    # flat damage dealt

Continuous

Deals damage repeatedly to entities in the animated area (which grows over the active phase) on a fixed cooldown.

damage-mode:
  type: continuous
  damage-per-second: 5.0    # damage rate
  hit-cooldown-ms: 200      # optional, defaults to 500. Minimum time between hits per entity.

Damage per hit = damage-per-second × (hit-cooldown-ms / 1000). With the values above: 5.0 × 0.2 = 1.0 damage per hit, at most once every 200 ms per entity.

Sweep

Deals damage once to each entity the moving zone passes over, the first time it touches them — good for a shockwave or an expanding wave that should only tag each target once.

damage-mode:
  type: sweep
  damage: 1.0    # flat damage dealt per entity

Combine with an expanding shape (e.g. a ring growing outward) or a shape that translates using offset-start/offset-end to create a wave that sweeps across the battlefield.


Zone Offset (Movement)

Zones can translate in world space over the active phase using offset-start and offset-end. Both are {x, y} maps in blocks, relative to the zone’s spawn position — the same vector shape used everywhere else in the configs (particle velocity, entity max-velocity).

offset-start: {x: 0.0, y: 0.0}     # center offset at t=0 of active phase
offset-end: {x: 15.0, y: 0.0}      # center offset at t=1 of active phase (sweeps 15 blocks right)

Both fields are optional, and either axis within them may be omitted (defaulting to 0.0 independently). offset-start defaults to {x: 0.0, y: 0.0}; offset-end defaults to whatever offset-start resolved to (no movement). During the telegraph, the zone is displayed at its offset-end position (the full destination).


Force Field (Updraft / Wind / Suction)

A zone can apply a continuous force to everything inside it during its active phase — the primitive for updrafts, wind gusts, and directional push hazards. Add an optional force field, an {x, y} vector in the same shape as offset:

force: {x: 0.0, y: 45.0}     # a steady upward push — an updraft

The vector is an acceleration in blocks/s², the same units as the world’s gravity, and is applied every active tick as velocity += force × delta_time. Because it composes with gravity:

  • y greater than the world’s gravity → the entity is lifted (an updraft that carries you upward).
  • y equal to gravity → the entity hovers (weightless).
  • x non-zero → a horizontal wind push.

The push accelerates hard but is capped at each entity’s own maximum velocity, so it never flings anything faster than it could normally move — hold an entity in a strong updraft and it rises at (up to) its top speed, then falls back to gravity the instant it leaves the zone. force is optional; omitting it (the default) means the zone applies no force, so existing zones are unaffected.

Force is independent of the damage mode — a zone can push and damage, or push with no damage. damage-mode is still required, so for a pure updraft/wind zone use a zero-damage one-shot:

aoe-zones:
  - name: my_updraft
    telegraph-duration-ms: 0        # no warning — a persistent traversal current
    active-duration-ms: 600000      # long-lived; re-trigger from script to sustain it
    shape:
      type: rectangle
      start-width: 4.0
      start-height: 20.0            # a tall column of rising air
    damage-mode:
      type: one_shot
      damage: 0.0                   # no damage — force only
    force: {x: 0.0, y: 45.0}

Force respects zone geometry and phase exactly like damage: it acts only within the current (animated) shape, only during the active phase (never the telegraph), and never on the entity that created the zone. It applies to players, mobs, and mounts alike.


Colors

Outline colors are optional. Each is an { r, g, b, a } map of RGBA components in the range [0.0, 1.0] — the same color format used by the light: block’s color everywhere else.

FieldDescription
outline-colorOutline color during the telegraph phase
outline-color-activeOutline color during the active phase

If either is omitted, the zone has no visible outline for that phase (it still functions, just invisible).

outline-color:            # orange, 80% opacity
  r: 1.0
  g: 0.5
  b: 0.0
  a: 0.8
outline-color-active:     # red, fully opaque
  r: 1.0
  g: 0.0
  b: 0.0
  a: 1.0

Triggering from Lua

Call create_aoe_zone on an entity, typically from that mob’s server update script:

entity:create_aoe_zone("YourMod:my_boss_slam", x, y)
  • First argument — the zone’s full name, including mod prefix
  • x, y — spawn position of the zone center in world coordinates

Example — a boss slams the ground at its own position every 10 seconds:

-- /mobs/my_boss/scripts/server_update.lua
return function(entity, delta_time_ns)
    if entity.lua_data.slam_cooldown_ns == nil then
        entity.lua_data.slam_cooldown_ns = 0
    end
    entity.lua_data.slam_cooldown_ns = entity.lua_data.slam_cooldown_ns + delta_time_ns
    if entity.lua_data.slam_cooldown_ns >= 10e9 then
        entity.lua_data.slam_cooldown_ns = 0
        local loc = entity:get_location()
        entity:create_aoe_zone("YourMod:my_boss_slam", loc.x, loc.y)
    end
end

Behavior Summary

PhaseDurationVisualDamage
Telegraphtelegraph-duration-msoutline-color, shown at full end sizeNone
Activeactive-duration-msoutline-color-active, animates start → endYes
  • The zone is removed automatically once the active phase ends.
  • One-shot zones deal damage exactly once, regardless of how long an entity stays in the area.
  • Continuous zones can hit the same entity multiple times, subject to hit-cooldown-ms.
  • Sweep zones deal damage once per entity, the first time the zone touches them.
  • Damage hits players, mobs, and mounts, but never the entity that created the zone.
  • A force field pushes players, mobs, and mounts inside the active zone every tick (updraft / wind / suction), independent of the damage mode; it too never affects the zone’s creator.

Complete Example

A boss that ground-slams with an expanding ring shockwave:

# mods/<YourMod>/aoe-zone-config.yaml
aoe-zones:
  - name: my_boss_ground_slam
    telegraph-duration-ms: 1000
    active-duration-ms: 800
    shape:
      type: ring
      start-inner-radius: 0.0
      end-inner-radius: 7.0
      start-outer-radius: 2.0
      end-outer-radius: 9.0
    damage-mode:
      type: sweep
      damage: 1.0
    outline-color:
      r: 1.0
      g: 0.5
      b: 0.0
      a: 0.8
    outline-color-active:
      r: 1.0
      g: 0.0
      b: 0.0
      a: 1.0

The boss then triggers it from its scripts.server-update hook (see mob-config.md#scripts):

-- /mobs/my_boss/scripts/server_update.lua
return function(entity, delta_time_ns)
    entity.lua_data.slam_cooldown_ns = (entity.lua_data.slam_cooldown_ns or 0) + delta_time_ns
    if entity.lua_data.slam_cooldown_ns >= 10e9 then
        entity.lua_data.slam_cooldown_ns = 0
        local loc = entity:get_location()
        entity:create_aoe_zone("YourMod:my_boss_ground_slam", loc.x, loc.y)
    end
end