1. Architectural Role & Engine Purpose
The BEF (Binary Effect File) format specifies particle system emitters, physical forces, and visual lifetimes in Project I.G.I. 1.
BEF files control complex visual effects such as smoke billowing from destroyed tanks, fiery explosions, rainstorms, snow flurries, industrial steam vents, and electrical sparks from severed power boxes.
2. Binary File Layout & Memory Map Diagram
A BEF file contains an effect definition header followed by an array of particle emitter parameters:
3. Particle Physics Simulation & Billboard Pipeline Diagram
Active particle emitters simulate Newtonian physics per particle and batch camera-facing billboard quads:
4. Architectural Mechanics & Engine Implementation Details
The BEF particle architecture provided high-density atmospheric effects on 2000 hardware:
- Circular Ring Buffers: Active particles are stored in fixed-size contiguous memory rings. When a particle expires, its slot is immediately reused, eliminating runtime dynamic memory allocation.
- Wind Force Interaction: The global level wind vector is added directly to particle acceleration during the Euler integration step, causing chimney smoke and snow to drift realistically.
5. C++ Struct Definitions
#pragma pack(push, 1)
struct BefHeader {
char magic[4]; // "BEF "
uint32_t version; // Format version
uint32_t emitter_count; // Number of emitter definitions
float duration; // Effect lifetime in seconds
};
struct BefEmitter {
uint32_t max_particles; // Max concurrent particles
float emission_rate; // Particles spawned per second
float vel_min[3]; // Minimum spawn velocity XYZ
float vel_max[3]; // Maximum spawn velocity XYZ
float gravity[3]; // Acceleration vector
float life_min; // Minimum particle lifetime in seconds
float life_max; // Maximum particle lifetime in seconds
uint32_t color_start; // Initial RGBA8888 color
uint32_t color_end; // Final RGBA8888 color
float scale_start; // Initial billboard size
float scale_end; // Final billboard size
uint32_t sprite_id; // Sprite resource index
uint32_t blend_mode; // 0=Alpha, 1=Additive
};
static_assert(sizeof(BefHeader) == 16, "BefHeader must be 16 bytes");
#pragma pack(pop)