Download docs/re-notes/task-hierarchy.md from nmarshall/wormz-a: direct link, hf CLI and curl.
- Browser
- Download file 6.63 kB
-
https://huggingface.co/nmarshall/wormz-a/resolve/main/docs/re-notes/task-hierarchy.md
- Command line
-
hf download hf://nmarshall/wormz-a/docs/re-notes/task-hierarchy.md
-
curl -L -o task-hierarchy.md https://huggingface.co/nmarshall/wormz-a/resolve/main/docs/re-notes/task-hierarchy.md
Task Hierarchy - Worms Armageddon 3.8.1
Overview
WA uses a hierarchical task/entity system. All game objects inherit from CTask,
which forms a tree via parent/children pointers. Tasks communicate through a
message passing system (see TaskMessage enum).
Class Hierarchy
CTask (base) vtable: 0x669F8C ctor: 0x5625A0
βββ CGameTask vtable: 0x6641F8 ctor: 0x4FED50
β βββ CTaskWorm ctor: 0x50BFB0
β βββ CTaskOldWorm ctor: 0x51FEB0
β βββ CTaskMissile ctor: 0x507D10
β βββ CTaskArrow ctor: 0x4FE130
β βββ CTaskMine ctor: 0x506660
β βββ CTaskCanister ctor: 0x501A80
β βββ CTaskCrate ctor: 0x502490
β βββ CTaskOilDrum ctor: 0x504AF0
β βββ CTaskCross ctor: 0x5045C0
β βββ CTaskLand ctor: 0x505440
βββ CTaskFilter ctor: 0x54F3D0
βββ CTaskTeam ctor: 0x555BB0
βββ CTaskTurnGame ctor: 0x55B280
βββ CTaskAirStrike ctor: 0x5553C0
βββ CTaskDirt ctor: 0x54EDC0
βββ CTaskFlame ctor: 0x54F0F0
βββ CTaskFire ctor: 0x54F4C0
βββ CTaskGirder (was CTaskFireBall) ctor: 0x550890
βββ CTaskGas ctor: 0x554750
βββ CTaskSmoke ctor: 0x5551D0
βββ CTaskCloud ctor: 0x5482E0
βββ CTaskSeaBubble ctor: 0x554FE0
βββ CTaskScoreBubble ctor: 0x554CA0
βββ CTaskCPU ctor: 0x5485D0
βββ CTaskSpriteAnimation ctor: 0x5466C0
Note: Not all tasks are confirmed to inherit from CGameTask. The hierarchy above needs further verification via Ghidra analysis of each constructor.
CTask vtable (0x669F8C)
| Index | Offset | Address | Name (from wkJellyWorm) |
|---|---|---|---|
| 0 | 0x00 | 0x562710 | vtable0 (init?) |
| 1 | 0x04 | 0x562620 | Free |
| 2 | 0x08 | 0x562F30 | HandleMessage |
| 3 | 0x0C | 0x5613D0 | unknown |
| 4 | 0x10 | 0x5613D0 | unknown (=vt3) |
| 5 | 0x14 | 0x562FA0 | unknown |
| 6 | 0x18 | 0x563000 | unknown |
| 7 | 0x1C | 0x563210 | ProcessFrame |
Note: wkJellyWorm says 7 methods but we see 8 entries. The 8th may be the start of CGameTask's extended vtable region, or the count was off by one.
CGameTask vtable (0x6641F8)
First 3 entries override CTask:
| Index | Offset | Address | Name |
|---|---|---|---|
| 0 | 0x00 | 0x4FF1C0 | vtable0 override |
| 1 | 0x04 | 0x4FEF10 | Free override |
| 2 | 0x08 | 0x4FF280 | HandleMessage override |
| 3 | 0x0C | 0x5613D0 | (inherited from CTask) |
| 4 | 0x10 | 0x5613D0 | (inherited from CTask) |
| 5 | 0x14 | 0x562FA0 | (inherited from CTask) |
| 6 | 0x18 | 0x563000 | (inherited from CTask) |
| 7 | 0x1C | 0x4FF720 | CGameTask-specific |
| 8 | 0x20 | 0x4FFED0 | CGameTask-specific |
| 9 | 0x24 | 0x500070 | CGameTask-specific |
| 10 | 0x28 | 0x500080 | CGameTask-specific |
| 11 | 0x2C | 0x5000E0 | CGameTask-specific |
| 12 | 0x30 | 0x500380 | CGameTask-specific |
| 13 | 0x34 | 0x500360 | CGameTask-specific |
| 14 | 0x38 | 0x4FE060 | CGameTask-specific |
| 15 | 0x3C | 0x500CC0 | CGameTask-specific |
| 16 | 0x40 | 0x592A50 | CGameTask-specific |
| 17 | 0x44 | 0x500090 | CGameTask-specific |
| 18 | 0x48 | 0x545780 | CGameTask-specific |
| 19 | 0x4C | 0x4AA060 | CGameTask-specific |
CGameTask also has a secondary vtable at object offset 0xE8, pointing to 0x669CF8.
CTask memory layout (0x30 bytes)
Offset Size Field
0x00 4 vtable pointer
0x04 4 parent (CTask*)
0x08 4 unknown (set to 0x10 in ctor)
0x0C 4 children.max_size (init 0)
0x10 4 children.unk4 (init 0)
0x14 4 children.size
0x18 4 children.data_ptr (allocated 0x60 bytes, zeroed 0x40)
0x1C 4 children.hash_list
0x20 4 class_type (ClassType enum)
0x24 12 unknown padding
CGameTask memory layout (0xEC bytes)
Extends CTask at offset 0x00. Key fields discovered from constructor:
Offset Size Field
0x00 0x30 CTask base
0x20 4 class_type (set to 3 = GameCollisionTask in ctor)
0x2C 4 param_3 from ctor
0x30 4 param_3 (weapon id?)
0x38 4 param_4
0x3C 4 unknown
...
0x4C 4 = 0x10000 (Fixed 1.0)
0x50 4 = 0x100000 (Fixed 16.0)
0x54 4 = 0xCCCC (Fixed ~0.8)
0x58 4 = 0x10000 (Fixed 1.0)
0x5C 4 = 0
0x60 4 = 0x10000 (Fixed 1.0)
0x64 4 = 0x20000 (Fixed 2.0)
0x68 4 = 0xF333 (Fixed ~0.95)
...
0x84 4 pos_x (Fixed)
0x88 4 pos_y (Fixed)
0x8C 4 = 0x10000 (Fixed 1.0, scale?)
0x90 4 speed_x (Fixed)
0x94 4 speed_y (Fixed)
...
0xCC 4 = 0x10000 (Fixed 1.0)
0xD8 1 byte flag (init 0)
0xD9 1 byte flag (init 0)
0xE0 4 unknown (init 0)
0xE4 4 unknown (init 0)
0xDC 4 unknown (init 0)
0xE8 4 secondary vtable pointer -> 0x669CF8
Physics defaults from CGameTask constructor
Several fixed-point constants are set in the constructor, likely physics defaults:
0x10000= 1.0 (appears at many offsets β scale factors, gravity?)0x100000= 16.0 (mass? terminal velocity?)0xCCCCβ 0.8 (friction? damping?)0x20000= 2.00xF333β 0.95 (air resistance?)0x3333β 0.20x4CCCβ 0.30xFEB8β 0.9950x9999β 0.60x3AE1β 0.230xFC000000= -67108864 (large negative, possibly a boundary?)