Particle Script

Revision as of 01:47, 21 February 2015 by imported>Jackoalan (Added layout section)
This file format is almost completely documented
Details are subject to corrections


Retro games feature a uniform, fixed-function Effect Script system for describing various geometrical effects and weapon systems. The PAK archives contain binary resources using FourCCs to build a key-value dictionary. These codes correspond to application-specific parameters controlling the effect system in question.

The binary script format uses a grammar that supports bool, int, float, float3, and float4 parameters to be evaluated and assigned to the dictionary. In addition, the various effect systems provide dynamic node classes that are evaluated as part of the effect runtime. Ultimately, the systems use a recursive, node-based approach of generating animated scalar and vector values to control the effect.

File Layout

All effect script file formats use a context-sensitive, free-form layout to build the key-value dictionary.

  • Script Magic FourCC (see table below)
  • Entries
    • Key FourCC (see script-format articles)
    • Value Parameter(s) (one of:)
      • CNST: Scalar/Vector literal
        • 1-4 int/float values
      • NONE: Dummy value (equivalent to not specifying the key at all)
      • Node Key (see below)
        • Node Parameters
  • _END

Script Types

Type Magic Purpose
PART GPSM Particle effect
SWHC SWSH Swoosh effect
ELSC ELSM Electric effect
DPSC DPSM Decal effect
WPSC WPSM Projectile weapon configuration
CRSC CRSM Projectile collision response configuration

Script Nodes

Many of the animated qualities from effect scripts are achieved with dynamic script nodes. These nodes provide parameter I/O interfaces and internally process numeric data that passes through. They may also gather data from other sources within the effect system.

Scope is one of (Constant, System, Particle, Auto)

  • Constant parameters are evaluated once initially and retained within the system.
  • System parameters are evaluated per-system, per-frame.
  • Particle parameters are evaluated per-system, per-frame, per-particle-instance.
  • Auto parameters select their scope based on the node's parent context.
Signature Scope Description Notes
SETR(ILOC=float3 location_vector, IVEC=float3 velocity_vector) System Point emitter Used with EMTR attachment to produce particle instances
SEMR(float3 location_vector, float3 velocity_vector) System Point emitter Seems to be similar to SETR
SPHE(float3 local_sphere_origin, float radius, float radial_velocity) System Sphere emitter Emits particles from a sphere-surface
ASPH(float3 local_sphere_origin, float x_ang_bias, float y_ang_bias, float x_ang_range, float y_ang_range, float radius, float radial_velocity) System Partial sphere emitter Emits particles from a sphere-surface section
float SCAL(float value) Particle Linear-lifetime interpolator Interpolates from 0.0 to value over particle's lifetime
int/float/float3/float4 ADD(int/float/float3/float4 a, int/float/float3/float4 b) Auto Value adder Dynamically adds two parameters
int/float/float3/float4 SUB(int/float/float3/float4 a, int/float/float3/float4 b) Auto Value subtractor Dynamically subtracts two parameters
int/float/float3/float4 MULT(int/float/float3/float4 a, int/float/float3/float4 b) Auto Value multiplier Dynamically multiplies two parameters
float CLMP(float low, float high, float val) Auto Value clamp Dynamically clamps val between low and high
int RLPT(float lifetime_percent) Particle Resolve frame-index from lifetime percentage Computes the frame on which the particle will reach a specified lifetime-percent (0-100)
float ISWT(float c, float v) Auto Linear equation evaluator Evaluates v * frame_index + c
int/float RAND(int/float low, int/float high) System Pseudo-random number generator Generates a random number between low and high
int/float IRND(int/float low, int/float high) Particle Instance-cached pseudo-random number generator Generates a random number between low and high and retains the value for each particle instance
float LFTW(float a, float b) Particle Triangle-wave generator Generates a triangle-wave cycle over the particle instance's lifetime. Evaluates a at 0% lifetime, b at 50% lifetime, then back to a at 100% lifetime
int/float/float3/float4 CHAN(int/float/float3/float4 a, int/float/float3/float4 b, int f) Particle Time-based parameter switch Evaluates a before particle instance reaches frame index f; evaluates b afterwards
float3 RTOV(float val) Auto Scalar to vector (vector splat) Constructs a 3-component vector using val for each component
int/float/float3/float4 PULS(int pulse_start_frame, int pulse_frame_count, int/float/float3/float4 a, int/float/float3/float4 b) Particle Pulsing duty-cycle switch (periodic CHAN) Evaluates a until pulse_start_frame is reached, then evaluates b for pulse_frame_count frames. This cycle repeats indefinitely
float SINE(float magnitude, float v, float c) Auto Animated sine function v and c are in degrees. Evaluates sin(v * frame_index + c) * magnitude
int/float/float3/float4 KEYE(<key-array>) System Emitter-based key array Stores an array of values; one for each frame of the emitter's lifetime; with clamped-extrapolation
int/float/float3/float4 KEYP(<key-array>) Particle Particle-based key array Stores an array of 100 values; one for each percentage point of the particle instance's lifetime
float PAPn() Auto ADVn access token (1-8) Access the value evaluated for one of the ADVn keys in the particle system
float PSLL()
float PRLW()
float PSOF()
float VMAG(float3 v) Auto Vector magnitude calculator Evaluates sqrt(v.x^2 + v.y^2, v.z^2)
float CLTN(float ca, float cb, float a, float b) Auto Less-than evaluator switch If ca < cb then evaluates a, else b
float CEQL(float ca, float cb, float a, float b) Auto Equal evaluator switch If ca == cb then evaluates a, else b
float VXTR(float3 vec) Auto X component of vector Extracts X component of vector
float VYTR(float3 vec) Auto Y component of vector Extracts Y component of vector
float VZTR(float3 vec) Auto Z component of vector Extracts Z component of vector
float CEXT(int val)
float ITRL(float val)
float GTCP(int val)
float MODU(float numerator, float denominator) Auto Floating-point modulo Dynamically evaluates remainder-division as numerator % denominator
int ILPT(int val) Particle Clamp to particle frame-count Clamps val to count of frames in particle instance
float4 FADE(float4 a, float4 b, float t) Particle Time-based (0-end) linear interpolator Interpolates from a to b over particle instance's first t frames
float4 CFDE(float4 a, float4 b, float s, float e) Particle Time-based (start-end) linear interpolator Interpolates from a to b between particle instance's s and e frames
float3 ANGC(float x_bias, float z_bias, float x_ang, float z_ang, float magnitude) Auto Spherical-section random vector generator Generates a vector of magnitude adhering to the XZ-angular constraints provided
float3 CIRC(float3 circle_offset, float3 circle_normal, float angle_bias, float angle_range, float magnitude) Auto Circular-section random vector generator Generates a vector of magnitude adhering to the circular constraints provided
float3 CONE(float3 cone_vector, float base_radius) Auto Cone random vector generator Generates a random vector from the cone's tip to somewhere within its base
WIND(float3 wind_vector, float drift_magnitude) Particle Wind velocity source Integrates a non-accelerated force simulating directional wind with a randomized drift
GRAV(float3 grav_vector) Particle Gravity velocity source Integrates a continuously-accelerated force simulating gravitational pull
SWRL(float3 helix_start, float3 helix_end, float angular_vel, float linear_vel) Particle Swirl velocity source Integrates a helically-shaped force simulating a 'swirling' motion
BNCE(float3 plane_point, float3 plane_normal, float ?, float ?, bool ?) Particle Bounce velocity source Establishes a local plane in the system for particles to bounce off
EXPL(float initial_velocity, float velocity_damping) Particle Explosion velocity source Moves particle away from emitted position at initial_velocity while continuously applying velocity_damping
IMPL(float3 implosion_point, float force, float ?, float ?, bool ?) Particle Implosion velocity source?
EMPL(float3 point, float force, float ?, float ?, bool ?) Particle
LMPL(float3 point, float force, float ?, float ?, bool ?) Particle
float3 SPOS(float3 vec) Particle Position delta Subtract from current particle instance position
float3 PLCO() Particle World Position Evaluate particle world position
float3 PLOC() Particle Local Position Evaluate particle local (emitter-space) position
ATEX(int seg_w, int seg_h, int ?, int ?, int frame_rate, bool loop) Particle Animated texture attachment Used in particle script's TEXR key to apply a UV-scanned animated texture