This document describes how LBA2 loads scenes (cubes), how the save/load system works, and what data is persisted. Understanding this flow is important for modders who want to hook into scene transitions or need to understand what state survives a save/load cycle.
In OBJECT.cpp, the ChangeCube method is the single entry point for all scene transitions:
Basic hero resets — Some hero object parameters are reset.
LoadScene — Reads all scene objects and zones from the HQR file.
onAfterLoaded hook fires, allowing mods to modify objects as if they were part of the HQR data.Set start position (skipped when loading a save):
FlagChgCube is 0 (new game) or 2 (teleport): SceneStart is set to CubeStart.FlagChgCube is 1 (scene-to-scene movement): SceneStart is set to NewPos, determined by the transposition zone between scenes.FlagChgCube is 3: Hero position is not overwritten (usage unknown).Object initialization (skipped when loading a save):
Load game branch — If this is a save-load, LoadContexte is called instead, which overwrites most object states from the save file (see below).
The LoadContexte function in SAVEGAME.cpp restores the following data from a save file:
| Data | Notes |
|---|---|
| Game variables | All world-scope variables |
| Scene (cube) variables | Current scene variables |
| Character stance | Normal, sportif, etc. |
| Money | Gold and zlitos |
| Magic level | |
| Magic points | |
| Keys count | |
| Clover boxes count | |
SceneStart<X,Y,Z> |
Starting position in scene |
Start<X,Y,Z>Cube |
Starting cube position |
| Current weapon | |
| Time reference | |
NumObjFollow |
Which object the camera follows |
SaveComportementHero, SaveBodyHero |
Used by SAVE_HERO / RESTORE_HERO Life commands |
| Holomap info | |
| Inventory items |
The next 2 sections are conditional based on whether it's a death restore or a full load.
When restoring after death (clover box used), only a subset is restored:
flagInit is set to true — view objects and scene parameters are not re-initializedFor a real save load, the following additional scene data is restored:
| Data | Notes |
|---|---|
| Last fire, bullet, input | |
ActionNormal, InventoryAction |
Action-related state |
| MagicBall | All parameters |
| Climbing and falling values | |
CameraZone |
|
InvSelect |
Currently selected inventory item |
| MegaPingouin active flag | |
| Darts state | |
| Number of scene objects | |
| All scene object data | Scripts offsets, labels, flags, 3D model, and intermediate object states |
Patches are parts of the Life and Track scripts that can be modified at runtime and must be persisted across saves. They are represented as an array of offsets and byte sizes baked into the HQR file, generated by the editor at compile time.
Some bytecode commands overwrite themselves and their arguments during execution to persist intermediate state (e.g., timer values). Patches capture those mutations so they survive save/load.
Track commands with patches: TM_ANGLE, TM_ANGLE_RND, TM_WAIT_NB_*, TM_FACE_TWINSEN, TM_LOOP
Life commands with patches: if-trigger operations — SWIF, SNIF, ONEIF
| Data | Notes |
|---|---|
| Extras | Dynamic objects — keys, hearts, magic, thrown magic ball, etc. |
| Zones | Only Info1, Info2, Info3, Info7 per zone. Fragment zones trigger a special function on load. |
| Incrusts | Overlays — sprites, numbers, text, flash, rain |
| Particle flows | |
| Camera state | |
| Clip window X min/max | |
AnimateTexture flag |
Whether animated textures are active |
| Sound parameters | Volume, frequency, shift |
| Buggies (cars) | Maximum 2 |
| Slate dome state | Floor visibility in the Slate Dome |
VueCamera |
Current view camera index |
After all parameters are loaded, rain is re-initialized if needed. If rain is modified from a script, it must be re-initialized as well.
The function returns flagInit == false, meaning a full game load was performed and all view objects need initialization.
Some game variables are reserved for inventory and built-in properties. These are defined in COMMON.H (line 244+) and their names start with FLAG_.
All vanilla inventory is managed through game variables — to add or remove vanilla items, set the corresponding FLAG_ variable. Supporting additional custom inventory items requires a custom IdaJS hook.
| Variable | Restriction |
|---|---|
FLAG_CLOVER |
Should be set through Life script only, or if set via setGameVariable, the special checks must be ported |
FLAG_CHAPTER |
Same as FLAG_CLOVER |
FLAG_DONT_USE (255) |
Must never be set |
Other special variables may also need restrictions — check how they are used in the engine code before modifying them.