Skip to content

How It Works

The Problem

DCS World's native blast damage model has unrealistically steep falloff. A 500lb bomb that lands 10 meters from a truck should destroy it. In DCS, it might scratch the paint. This has been a known issue in the community for years. Eagle Dynamics has not fixed it.

The Fix

BUFF intercepts weapon launches, tracks them in flight, and spawns supplemental explosions at impact. These stack on top of DCS's native damage to produce realistic blast radii.

The core trick is simple and well-established in the community -- Splash Damage has been doing this since FrozenDroid's original script. BUFF just does it with less overhead.

Four-Phase Pipeline

Phase 1: Registration (Event-Driven)

When any weapon is launched, DCS fires S_EVENT_SHOT. BUFF's event handler:

  1. Checks if the weapon type is in the weapon table
  2. If players_only is set, checks for a player name on the initiator
  3. Pre-computes the final explosion power with all multipliers applied:
    power = base_power * power_scale
    if shaped_charge: power = power * shaped_charge_scale
    if rocket:        power = power * rocket_scale
    
  4. Stores the weapon object, pre-computed power, and initial position/velocity in the tracking table

Key design choice: Power is computed once at registration and never recalculated. No per-tick or per-impact lookups.

Phase 2: Tracking (Polling Loop)

A timer.scheduleFunction polls tracked weapons at refresh_rate (default 0.1s):

  • For each tracked weapon, check isExist()
  • If alive: update cached position, direction, and velocity (3 property reads)
  • If gone: queue for impact processing, remove from tracking table

When nothing is tracked, the poll interval widens to idle_rate (default 0.5s).

What this does NOT do per tick:

  • No world.searchObjects (the expensive spatial query)
  • No land.getIP (terrain intersection)
  • No closure allocations
  • No health snapshots

This is the key performance difference from the original Splash Damage -- zero sphere searches during weapon flight.

Phase 3: Impact Processing (Once Per Weapon)

When a weapon disappears (isExist() returns false), BUFF processes it through two gates before spawning explosions.

Gate 1: Mid-Air Intercept Check

DCS destroys weapon objects identically for ground impact and mid-air intercept (SHORAD, CIWS, etc). isExist() going false tells us nothing about why the weapon was destroyed.

Without this check, a Gepard shooting down a GBU-12 at 5000ft AGL would produce a phantom explosion on the terrain below.

Fix: Compare the weapon's last-known altitude against terrain height. If the weapon was well above ground (default: 50m AGL) when it disappeared, treat it as an interception and skip all processing.

This is a bug in the original Splash Damage script

The original author found this issue in the napalm handler (line 1611) and added an AGL check there, but never applied it to the main splash damage pipeline. BUFF fixes this for all weapons.

Gate 2: Impact Point Estimation

Use the weapon's last-known position and direction to project a terrain intersection via land.getIP. This refines the impact point beyond the last cached position (which could be up to one poll interval stale). Falls back to raw last-known position if the ray misses.

Primary Explosion

trigger.action.explosion(impact_point, power)

This is the core of the entire script. DCS already exploded the weapon with its native (weak) damage. BUFF supplements with a properly-scaled explosion at the same point.

Cascade (Blast Wave)

If cascade is enabled (default: yes), BUFF performs one world.searchObjects sphere search around the impact point. The search radius scales with weapon power using cube-root scaling (approximates real pressure wave falloff):

radius = power^(1/3) * 10

For each object found in the search:

  1. Distance check -- skip objects at ground zero (already hit by primary)
  2. Inverse-square intensity -- calculate blast pressure at the object's distance
  3. Surface area scaling -- multiply by the object's bounding box facing area (larger targets catch more blast)
  4. Structure boost -- buildings get a flat multiplier (DCS structures are unrealistically tanky)
  5. Minimum damage gate -- skip if calculated damage is negligible
  6. Secondary explosion -- schedule trigger.action.explosion on the object with a propagation delay (~500 m/s shockwave speed)

Phase 4: Damage Model (Deferred)

1.5 seconds after impact (to let cascade explosions resolve), BUFF checks surviving ground units:

  • Infantry below 60% health: ROE set to WEAPON_HOLD
  • Vehicles below 40% health: ROE set to WEAPON_HOLD
  • Vehicles below 30% health: full stop, unit disabled

This simulates partial kills -- a damaged vehicle stops fighting and moving, even if DCS didn't fully destroy it.

Error Handling

Every DCS API call is wrapped in pcall. Errors go to env.error() (DCS.log) but never crash the mission. A scripting bug in BUFF will not bring down a multiplayer server.

Performance Analysis

The expensive operation in DCS scripting is world.searchObjects -- it scans the simulation's spatial index on the main thread and directly impacts frame time.

Scenario Splash Damage 3.4 BUFF
16 weapons in flight (10Hz) 320 sphere searches/sec 0
16 weapons impact 16 + N cascade searches 16 total
Nothing tracked 10Hz poll 0.5s poll

BUFF eliminates ~95% of expensive operations during the weapon flight phase by deferring all spatial queries to impact time.