DEMIENGINEPACKAGE STORE Everything is free
← Explore packages
3D

Destruction Weapons & Streaming

Published by DemiEngine · Version 1.1.0

About this package

Destruction weapon probes

Requires the current DemiEngine development build with the experimental native destruction APIs. Install from a project directory with demi package add demi.gameplay.destruction@1.1.0 --registry /path/to/DemiEngine/packages. Version 1.1.0 is currently a local development release; the hosted 1.0.0 archive is unchanged. See LICENSE for BSD-3-Clause terms. This is gameplay code; no third-party models or textures are included.

demi.gameplay.destruction.weapons owns hammer phases, ammunition, cooldowns, bounded rocket flight and cleanup. demi.gameplay.destruction.native adapts public engine queries, prefab visuals and native spatial impacts. No shard names or physics-body splitting rules appear in the package.

local Weapons = require("demi.gameplay.destruction.weapons")
local Native = require("demi.gameplay.destruction.native")
local weapon = Weapons.new(Native.new({owner = "player", rocket_prefab = "prefab://rocket"}),
  {id_prefix = "player/rocket/"})

Call hammer() to begin an attack, fire(origin, direction) for a rocket, and update(fixed_dt, origin, direction) every fixed step. The hammer queries at the end of its swing, not at button press. Rockets sweep a sphere over their entire step, expire without exploding, and detonate once on first contact. Initial overlaps detonate without spawning a visual. dispose() releases active visuals. reload() is an immediate diagnostic refill, only allowed with no active rockets.

The visual prefab must have an unparented Transform3D root named body (override with rocket_root) and no collider/rigidbody: propelled rockets use native swept queries, not independent ballistic bodies. A unique id_prefix is required for each weapon owner. Supply all services explicitly for isolated unit testing; native modules are imported only by the native adapter. The visual root follows the swept-sphere centre and faces local +Z. Keep the model's leading tip within rocket_radius; the example offsets its shell so the visible nose and collision front agree.

hammer_phase() returns phase/progress for visual animation. drain_events() returns bounded presentation events (the latest 32), not authoritative damage. Counters shots, detonations, contacts, ammo, and rockets can be polled. An accepted impact is queued; native destruction may still reject its commit. The native adapter attaches an optional receipt to impact events, containing the directly hit target's stable assembly root, pre-queue revision, and original target body ID. Poll Destruction.state(receipt.root) to distinguish queued, failed and revision-advanced batches; the original body may be retired by a split. This tracks the primary target's assembly, not all assemblies touched by a radial explosion, and is diagnostic rather than a per-request transaction ID. Custom impact services can return this metadata as their fourth result; the optional second service argument is the directly hit body (not a radial filter).

This is a local gameplay foundation, not network authority, an inventory system, ballistic rocket physics or a full animation system. Initial overlap checks and native sweeps ignore trigger volumes while retaining blocking geometry behind them.

Streamed structures

demi.gameplay.destruction.streaming accepts compact {id,prefab,position} records and Native.streaming() services. Records allocate no engine entities until they enter range. update(dt, observer_position) uses a spatial index, bounded scan/spawn budgets and an active-instance cap. Defaults: 24 m load, 32 m unload, 8 active, 1 spawn/update, 256 candidates/update. Distance uses assembly origins, not individual debris bounds. First-use generation is synchronous.

Damage is retained in memory on unload (preserve=false explicitly resets a record instead). debris_lifetime=0 disables cleanup; a positive value opts into retiring detached groups after idle active time, while preserving the resulting holes. export_state() returns a versioned, geometry-free save table; pass it to demi.save only when disk persistence is wanted. import_state(state) must run before activation. Template mismatch fails rather than silently restoring a pristine wall. Check last_error; active_count and last_scanned are diagnostics.

dispose() releases this manager's instances; export first if their state must survive disposal. This package is policy over native checkpoint/restore/cleanup, not an alternate Lua physics or fracture implementation. See the engine's docs/streamed-destruction.md for authoring, cache limits and qualification gaps.

Tags

Dependencies

No additional package dependencies.

Related packages