Force Fields
By Geep, 2021
Introduction
A force field is a volume in space that you derive from a brush. Then, the player or any AI or moveable whose origin is within that field can be potentially moved by it. The movement works as if the object’s origin is also (in the real-world physics sense) its center of mass. This is a reasonable assumption for most objects. For AI, where the origin is at the feet, or collections of bound objects, the behavior does not strictly mimic real-world physics.
On each “think time” tic, the force field is re-evaluated to see which objects are within it, to which a new force might be applied. The location of the object relative to the force field origin is also important in some cases.
Defining a Force Field
Create and size your brush, convert it to func_static and then to func_forcefield. Texture it with common/caulk (not nodraw). Then set the appropriate spawnargs.
Types of Force Fields
There are 3 types of force field. Each has a force defined by a magnitude and direction.
Explosion
Select this by defining this spawnarg:
"explosion" <magnitude as float>
On each evaluation, the direction from the force field origin to the object origin is calculated. This is normalized (so distance between the two origins is ignored), then scaled by the float parameter.
Implosion
Selected by defining spawnarg:
"implosion" <magnitude as float>
Like “explosion”, but the direction is inward towards the force field origin.
Uniform
With spawnarg:
"uniform" <vector3>
The vector you set defines both the magnitude and direction. The force field’s origin is ignored.
If you just want an axis-aligned force, choose one of these, where Mag is a positive value:
- <Mag 0 0> = Push East
- <-Mag 0 0> = Push West
- <0 Mag 0> = Push North
- <0 -Mag 0> = Push South
- <0 0 Mag> = Push Up
- <0 0 -Mag> = Push Down
For other force directions, see Func Forcefields for useful equations.
Meaning of “Magnitude”
There are 4 Types of Magnitude
As Applied Force
Selected by defining spawnarg:
"applyForce 1"
This applies a directed force (adding to any pre-existing force vector, including gravity). As long as the entity is within the force field, this steady force will cause the object (if able to freely move) to accelerate on each time step evaluation.
As Applied Impulse (Original Version)
Selected by defining spawnarg:
"applyImpulse 1"
This causes an instantaneous but one-time boost [I’m assuming] to linear momentum (which is a vector given by the object’s mass multiplied by its velocity vector). So for two objects traveling side by side at the same speed, and receiving the same impulse, the lighter object’s velocity will be more affected. [I’m assuming] after an object is thrown out of a force field and then falls back in, the impulse will be applied again to it.
As Applied Impulse (Newer Version)
Selected by defining these spawnargs:
"applyImpulse 1"
"scaleImpulse 1"
For objects with mass less than that of the player (typically 70), the magnitude is scaled down proportionately, to give more realistic behavior.
As Applied Velocity
Selected by defining neither “applyForce 1” nor “applyImpulse 1”.
Basically, this sets a constant speed for as long as the entity is within the force field’s boundary.
Angular Rotation
Consistent with the assumption that the force vector is being applied through the center of mass, no angular motions are created by the above (though it can arise after collisions). So to fake up some turbulent spinning action even without collisions:
randomTorque <magnitude as float>
This is applied (in different ways) by all the variations. But essentially, a torque direction is chosen at random each time step, scaled by the randomTorque magnitude, and combined with the torque from the previous time step. This causes the spinning to flop around with time. When the entity leaves the force field’s boundary, the spinning becomes fixed.
Other Spawnargs
- "playerOnly 1". Force affects only player, not AI or other entities.
- "monsterOnly 1". Force does not affect player or non-AI entities.
- "start_on". Force field is activated at world spawn.
- "wait". Time in seconds from activation to begin evaluations.
Script Calls
<$forcefield>.Activate(); // turn on
<$forcefield>.Toggle(); // turns on and off
See Also
The information presented here is primarily based on a 2019 review of the TDM 2.07 source code found in physics/Force_Field.cpp & .h, and the idForceField sections of Misc.cpp.
Func_Forcefields has an early TDM treatment from Ishtvan.
Ivan_the_B’s ModDB Doom3 Tutorial 04 – Forcefields, about creating a “jump pad” (upwards forcefield).