Effects pools¶
This page tracks the smaller effect pools used for weapon and perk visuals.
Particle pool (particle_pool / DAT_00493eb8)¶
Entry size: 0x38 bytes. Pool size: 0x80 entries (looping to 0x495ab8).
Field arrays are labeled in the data map (e.g. particle_pos_x, particle_vel_y,
particle_style_id, particle_target_id) at particle_pool + offsets.
Spawn helpers:
FUN_00420130->fx_spawn_particle(fast variant, speed ~90)FUN_00420240->fx_spawn_particle_slow(slow variant, speed ~30)
Layout (partial):
| Offset | Field | Evidence |
|---|---|---|
| 0x00 | active (byte) | Set to 1 on spawn; cleared by update/render when expired. |
| 0x01 | render flag | Set to 1 on spawn; referenced in render loops. |
| 0x04 | pos_x | Written from *param_1 on spawn. |
| 0x08 | pos_y | Written from param_1[1] on spawn. |
| 0x0c | vel_x | cos(angle) * 90 or *30 on spawn. |
| 0x10 | vel_y | sin(angle) * 90 or *30 on spawn. |
| 0x14 | scale_x | Initialized to 1.0 on spawn. |
| 0x18 | scale_y | Initialized to 1.0 on spawn. |
| 0x1c | scale_z | Initialized to 1.0 on spawn. |
| 0x20 | age / timer | Zeroed on spawn. |
| 0x24 | intensity | param_4 (fast) or 1.0 (slow). |
| 0x28 | angle | Written from param_2 on spawn. |
| 0x2c | spin | Random rand % 0x274 * 0.01. |
| 0x30 | style id | Set to 0, 1, 2, or 8 at callsites. |
| 0x34 | target id | Set to -1 in slow variant. |
Known style ids (particle pool)¶
| style id | Source | Notes |
|---|---|---|
0 |
Plasma Rifle (weapon id 0x9) |
Default fast particle from fx_spawn_particle. |
1 |
HR Flamer (weapon id 0x10) |
fx_spawn_particle plus DAT_00493ee8 = 1. |
2 |
Mini-Rocket Swarmers (weapon id 0x11) |
fx_spawn_particle plus DAT_00493ee8 = 2. |
8 |
Rainbow Gun (weapon id 0x2b) |
Slow particle (fx_spawn_particle_slow). |
Secondary projectile pool (secondary_projectile_pool / DAT_00495ad8)¶
Entry size: 0x2c bytes. Pool size: 0x40 entries (looping to 0x4965d8).
Field arrays are labeled in the data map (e.g. secondary_proj_pos_x,
secondary_proj_type_id, secondary_proj_target_id) at secondary_projectile_pool + offsets.
Spawn helper:
FUN_00420360->fx_spawn_secondary_projectile
Layout (partial):
| Offset | Field | Evidence |
|---|---|---|
| 0x00 | active (byte) | Set to 1 on spawn; cleared in projectile_update. |
| 0x04 | angle | Set from param_2. |
| 0x08 | speed | Initialized to 2.0 on spawn. |
| 0x0c | pos_x | Written from *param_1 on spawn. |
| 0x10 | pos_y | Written from param_1[1] on spawn. |
| 0x14 | vel_x | cos(angle - PI/2) * 90 (or *190 for type 2). |
| 0x18 | vel_y | sin(angle - PI/2) * 90 (or *190 for type 2). |
| 0x1c | type id | Spawn parameter; branches in projectile_update. |
| 0x20 | lifetime | Zeroed on spawn; decremented in update. |
| 0x24 | target id | Set to nearest creature when type_id == 2. |
projectile_update (FUN_00420b90) advances and damages creatures for this pool, and the render path
in the same function draws the sprite variants based on type id.
Type id behaviors (secondary pool)¶
| type id | Behavior | Sources |
|---|---|---|
1 |
Straight projectile; accelerates while speed < ~500; lifetime decays at 1.0x. On hit or timeout, switches to type 3 detonation with base scale 1.0. |
Seeker Rockets (weapon id 0x0d). |
2 |
Homing projectile; targets nearest creature and steers toward it (velocity += 800 * dt, capped ~350). Lifetime decays at 0.5x. On hit or timeout, switches to type 3 detonation with base scale 0.35. |
Plasma Shotgun (weapon id 0x0e), Rocket Minigun (weapon id 0x12). |
4 |
Straight projectile; accelerates while speed < ~600; lifetime decays at 1.0x. On hit or timeout, switches to type 3 detonation with base scale 0.25. |
Pulse Gun (weapon id 0x13). |
3 |
Detonation state; expands over ~1s, applies radial damage each tick, spawns fx_queue_add(0x10) and clears when the timer > 1.0. |
Triggered by types 1/2/4 or when their lifetime expires. |
Render notes:
- Base pass sizes in
projectile_render: type1draws14x14, type2draws10x10, type4draws8x8(all fromprojs.png, atlas frame4,3).
FX queue (fx_queue / DAT_004912b8)¶
Entry size: 0x28 bytes. Queue size: 0x80 entries (index 0..0x7f via fx_queue_count).
Field arrays are labeled in the data map (e.g. fx_queue_pos_x, fx_queue_color_a)
at fx_queue + offsets.
This queue is written by fx_queue_add (FUN_0041e840) and rendered (then
cleared) by fx_queue_render once per frame.
Layout (struct view of the SoA block):
| Offset | Field | Evidence |
|---|---|---|
| 0x00 | effect_id | Stored by fx_queue_add; passed into effect_select_texture in fx_queue_render. |
| 0x04 | rotation | Stored by fx_queue_add; passed to grim_set_rotation. |
| 0x08 | pos_x | Stored from pos[0] in fx_queue_add. |
| 0x0c | pos_y | Stored from pos[1] in fx_queue_add. |
| 0x10 | height | Stored from h in fx_queue_add; used as draw height. |
| 0x14 | width | Stored from w in fx_queue_add; used as draw width. |
| 0x18 | color_r | Stored from rgba[0] in fx_queue_add. |
| 0x1c | color_g | Stored from rgba[1] in fx_queue_add. |
| 0x20 | color_b | Stored from rgba[2] in fx_queue_add. |
| 0x24 | color_a | Stored from rgba[3] in fx_queue_add. |
Notes:
effect_select_textureresolveseffect_idthrougheffect_id_size_code/effect_id_frameand sets atlas size/frame (0x10/0x20/0x40/0x80->16/8/4/2cells).fx_queue_add_randomis a small helper that spawns a randomfx_queue_addentry (effect ids3..7) with randomized grayscale color and size; it uses thefx_queue_random_color_*scratch RGBA globals.fx_queue_addclamps the queue length to0x7fif the caller overflows it.
Rotated FX queue (fx_queue_rotated / DAT_004aaf3c)¶
Queue size: 0x40 entries. Written by fx_queue_add_rotated (FUN_00427840)
and rendered by fx_queue_render.
Backing arrays are labeled in the data map (e.g. fx_rotated_pos_x, fx_rotated_color_a,
fx_rotated_effect_id).
Layout (structure-of-arrays):
| Array base | Field | Notes |
|---|---|---|
DAT_00490430 |
pos_x | Stride 2 floats. |
DAT_00490434 |
pos_y | Stride 2 floats. |
DAT_0049bb38 |
color_r | Stride 4 floats. |
DAT_0049bb3c |
color_g | Stride 4 floats. |
DAT_0049bb40 |
color_b | Stride 4 floats. |
DAT_0049bb44 |
color_a | Stride 4 floats; scaled by view factor in fx_queue_add_rotated. |
DAT_0049669c |
rotation | Stored from rotation in fx_queue_add_rotated. |
DAT_004906a8 |
scale | Stored from scale in fx_queue_add_rotated. |
DAT_0049ba30 |
effect_id | Used to index the atlas table in fx_queue_render. |
Notes:
fx_queue_renderbindsbodyset_texture(DAT_0048f7dc) and mapseffect_idthrough the creature type table:frame = *(int *)(&DAT_00482764 + effect_id * 0x44). That offset is the per‑typecorpse frame(seedocs/creature-struct.md), and the frame is converted to UVs via the 4x atlas tables (effect_uv4_u/effect_uv4_v).- The rotated queue is drawn in two passes: the first uses half alpha and a
slightly inflated size (
scale * 1.064), the second uses full alpha/size. fx_queue_add_rotatedskips enqueuing whenDAT_004871c8 != 0or the queue is full.
Effect entries (effect_pool_pos_x pool)¶
Entry size: 0xbc bytes (0x2f floats). Free list head: effect_free_list_head
with next pointer at offset 0xb8.
Spawn/update helpers:
effect_spawn(FUN_0042e120) allocates an entry and seeds UVs for the selected atlas frame.effects_update(FUN_0042e710) advances timers/velocities and frees expired entries.effects_render(FUN_0042e820) draws active entries.
Layout (partial):
| Offset | Field | Evidence |
|---|---|---|
| 0x00 | pos_x | Set from pos[0] in effect_spawn; advanced in effects_update. |
| 0x04 | pos_y | Set from pos[1] in effect_spawn; advanced in effects_update. |
| 0x08 | effect_id (byte) | Stored in effect_spawn; used when expiring to call fx_queue_add. |
| 0x0c | vel_x | pos_x += vel_x * dt in effects_update. |
| 0x10 | vel_y | pos_y += vel_y * dt in effects_update. |
| 0x14 | rotation | Used in effects_render; updated when flags & 0x4 using 0x40. |
| 0x18 | scale | Used in effects_render; updated when flags & 0x8 using 0x44. |
| 0x1c | half_width | Doubled when queuing the expiry sprite. |
| 0x20 | half_height | Doubled when queuing the expiry sprite. |
| 0x24 | age | Incremented by dt in effects_update. |
| 0x28 | lifetime | Compared against age in effects_update. |
| 0x2c | flags | 0x4 updates rotation via 0x40; 0x8 updates scale via 0x44; 0x10 fades alpha; 0x40 draws in the first effects_render batch; 0x80 spawns fx_queue_add on expiry; 0x100 selects a dimmer expiry alpha. |
| 0x30 | color_r | Initialized to 1.0; passed into fx_queue_add. |
| 0x34 | color_g | Initialized to 1.0; passed into fx_queue_add. |
| 0x38 | color_b | Initialized to 1.0; passed into fx_queue_add. |
| 0x3c | color_a | Initialized to 1.0; 0x10 flag drives fade-out. |
| 0x40 | rotation_step | Added into rotation when flags & 0x4. |
| 0x44 | scale_step | Added into scale when flags & 0x8. |
| 0x48 | quad vertex data | effect_spawn writes four corners (pos + UVs) using half_width/half_height and the atlas tables. |
Notes:
effect_spawnfills a 4‑corner quad starting at0x48. The position and UV components are spaced with a 7‑float stride, leaving three unknown floats between the position and UV fields for each corner.effects_rendersplits entries byflags & 0x40. Both passes build a 2x2 rotation/scale matrix fromrotation+scaleand draw the quad data starting at0x48.effect_free(FUN_0042e080) clearsflagsto0and pushes the entry back onto the free list; the flag presets always include bit0x1to keepflagsnonzero while active.
Common flag presets (from the template helpers that seed DAT_004ab1dc):
| Flags | Bits present | Notes |
|---|---|---|
0x19 |
0x1 + 0x8 + 0x10 |
Base preset with scale step + alpha fade. |
0x1d |
0x1 + 0x4 + 0x8 + 0x10 |
Adds rotation step to the base preset. |
0x59 |
0x1 + 0x8 + 0x10 + 0x40 |
Base preset rendered in the first batch (flags & 0x40). |
0x5d |
0x1 + 0x4 + 0x8 + 0x10 + 0x40 |
Rotating variant rendered in the first batch. |
0xc9 |
0x1 + 0x8 + 0x40 + 0x80 |
First-batch preset that spawns a queue entry on expiry. |
0x1cd |
0x1 + 0x4 + 0x8 + 0x40 + 0x80 + 0x100 |
As above, but uses the dim expiry alpha (0x100). |
Quad layout (from effect_spawn writes):
| Corner | pos offsets | uv offsets | Values |
|---|---|---|---|
| 0 | 0x48/0x4c |
0x5c/0x60 |
(-half_w, -half_h) + (u0, v0) |
| 1 | 0x64/0x68 |
0x78/0x7c |
( half_w, -half_h) + (u1, v0) |
| 2 | 0x80/0x84 |
0x94/0x98 |
( half_w, half_h) + (u1, v1) |
| 3 | 0xa0/0xa4 |
0xb0/0xb4 |
(-half_w, half_h) + (u0, v1) |
effect_spawnreadseffect_id_size_code/effect_id_frameto pick atlas size + frame index, then pulls UVs from size-specific tables:0x10->effect_uv16_u/effect_uv16_vwith baseeffect_uv_step_16.0x20->effect_uv8_u/effect_uv8_vwith baseeffect_uv_step_8.0x40->effect_uv4_u/effect_uv4_vwith baseeffect_uv_step_4.0x80->effect_uv2_u/effect_uv2_vwith baseeffect_uv_step_2.effect_spawncopies 15 floats from the template block ateffect_template_vel_xinto offsets0x0c..0x44(see template map below).
Effect template block (effect_template_vel_x)¶
These globals act as a staging area for effect_spawn. They are copied into
the effect entry (offsets 0x0c..0x44) before the UVs are assigned.
| Template | Entry offset | Meaning |
|---|---|---|
effect_template_vel_x |
0x0c | vel_x |
effect_template_vel_y |
0x10 | vel_y |
effect_template_rotation |
0x14 | rotation |
effect_template_scale |
0x18 | scale |
effect_template_half_width |
0x1c | half_width |
effect_template_half_height |
0x20 | half_height |
effect_template_age |
0x24 | age |
effect_template_lifetime |
0x28 | lifetime |
effect_template_flags |
0x2c | flags |
effect_template_color_r |
0x30 | color_r |
effect_template_color_g |
0x34 | color_g |
effect_template_color_b |
0x38 | color_b |
effect_template_color_a |
0x3c | color_a |
effect_template_rotation_step |
0x40 | rotation_step |
effect_template_scale_step |
0x44 | scale_step |
Effect id table (effect_id_size_code)¶
Entry size: 0x08 bytes. Indexed by effect_id.
effect_select_texture (FUN_0042e0a0) reads this table and calls the renderer
with grid sizes 16/8/4/2 depending on the size code (0x10/0x20/0x40/0x80).
| Offset | Field | Evidence |
|---|---|---|
| 0x00 | atlas size code | Read by effect_select_texture/effect_spawn; values 0x10/0x20/0x40/0x80 map to 16/8/4/2 cell atlases. |
| 0x04 | frame index | Read by effect_select_texture/effect_spawn; selects the atlas frame. |
Known entries (extracted from crimsonland.exe at effect_id_size_code):
| effect_id | size code | frame |
|---|---|---|
0x00 |
0x80 |
0x2 |
0x01 |
0x80 |
0x3 |
0x02 |
0x20 |
0x0 |
0x03 |
0x20 |
0x1 |
0x04 |
0x20 |
0x2 |
0x05 |
0x20 |
0x3 |
0x06 |
0x20 |
0x4 |
0x07 |
0x20 |
0x5 |
0x08 |
0x20 |
0x8 |
0x09 |
0x20 |
0x9 |
0x0a |
0x20 |
0xa |
0x0b |
0x20 |
0xb |
0x0c |
0x40 |
0x5 |
0x0d |
0x40 |
0x3 |
0x0e |
0x40 |
0x4 |
0x0f |
0x40 |
0x5 |
0x10 |
0x40 |
0x6 |
0x11 |
0x40 |
0x7 |
0x12 |
0x10 |
0x26 |
Effect id usage (partial)¶
| effect_id | Call sites | Notes |
|---|---|---|
0 |
bonus_spawn_at, FUN_0042ef60, FUN_0042f080, FUN_0042f3f0, FUN_0042f540, effect_spawn_explosion_burst, FUN_004207c0 |
Generic burst/spark effects (used for bonus pickup and explosions). |
1 |
bonus_apply (Reflex Boost/Freeze), FUN_0042f080, FUN_0042f270, FUN_0042f330, effect_spawn_explosion_burst |
Power-up ring/halo style effects. |
7 |
effect_spawn_blood_splatter |
Blood splatter burst used by hit effects. |
8..10 |
effect_spawn_freeze_shard |
Randomized variant picks (iVar3 % 3 + 8). |
0xc |
effect_spawn_explosion_burst |
Used during large explosion sequences. |
0xe |
effect_spawn_freeze_shatter |
Four-way burst helper. |
0x11 |
effect_spawn_explosion_burst |
Extra burst when difficulty is high. |
0x12 |
player_update (FUN_004136b0) |
Muzzle flash path when weapon flag 0x1 is set (grid 16, frame 0x26 in particles.png; sprite resembles a shell casing). |
Effect template helpers (partial)¶
These helpers primarily configure effect_template_vel_x and then call effect_spawn.
| Function | Effect ids | Notes |
|---|---|---|
effect_spawn_blood_splatter |
7 |
Spawns two bursts with randomized direction/size; used in projectile/chain effects. |
effect_spawn_freeze_shard |
8..10 |
Picks a random variant (iVar3 % 3 + 8); used by freeze/shatter logic. |
effect_spawn_freeze_shatter |
0xe, 8..10 |
Four-way burst (0xe) plus additional effect_spawn_freeze_shard calls. |
FUN_0042ef60 |
0 |
Generic burst loop with randomized velocity. |
FUN_0042f080 |
1, 0 |
Ring + burst combo used for power-up visuals. |
FUN_0042f270 |
1 |
Single ring burst. |
FUN_0042f330 |
1 |
Single ring burst with different color/alpha defaults. |
FUN_0042f3f0 |
0 |
Radial scatter of bursts (count parameter). |
FUN_0042f540 |
0 |
Scaled burst loop used for explosions. |
effect_spawn_explosion_burst |
1, 0x11, 0, 0xc |
Large multi-stage explosion effect. |
Sprite effect pool (sprite_effect_pool / DAT_00496820)¶
Entry size: 0x2c bytes. Pool size: 0x180 entries (looping to 0x49aa20).
Field arrays are labeled in the data map (e.g. sprite_effect_pos_x,
sprite_effect_color_a, sprite_effect_scale) at sprite_effect_pool + offsets.
Spawn helper:
FUN_0041fbb0->fx_spawn_sprite
Layout (partial):
| Offset | Field | Evidence |
|---|---|---|
| 0x00 | active (byte) | Set to 1 on spawn; cleared when lifetime reaches zero. |
| 0x04 | color_r | Initialized to 1.0 on spawn; passed into render color. |
| 0x08 | color_g | Initialized to 1.0 on spawn; passed into render color. |
| 0x0c | color_b | Initialized to 1.0 on spawn; passed into render color. |
| 0x10 | color_a / lifetime | Initialized to 1.0 on spawn, decremented by dt; when it reaches <= 0 the entry is deactivated. Also passed into render color alpha. |
| 0x14 | rotation | Seeded from rand, incremented by dt * 3.0, passed into grim_set_rotation. |
| 0x18 | pos_x | Written from param_1[0]; advanced by vel_x each tick. |
| 0x1c | pos_y | Written from param_1[1]; advanced by vel_y each tick. |
| 0x20 | vel_x | Written from param_2[0]; scaled by DAT_00480840 in update. |
| 0x24 | vel_y | Written from param_2[1]; scaled by DAT_00480840 in update. |
| 0x28 | scale / size | Written from param_3; incremented by dt * 60.0 before render, but not referenced in the current render path. |
Notes:
- Render is gated by
DAT_00480359and bindsparticles_texture(DAT_0048f7ec) with a fixed 4x atlas UV (effect_uv4_u/effect_uv4_v+0x38), then draws each active entry with the per-entry rotation and RGBA.
Common color overrides (callers mutate the RGBA fields after spawning):
| Override | Fields | Notes |
|---|---|---|
| dim spark | color_r/g/b = 0.5, color_a = 0.25 |
Used by projectile detonation sparks (FUN_00420b90). |
| soft burst | color_a = 0.37 |
Used by radial burst loops (FUN_00420b90). |
| mid alpha | color_a = 0.7 |
Used by periodic spark spawns (FUN_00420b90). |