Physics System
Version History
Build Version | Change Date | Change Type | Description |
---|---|---|---|
676042 | 2025-06-21 | stable | Current version |
Overview
The physics
module provides essential physics-related functionality for Don't Starve Together, including collision detection callbacks, entity launching mechanics, area destruction systems, and collision mask management. This module serves as the bridge between the engine's physics system and Lua gameplay logic, enabling complex interactions between entities and environmental effects.
Usage Example
-- Register physics collision callback
PhysicsCollisionCallbacks[entity.GUID] = function(inst, other, ...)
print("Collision detected between " .. inst.prefab .. " and " .. other.prefab)
end
-- Launch entity with basic parameters
Launch(projectile, launcher, 10) -- Launch at speed 10
-- Launch with advanced control
Launch2(item, explosion_source, 5, 3, 0.5, 2, 8) -- Complex launch parameters
-- Create explosion effect with area clearing
LaunchAndClearArea(bomb, 8, 6, 4, 0.3, 1.5) -- Radius 8, various launch parameters
Collision System
OnPhysicsCollision(guid1, guid2, world_position_on_a_x, world_position_on_a_y, world_position_on_a_z, world_position_on_b_x, world_position_on_b_y, world_position_on_b_z, world_normal_on_b_x, world_normal_on_b_y, world_normal_on_b_z, lifetime_in_frames)
Status: stable
Description: Engine callback function that handles physics collisions between entities. Automatically called by the engine when two physics objects collide, dispatching to registered callback functions for each entity involved.
Parameters:
guid1
(number): GUID of first entity in collisionguid2
(number): GUID of second entity in collisionworld_position_on_a_x/y/z
(number): World position of collision point on entity Aworld_position_on_b_x/y/z
(number): World position of collision point on entity Bworld_normal_on_b_x/y/z
(number): World normal vector on entity Blifetime_in_frames
(number): Duration of collision in frames
Returns: None
Example:
-- Set up collision detection for a projectile
local function SetupProjectileCollision(projectile)
PhysicsCollisionCallbacks[projectile.GUID] = function(inst, other,
pos_a_x, pos_a_y, pos_a_z,
pos_b_x, pos_b_y, pos_b_z,
normal_x, normal_y, normal_z,
lifetime)
print("Projectile hit " .. (other.prefab or "unknown"))
-- Calculate impact force based on collision normal
local impact_force = math.sqrt(normal_x^2 + normal_y^2 + normal_z^2)
-- Apply damage based on impact
if other.components.health then
other.components.health:DoDelta(-10 * impact_force)
end
-- Create impact effect at collision point
local fx = SpawnPrefab("impact_fx")
fx.Transform:SetPosition(pos_a_x, pos_a_y, pos_a_z)
-- Remove projectile on impact
inst:Remove()
end
end
-- Clean up collision callback when entity is removed
local function CleanupProjectileCollision(projectile)
PhysicsCollisionCallbacks[projectile.GUID] = nil
end
PhysicsCollisionCallbacks
Status: stable
Description: Global table storing collision callback functions indexed by entity GUID. Register functions here to receive collision notifications for specific entities.
Structure:
PhysicsCollisionCallbacks[entity_guid] = callback_function
Example:
-- Advanced collision handling system
local CollisionManager = {}
function CollisionManager:RegisterEntity(entity, collision_type)
local callback_func
if collision_type == "bouncy" then
callback_func = function(inst, other, ...)
-- Bounce off other entities
local vel_x, vel_y, vel_z = inst.Physics:GetVel()
inst.Physics:SetVel(-vel_x * 0.8, vel_y, -vel_z * 0.8)
end
elseif collision_type == "sticky" then
callback_func = function(inst, other, ...)
-- Stick to the first thing we hit
inst.Physics:Stop()
inst:AddTag("stuck")
end
elseif collision_type == "explosive" then
callback_func = function(inst, other, ...)
-- Explode on any collision
LaunchAndClearArea(inst, 5, 8, 6, 0.5, 2)
inst:Remove()
end
end
PhysicsCollisionCallbacks[entity.GUID] = callback_func
-- Cleanup when entity is removed
entity:DoTaskInTime(0, function()
entity:ListenForEvent("onremove", function()
PhysicsCollisionCallbacks[entity.GUID] = nil
end)
end)
end
-- Usage examples
CollisionManager:RegisterEntity(bouncy_ball, "bouncy")
CollisionManager:RegisterEntity(glue_blob, "sticky")
CollisionManager:RegisterEntity(bomb, "explosive")
Collision Mask Management
CollisionMaskBatcher
Status: stable
Description: Helper class for efficiently managing entity collision masks without multiple C++ calls. Allows batching of collision mask operations before committing changes to the Physics component.
Constructor
CollisionMaskBatcher(entormask)
Parameters:
entormask
(Entity|number): Entity to copy mask from, or initial mask value
Methods
ClearCollisionMask()
Description: Clears all collision mask bits.
Returns:
- (CollisionMaskBatcher): Self for method chaining
SetCollisionMask(...)
Description: Sets collision mask bits using bitwise OR operation.
Parameters:
...
(number): Variable number of collision mask constants
Returns:
- (CollisionMaskBatcher): Self for method chaining
CollidesWith(mask)
Description: Adds collision mask bits using bitwise OR operation.
Parameters:
mask
(number): Collision mask to add
Returns:
- (CollisionMaskBatcher): Self for method chaining
ClearCollidesWith(mask)
Description: Removes collision mask bits using bitwise AND NOT operation.
Parameters:
mask
(number): Collision mask to remove
Returns:
- (CollisionMaskBatcher): Self for method chaining
CommitTo(ent)
Description: Applies the batched collision mask changes to the entity's Physics component.
Parameters:
ent
(Entity): Entity to apply collision mask to
Example:
-- Efficient collision mask management for flying creatures
local function SetupFlyingCreature(creature)
CollisionMaskBatcher(creature)
:ClearCollisionMask() -- Start fresh
:CollidesWith(COLLISION.GROUND) -- Collide with ground
:CollidesWith(COLLISION.OBSTACLES) -- Collide with obstacles
:ClearCollidesWith(COLLISION.ITEMS) -- Don't collide with items
:CollidesWith(COLLISION.FLYERS) -- Collide with other flyers
:CommitTo(creature) -- Apply all changes at once
end
-- Dynamic collision mask switching
local function ToggleGhostMode(entity, is_ghost)
local batcher = CollisionMaskBatcher(entity)
if is_ghost then
batcher:ClearCollidesWith(COLLISION.GROUND)
:ClearCollidesWith(COLLISION.OBSTACLES)
:CollidesWith(COLLISION.GHOSTS)
else
batcher:CollidesWith(COLLISION.GROUND)
:CollidesWith(COLLISION.OBSTACLES)
:ClearCollidesWith(COLLISION.GHOSTS)
end
batcher:CommitTo(entity)
end
-- Advanced collision setup for projectiles
local function SetupProjectileCollisions(projectile, projectile_type)
local batcher = CollisionMaskBatcher(0) -- Start with empty mask
-- Base collisions for all projectiles
batcher:CollidesWith(COLLISION.GROUND)
:CollidesWith(COLLISION.OBSTACLES)
-- Type-specific collisions
if projectile_type == "magic" then
batcher:ClearCollidesWith(COLLISION.ITEMS) -- Pass through items
:CollidesWith(COLLISION.CHARACTERS) -- Hit characters
elseif projectile_type == "physical" then
batcher:CollidesWith(COLLISION.ITEMS) -- Interact with items
:CollidesWith(COLLISION.CHARACTERS) -- Hit characters
elseif projectile_type == "ghost" then
batcher:ClearCollidesWith(COLLISION.GROUND) -- Pass through ground
:CollidesWith(COLLISION.GHOSTS) -- Only hit ghosts
end
batcher:CommitTo(projectile)
end
Entity Launching Functions
Launch(inst, launcher, basespeed)
Status: stable
Description: Launches an entity away from a launcher with basic physics parameters. Calculates direction based on relative positions and applies randomized angle variation.
Parameters:
inst
(Entity): Entity to launchlauncher
(Entity): Entity that causes the launch (determines direction)basespeed
(number, optional): Base launch speed (default: 5)
Returns: None
Example:
-- Basic entity launching
local function ExplodeBarrel(barrel)
local x, y, z = barrel.Transform:GetWorldPosition()
local nearby_items = TheSim:FindEntities(x, y, z, 3, {"_inventoryitem"})
for _, item in ipairs(nearby_items) do
if item.Physics and item.Physics:IsActive() then
Launch(item, barrel, 8) -- Launch items at speed 8
end
end
end
-- Launch items from chest when destroyed
local function OnChestDestroyed(chest)
if chest.components.container then
for _, item in pairs(chest.components.container.slots) do
if item then
item.Transform:SetPosition(chest.Transform:GetWorldPosition())
Launch(item, chest, 6) -- Scatter items
end
end
end
end
-- Simple knockback effect
local function KnockbackEntity(target, source, force)
if target.Physics and target.Physics:IsActive() then
Launch(target, source, force or 5)
end
end
Launch2(inst, launcher, basespeed, speedmult, startheight, startradius, vertical_speed, force_angle)
Status: stable
Description: Advanced entity launching with comprehensive control over trajectory, starting position, and velocity components. Provides precise control for complex launching scenarios.
Parameters:
inst
(Entity): Entity to launchlauncher
(Entity): Entity that causes the launchbasespeed
(number): Base horizontal speedspeedmult
(number): Additional random speed multiplierstartheight
(number): Starting height (Y position)startradius
(number): Starting distance from launchervertical_speed
(number, optional): Vertical velocity (default: basespeed * 5 + random)force_angle
(number, optional): Forced launch angle in degrees
Returns:
- (number): Launch angle in radians
Example:
-- Advanced explosion system
local function CreateAdvancedExplosion(center, radius, force)
local x, y, z = center.Transform:GetWorldPosition()
local items = TheSim:FindEntities(x, y, z, radius, {"_inventoryitem"})
for _, item in ipairs(items) do
if item.Physics and item.Physics:IsActive() then
-- Calculate distance-based parameters
local distance = center:GetDistanceSqToInst(item)
local distance_factor = 1 - (distance / (radius * radius))
-- Launch with parameters based on distance
local launch_angle = Launch2(
item, -- item to launch
center, -- explosion center
8 * distance_factor, -- base speed (closer = faster)
4 * distance_factor, -- speed multiplier
0.2, -- start slightly above ground
1, -- start 1 unit from center
12 * distance_factor -- vertical speed
)
-- Add spin based on launch angle
if item.Physics then
local spin_speed = 5 * distance_factor
item.Physics:SetAngularVel(spin_speed)
end
end
end
end
-- Catapult system
local function FireCatapult(catapult, projectile, target_pos, power)
local angle_to_target = catapult:GetAngleToPoint(target_pos:Get())
Launch2(
projectile, -- projectile to fire
catapult, -- catapult as launcher
power * 0.8, -- base speed
power * 0.4, -- speed variation
2, -- start high up
1.5, -- start in front of catapult
power * 1.2, -- high arc
angle_to_target -- aim at target
)
-- Track projectile trajectory
projectile:DoPeriodicTask(0.1, function()
local px, py, pz = projectile.Transform:GetWorldPosition()
if py <= 0.1 then -- Hit ground
-- Create impact effect
LaunchAndClearArea(projectile, 3, 4, 2, 0.1, 0.5)
projectile:Remove()
end
end)
end
-- Volcanic eruption effect
local function CreateVolcanicEruption(volcano, intensity)
local x, y, z = volcano.Transform:GetWorldPosition()
-- Launch multiple projectiles in sequence
for i = 1, intensity do
volcano:DoTaskInTime(i * 0.2, function()
local rock = SpawnPrefab("volcanic_rock")
local random_angle = math.random() * 360
Launch2(
rock, -- volcanic rock
volcano, -- volcano center
15, -- high speed
10, -- high variation
0, -- ground level start
math.random() * 3, -- varying start radius
20 + math.random() * 10, -- very high vertical speed
random_angle -- random direction
)
end)
end
end
LaunchAt(inst, launcher, target, speedmult, startheight, startradius, randomangleoffset)
Status: stable
Description: Launches an entity toward a specific target with randomized angle offset. Useful for creating targeted attacks or guided projectiles with some inaccuracy.
Parameters:
inst
(Entity): Entity to launchlauncher
(Entity): Entity that causes the launchtarget
(Entity, optional): Target to aim at (uses camera direction if nil)speedmult
(number, optional): Speed multiplier (default: 1)startheight
(number, optional): Starting height (default: 0.1)startradius
(number, optional): Starting distance from launcher (default: 0)randomangleoffset
(number, optional): Maximum angle offset in degrees (default: 30)
Returns: None
Example:
-- Targeted magic missile system
local function FireMagicMissile(caster, target, accuracy)
local missile = SpawnPrefab("magic_missile")
-- Calculate accuracy (lower offset = higher accuracy)
local angle_offset = (100 - accuracy) * 0.3 -- 0-30 degrees based on accuracy
LaunchAt(
missile, -- magic missile
caster, -- spell caster
target, -- intended target
2, -- medium speed
1, -- start at waist height
0.5, -- slight offset from caster
angle_offset -- accuracy-based spread
)
-- Add homing behavior after initial launch
missile:DoPeriodicTask(0.1, function()
if target and target:IsValid() then
local missile_pos = missile:GetPosition()
local target_pos = target:GetPosition()
local direction = (target_pos - missile_pos):Normalize()
-- Slight course correction
local current_vel = Vector3(missile.Physics:GetVel())
local corrected_vel = current_vel + direction * 0.5
missile.Physics:SetVel(corrected_vel:Get())
end
end)
end
-- Area bombardment system
local function BombardArea(artillery, center_target, num_shells, spread_radius)
for i = 1, num_shells do
artillery:DoTaskInTime(i * 0.3, function()
local shell = SpawnPrefab("artillery_shell")
-- Create virtual target around the center
local angle = (i / num_shells) * 360 * DEGREES
local spread = math.random() * spread_radius
local virtual_target = {
Transform = {
GetWorldPosition = function()
local cx, cy, cz = center_target.Transform:GetWorldPosition()
return cx + math.cos(angle) * spread, cy, cz + math.sin(angle) * spread
end
},
GetAngleToPoint = function(_, x, y, z)
local tx, ty, tz = center_target.Transform:GetWorldPosition()
return math.atan2(tz - z, tx - x) * RADIANS
end
}
LaunchAt(
shell, -- artillery shell
artillery, -- artillery piece
virtual_target, -- randomized target
3, -- high speed
2, -- high starting point
1, -- start in front of artillery
15 -- moderate spread for area effect
)
end)
end
end
-- Smart enemy projectile system
local function EnemyRangedAttack(enemy, player_target)
local projectile = SpawnPrefab("enemy_projectile")
-- Adjust accuracy based on distance and enemy skill
local distance = enemy:GetDistanceSqToInst(player_target)
local base_accuracy = 20 -- Base spread
local distance_penalty = math.sqrt(distance) * 2 -- More spread at distance
local final_spread = base_accuracy + distance_penalty
LaunchAt(
projectile, -- enemy projectile
enemy, -- attacking enemy
player_target, -- player target
1.5, -- moderate speed
0.8, -- shoulder height
0.3, -- slight forward offset
final_spread -- distance-based accuracy
)
-- Add projectile tracking
projectile.target = player_target
projectile:AddTag("enemy_projectile")
end
Area Destruction Functions
DestroyEntity(ent, destroyer, kill_all_creatures, remove_entity_as_fallback)
Status: stable
Description: Intelligently destroys an entity using the most appropriate method based on its components and tags. Handles workable objects, pickable items, creatures, and fallback removal.
Parameters:
ent
(Entity): Entity to destroydestroyer
(Entity): Entity causing the destructionkill_all_creatures
(boolean): Whether to kill creatures with healthremove_entity_as_fallback
(boolean): Whether to remove entity if other methods fail
Returns: None
Special Handling:
- Workable entities: Uses workable component destruction (trees, rocks, etc.)
- Pickable entities: Picks items instead of destroying them
- Creatures: Kills entities with health if
kill_all_creatures
is true - Combat entities: Kills stationary combat entities
- Fallback: Removes entity if
remove_entity_as_fallback
is true
Example:
-- Smart demolition system
local function DemolishArea(center, radius, demolition_type)
local x, y, z = center.Transform:GetWorldPosition()
local entities = TheSim:FindEntities(x, y, z, radius)
for _, entity in ipairs(entities) do
if entity:IsValid() and entity ~= center then
if demolition_type == "construction" then
-- Only destroy workable structures, preserve creatures and items
DestroyEntity(entity, center, false, false)
elseif demolition_type == "natural_disaster" then
-- Destroy everything including creatures
DestroyEntity(entity, center, true, true)
elseif demolition_type == "harvest" then
-- Gentle destruction that preserves items
DestroyEntity(entity, center, false, false)
elseif demolition_type == "military" then
-- Aggressive destruction but don't remove non-destroyable entities
DestroyEntity(entity, center, true, false)
end
end
end
end
-- Earthquake effect
local function CreateEarthquake(epicenter, magnitude, duration)
local x, y, z = epicenter.Transform:GetWorldPosition()
local max_radius = magnitude * 5
-- Progressive destruction waves
for wave = 1, 5 do
epicenter:DoTaskInTime(wave * (duration / 5), function()
local wave_radius = (wave / 5) * max_radius
local entities = TheSim:FindEntities(x, y, z, wave_radius)
for _, entity in ipairs(entities) do
if entity:IsValid() then
-- Higher chance of destruction closer to epicenter
local distance = entity:GetDistanceSqToInst(epicenter)
local destruction_chance = 1 - (distance / (max_radius * max_radius))
if math.random() < destruction_chance then
DestroyEntity(entity, epicenter, false, false)
-- Add shake effect
if entity.AnimState then
entity.AnimState:SetOffset(
math.random(-0.2, 0.2),
0,
math.random(-0.2, 0.2)
)
entity:DoTaskInTime(0.5, function()
if entity:IsValid() then
entity.AnimState:SetOffset(0, 0, 0)
end
end)
end
end
end
end
end)
end
end
-- Controlled demolition for base clearing
local function ControlledDemolition(structures, delay_between)
delay_between = delay_between or 0.5
for i, structure in ipairs(structures) do
structure:DoTaskInTime(i * delay_between, function()
if structure:IsValid() then
-- Create demolition effect
local fx = SpawnPrefab("demolition_fx")
fx.Transform:SetPosition(structure.Transform:GetWorldPosition())
-- Destroy with force
DestroyEntity(structure, structure, false, true)
print("Demolished: " .. (structure.prefab or "unknown"))
end
end)
end
end
LaunchAndClearArea(inst, radius, launch_basespeed, launch_speedmult, launch_startheight, launch_startradius)
Status: stable
Description: Comprehensive area effect function that destroys entities and launches items within a radius. Creates realistic explosion or impact effects by combining destruction and physics launching.
Parameters:
inst
(Entity): Central entity causing the effectradius
(number): Effect radiuslaunch_basespeed
(number): Base speed for launched itemslaunch_speedmult
(number): Speed multiplier for launched itemslaunch_startheight
(number): Starting height for launched itemslaunch_startradius
(number): Starting radius for launched items
Returns: None
Effect Categories:
- Destroys: Workable objects, pickable items, creatures (based on tags)
- Launches: Inventory items with physics (excludes locomotor entities)
- Special: Deactivates mines before launching
Example:
-- Bomb explosion system
local function CreateBombExplosion(bomb, explosion_power)
local base_radius = explosion_power * 2
local launch_speed = explosion_power * 1.5
-- Create visual explosion effect first
local fx = SpawnPrefab("explosion_fx")
fx.Transform:SetPosition(bomb.Transform:GetWorldPosition())
fx.Transform:SetScale(explosion_power, explosion_power, explosion_power)
-- Launch and clear area
LaunchAndClearArea(
bomb, -- explosion center
base_radius, -- destruction radius
launch_speed, -- base launch speed
launch_speed * 0.5, -- speed variation
0.5, -- items start slightly above ground
1 -- items start 1 unit from center
)
-- Remove the bomb after explosion
bomb:Remove()
end
-- Meteor impact system
local function MeteorImpact(meteor, impact_force)
local x, y, z = meteor.Transform:GetWorldPosition()
-- Create crater effect
local crater = SpawnPrefab("meteor_crater")
crater.Transform:SetPosition(x, y, z)
-- Multiple impact waves
for wave = 1, 3 do
meteor:DoTaskInTime(wave * 0.1, function()
LaunchAndClearArea(
meteor, -- impact center
wave * 3, -- expanding radius
impact_force * (4 - wave), -- decreasing force
impact_force * (4 - wave), -- decreasing variation
wave * 0.2, -- increasing height
wave -- increasing start radius
)
end)
end
meteor:Remove()
end
-- Magical explosion with special effects
local function MagicalExplosion(caster, spell_power, element_type)
local explosion_radius = spell_power * 1.5
-- Pre-explosion effects
local warning_fx = SpawnPrefab("magic_warning")
warning_fx.Transform:SetPosition(caster.Transform:GetWorldPosition())
caster:DoTaskInTime(1, function() -- 1 second warning
warning_fx:Remove()
-- Main explosion
LaunchAndClearArea(
caster, -- spell center
explosion_radius, -- magical radius
spell_power * 2, -- magical force
spell_power, -- force variation
1, -- magical levitation
0.5 -- tight start radius
)
-- Element-specific aftereffects
local x, y, z = caster.Transform:GetWorldPosition()
if element_type == "fire" then
-- Leave burning patches
for i = 1, 5 do
local fire = SpawnPrefab("fire_patch")
local angle = (i / 5) * 360 * DEGREES
local distance = explosion_radius * 0.7
fire.Transform:SetPosition(
x + math.cos(angle) * distance,
y,
z + math.sin(angle) * distance
)
end
elseif element_type == "ice" then
-- Freeze remaining entities
local survivors = TheSim:FindEntities(x, y, z, explosion_radius * 1.2)
for _, survivor in ipairs(survivors) do
if survivor.components.freezable then
survivor.components.freezable:AddColdness(100)
end
end
elseif element_type == "lightning" then
-- Chain lightning to nearby entities
local targets = TheSim:FindEntities(x, y, z, explosion_radius * 2)
for _, target in ipairs(targets) do
if target.components.health then
local lightning = SpawnPrefab("lightning_fx")
lightning.Transform:SetPosition(target.Transform:GetWorldPosition())
end
end
end
end)
end
-- Building collapse system
local function TriggerBuildingCollapse(building, collapse_direction)
local x, y, z = building.Transform:GetWorldPosition()
-- Gradual collapse with directional bias
for stage = 1, 4 do
building:DoTaskInTime(stage * 0.3, function()
if building:IsValid() then
local stage_radius = stage * 2
local directional_offset = collapse_direction * stage
LaunchAndClearArea(
building, -- collapse center
stage_radius, -- expanding destruction
5 + stage, -- increasing force
3, -- consistent variation
0.1 * stage, -- progressive height
1 -- consistent start radius
)
-- Create dust clouds
local dust = SpawnPrefab("dust_cloud")
dust.Transform:SetPosition(
x + directional_offset.x,
y,
z + directional_offset.z
)
end
end)
end
-- Final building removal
building:DoTaskInTime(1.5, function()
if building:IsValid() then
building:Remove()
end
end)
end
Constants and Tags
The module references several important constants and tag sets:
Collision-Related Constants
-- Used in entity destruction and area clearing
COLLAPSIBLE_WORK_ACTIONS = {
CHOP = true, -- Trees and wooden structures
DIG = true, -- Buried or planted items
HAMMER = true, -- Built structures
MINE = true, -- Rocks and mineral deposits
}
COLLAPSIBLE_TAGS = {
"_combat", "pickable", "NPC_workable",
"CHOP_workable", "DIG_workable",
"HAMMER_workable", "MINE_workable"
}
NON_COLLAPSIBLE_TAGS = {
"antlion", "groundspike", "flying", "shadow",
"ghost", "playerghost", "FX", "NOCLICK",
"DECOR", "INLIMBO"
}
TOSS_MUST_TAGS = { "_inventoryitem" }
TOSS_CANT_TAGS = { "locomotor", "INLIMBO" }
Integration Examples
Complete Physics-Based Game System
-- Advanced physics-based interaction system
local PhysicsGameSystem = {}
function PhysicsGameSystem:Initialize()
self.active_explosions = {}
self.collision_handlers = {}
self.launch_effects = {}
end
function PhysicsGameSystem:RegisterExplosive(entity, power, explosion_type)
entity.explosion_power = power
entity.explosion_type = explosion_type
-- Register collision callback for detonation
PhysicsCollisionCallbacks[entity.GUID] = function(inst, other, ...)
if other.components.health or other:HasTag("structure") then
self:TriggerExplosion(inst, inst.explosion_power, inst.explosion_type)
end
end
end
function PhysicsGameSystem:TriggerExplosion(source, power, explosion_type)
local explosion_id = source.GUID .. "_" .. GetTime()
self.active_explosions[explosion_id] = true
if explosion_type == "fragmentation" then
-- Multiple small explosions
for i = 1, power do
source:DoTaskInTime(i * 0.1, function()
LaunchAndClearArea(source, power * 0.5, power * 2, power, 0.3, 0.8)
end)
end
elseif explosion_type == "incendiary" then
-- Fire-based explosion
LaunchAndClearArea(source, power * 1.5, power, power * 0.5, 0.2, 1)
self:CreateFireField(source, power * 2)
elseif explosion_type == "concussive" then
-- High-force, low-damage explosion
LaunchAndClearArea(source, power * 2, power * 3, power * 2, 0.8, 1.5)
else
-- Standard explosion
LaunchAndClearArea(source, power, power * 1.5, power, 0.4, 1)
end
self.active_explosions[explosion_id] = nil
end
function PhysicsGameSystem:CreateChainReaction(entities, reaction_delay)
reaction_delay = reaction_delay or 0.3
for i, entity in ipairs(entities) do
entity:DoTaskInTime(i * reaction_delay, function()
if entity:IsValid() and entity.explosion_power then
self:TriggerExplosion(entity, entity.explosion_power, entity.explosion_type)
end
end)
end
end
return PhysicsGameSystem
Related Modules
- Collision Constants: COLLISION mask constants used in CollisionMaskBatcher
- Entity Script: Base entity functionality for physics entities
- Components: Physics-related components like locomotor and health
- Debug Tools: Physics debugging and visualization tools
- World Generation: World physics setup and configuration
Performance Considerations
- Collision Callbacks: Only register callbacks for entities that need them to avoid unnecessary overhead
- Collision Mask Batching: Use CollisionMaskBatcher for multiple mask operations to reduce C++ calls
- Area Effects: Large radius effects can impact performance - use staged execution for major explosions
- Physics Queries: Entity finding operations in large areas should be used judiciously
- Cleanup: Always remove collision callbacks when entities are destroyed to prevent memory leaks
Security and Safety Notes
- Entity Validation: Always check if entities are valid before performing physics operations
- Null Checks: Verify Physics component exists before calling physics methods
- Cleanup: Properly remove collision callbacks to prevent orphaned references
- Performance: Limit simultaneous large-scale physics operations to maintain frame rate