Variables with the TRNG Engine

Introduction
What could we get with variables?
Different types of Variables
          Local and Global Variables
          The size of the Variables
          Numeric or Testual Variables
          Common and Special Variables
                    The Timer Variable
                              Global Trigger for TRNG Timers
                    The CurrentValue variable
                    The LastInputNumber variable
                    The Store variables
The PlaceFolders for Variables
The Critical Memory Zones
          The Item Memory Zone
          The Savegame Memory Zone
          The Code Memory Zone
          The Slot Memory Zone
          The Animation Memory Zone
The Variables Demo Project
          TRNG Timer and gained MediPacks
          The skill about Jump Gain
          The wooden Door: how save and restore our changes
Tips & Tricks
          How discover the sense of some memory fields
          Enable the debugging for script commands
          Force the saving of coordinates about some Moveable
          How detect time intervals without using the timer





Introduction

This document tries to describe functions and usage of TRNG Variables.

How we could see the direct usage of variables it's very easy: you find flipeffects to copy a number from a variable to another, or to apply some mathematic function, adding, substracting multiply, to some variable.

It's instead more complicated understand how realizing something of useful with the variables.




What could we get with variables?

A first target that we could get with variables is to remember some old fact happened in the game to perform different actions in the future.
The most of triggers permit to realize some of alike but only in same level, while with variables we could remember the time elapsed in a race in first level, to give at end of third level the chance to play also a bonus level.

Another target is to realize very complex new skills using globaltriggers triggergroup and conditions.
In trng features there are already many command working like programmin commands: the triggergroup for commands, and the conditional trigger for condition.
But it was missing a basic requirement for each programming language: the variables.

For example you could to use a globaltrigger with triggergroup to realize a new complex operation like simulate a new vehicle or some hardcoded puzzle, but to realize this it's sure you'll need also of some variable to remember in what phase of these long complex operations serie you are in a specific moment.

You can see the example of jump-gain in the trng_variables.zip project to understand how we used the variables to permit that new skill for lara.




Different types of Variables

If you look some flipeffect for variables (all start with the text "Variables.") you can see the long list of available variables under trng.
They could be divided in different groups in according with different standards.

Local and Global Variables

There are two set of variables: the local variables and the global variables.
It's important understand they are really different variables: the local alfa variable has an independent value than global alfa.
They are Local variabels those will be linked with a specific level, while are global variable those variable keep same values in all levels.
You could think that the global variable are better but in the reality the local variable have own the advantage to keep a set of variable for each level, so you can have a value for Local Alfa in level 1, then (with finish trigger) lara goes in level2 and you can have a different value in Local Alfa for level 2, and when lara comes back to level1 she'll find newly the value of local alfa of level1.

Pratically you should use local variables when those values affect only that level, while you have to use global variable when you set a value in a level and you want preserve that value also in future levels.

The size of the Variables

The speech about size of variables could seem complicated but just you think about a variable like it was a box.
We can have a big box, where store big "things" (or numbers) or little boxes.
The complication is that you can place the little boxes in a big box if you wish.
This is that happens in trng variables.
You can decide if you want use few big boxes, i.e. few variables where you can store big numbers, or if you wish have many little variables where you can store littler values.

To understand the overlapping used in trng variables you could immaginate that you divided a big box to get many little boxes.

See following picture:




This scheme show how work (almost) all trng variables.
For each variable name "Local Alfa", "Global Delta", "Local Beta" ect, we can decide if we want use 4 little boxes (bytes 1, 2,3 and 4) or 2 middle variables (short 1 and short2) or a single big variables.
The numbers you can store in these different "boxes" are the following:

BYTE: Min = 0 ; Max = 255 (only positive numbers)
SHORT: Min = -32768 ; Max = +32767
LONG: Min= -2.147.483.648 ; Max = +2.147.483.647 (i.e. about +/- 2 bilions)

In this overlapping of big or little variables you have to avoid the error to overwrite a big variable while you write in a little variable.
For example if you use the Short1 to store a number, then you cannot store antoher number in Byte1 or Byte2 of same variable, because in this way you'll modify in upredictable way also the Short value.
Differently if you look the above picture you can understand that you can use Byte1 and Byte2 and Short2, too, because these variables are not overlapped.

Numeric or Testual Variables

Probably you'll use more often the numeric variables, anyway there are also testual variabiles where you can store text.
The text variables have following names:

Text1
Text2
Text3
Text4
BigText
LastInputText

In text variables you can copy extra ng strings, or, in the future versions, the text typed by player like his name or some testual password.
There are some flipeffects to add text in BigText variable. This variabile is bigger than other text# variabiles, since you can host upto 319 characters while in text# vaeriables you can store only 79 characters.

Common and Special Variables

The common variable are Alfa, Beta and Delta, locals or globals.
All above variabiles may be divided like showed in The size of the Variables chapter.
There are other variable having something of special:

The Timer variabile, local or global.
The CurrentValue variable (only global)
The LastInputNumber variable (only global)\
The Store variables: from variable A upto variable P (all globals and divided like common variables in byte, short or long size)

In following chapters will be described what having of special above variables.

The Timer Variable

There are two timer variables: global and local.
The timer variable could be used like other common variables except for the fact it was always long and therefore you cann't use bytes or short in timer.
Anyway the Timer variable has some interesting features about counting time, like its name says.
You have flipeffects to start or stop a local or global timer.
Remember that the trng timer variables are different than screen timer of tomb4, they are independent.

There are two flipeffects to set a time in trng timers. You can set the value in seconds or in tickframes, where one second = 30 tick frames.
In spite of these different flipeffect remember that the value in trng timer is always in tick frames, but simply some flipeffect allow you to type a value in seconds and the engine will think to convert in in tick frames.

Remember that the flipeffect to start the trng timer doesn't show byself the timer on screen, you have to use another flipeffect to show or hide some trng timer.
In some cirucstances you could find useful having an "hidden" timer to compute some time interval for your new skills.
For example also in jump gain skill we used a local timer to disable all when it elapsed 1.5 seconds from arrival of the jump.

Another interesting feature of trng timer is that you can insert its placefolder (see The PlaceFolders for Variables ) in any text and then it will be replaced with current time in that timer variable, formatted in the format:

mm:ss:t

Where "mm" are minutes, "ss" are seconds, and "t" is teeny of second.
In this way it's easy show text like this:

Remaining time: #0073

And it wil be showed in game, in this way:

Reamining time: 00:53:4

With the value will be continuosly updated with elapsing of the time.

You can set the timer for increasing or decreasing progression.

You have a flipeffect to show in fast way where show the trng time on the screen.

While, about color and size of text, it has been prefixed, and you cann't change it with that flipeffect, anyway if you want show a trng timer with a different size or color just you use a common "print extra ng string" flipeffect, containing the placefolder of wished timer and in this way you'll be able to set color, size, and durate of viewing as you wish.
Pratically the flipeffect to show a trng timer should be seen only like an easy way to show a timer without having to thing about text formatting.



Global Trigger for TRNG Timers

When you use a timer you can detect the completation of the time with the GT_TRNG_G_TIMER_EQUALS or GT_TRNG_L_TIMER_EQUALS global triggers.
The only difference in above global triggers is that the "_G_TIMER" will be used for global timer, while the "_L_TIMER" will be used for local timer.
Theorically you could also using a commond conditional trigger testing the content of timer variabile but the global trigger is more precise and easy to use because it has been builded to avoid the false positives.
For example if you want give only 10 seconds to player to complete some operation and you wish use a countdown where the start value will be 10 seconds and the final of countdows will be at 0, you could have a problem with conditional triggers, because if you let enabled the global trigger at start of the game, it will detect immedialty the zero value in trng timer, simply because at begin of new level all variables will be cleared.
Differently if you use the global trigger GT_TRNG_x_TIMER_EQUALS with 0 in parameter field, you'll have no problems because this global trigger works only when the timer is running.

Thanks to above method you have no need (and neither it's advisable) to use SINGLE_SHOT flags with global trigger, just you stop the trng timer when it reaches the final value and no global trigger will be enabled until to next starting of timer.

The CurrentValue variable

The CurrentVariable is a special variable only because it is the only variable surely present in all operations performed with flipeffects.
Pratically it happens that some mathematic operations or copying could be not not available for all variables but you'll have always that operation for CurrentValue.
The only thing you should remember about this variable is to avoid to use it to store value you want preserve for long time, because it's probably you'll need to use it only to move a value from a numeric variable to some critical memory and in this case you should have the problem to save its value, while it's more easy to let this value always free of long-time targets to may use it when it's necessary.

The LastInputNumber variable

In the LastInputNumber variable will be copied always the value typed with KeyPad switch, or -1 if player aborts the keypad with Escape.
In future versions of trng also other input methods could set their values in this variable.

The Store variables

The Store variables are very alike than common variables Alfa, beta, Delta, they may be divided in Bytes, shorts or long, too.
While the most difference respect than common variables it that, for technical reasons, you have no direct mathematic operation available to perorm on these store variabile, but you can only copy a store variable in CurrentValue variable, or (the opposite) move the value of CurrentValue in some Store variable.
This set of variables will be used to store different result you can get in the course of the level when the common variables are no more sufficent to keep them.
The advantage of Store variables is that there are many store variables: they are 16 long store variables, and therefore you can also see them like 32 short variables or 64 bytes variables.
The best usage of store variables is to copy in this zone a value when you know it will be required only seldomly or in future, letting free some common variable for effective computes.




The PlaceFolders for Variables

In the Reference panel of NG_Center you can now find a new section named "VARIABLE PLACEFOLDERS" where you can find that little number (the placefolder) to copy in your extra ng strings (but it works also for common PC strings) to have showed on the screen the content of that variable.
In the list there are all common numeric variable, but also the special and store variables.

So, to show the value of some variables in game, just you copy the placefolder in your text to print.

There are many nice tricks you can do with this method.
For example you could show your own version of statistics copy from savegame memory what you wish in some variable and then print a text like this:

Stars of Iside #0044
Remaing time #0073
Missing Targets #004A

And once you copied in the variable the correct values it will be showed like:

Stars of Iside 2
Remaining Time 05:23:2
Missing Targets: 8

About the timer placefolder see also The Timer Variable chapter

To get the value of picked up items or other statisc values see the next chapter about the critical memory zones.




The Critical Memory Zones

With the variables feature there is another interesting chance: now you can change many critical memory cells of tomb4 engine, copy values from your variables to these memory zones, or vice-versa.

For "Critical" memory zone we mean those zones used by trng engine to set the position of object, the number of inventory items and many other interesting stuff.
The most of trng flipefffect have been created writing the right values in the righe memory zone. Now also you can create other own special effect in this way.

I want remember that the change of critical memory could create some nice mess, so if you are not very expert pheraps it's better you limit your usage of critical memory only to read the content of some localtion for example to know the values of inventory items or statistics.

Differently if you want create new skill it will be necessary that you modify some critical zone, for examples in Item structure, the zone where all most important value about a moveable has been saved.

Currently there are following Critical Memory Zones available:

Item Memory
It stores the most of data about each moveable, from lara to any other enemy or animating
Savegame Memory
It keeps many inventory values but also statistics and other
Slot Memory
The slot is the structure for type of moveables and it contains the common characteristics for moveables of same type)
Animation Memory
To manage the memory of a specific animation structure.
Code Memory
It regards zone differents by other groups, currently this list is short but it could grow in the future

In following chapters will be explained better above zones.




The Item Memory Zone

Description of Item memory

Remember that, before performing operations on Item Memory, you have to use the action trigger: "Variables. Set the index of <#>moveable as Selected Item" , to choose what is the item memory to modify. Each moveable has own item memory, i.e. a structure with its data.
Reramrk: some descriptions could be wrong. You could verify the behavior of some field using the method suggested in Tips & Tricks chapter
Name of Field Size Description of Field
Animation Now Short This field hosts the current animation.
This number of animation it's absolute, this means you cann't find a 0 number for first animation of some baddy but you'll find a big number about the number of current animation in the full list of animations of all previous moveables in the tr4 file.
To convert this absolute number in a relative number, where the first animation for this moveable will be 0, the second will be 1 ect, you have to perform this compute:

1) Read the Slot index from "Slot id" field (if you don't known already it)
2) Set this index to work on Selected Slot Memory

3) Read in slot memory the "First Animation Index"

4) Now you can get the relative animation in this way:

RelativeAnimIndex = ItemMemory.AnimationNumber - Slot.FirstAnimationIndex.
Contact Flags Long I'm not sure, anyway when there are single bits of values $2000 and $400, lara should be damaged by this item on touching.
In darts there is this value: $2400
Custom Flags Byte Misterious field.
It seems that the values in this field change in according with type of object.
It appears like bit flags to signal something
Custom_A Short This field, like other Custom fields, has different usage in according with the type of object.
The only way to discover how it will be used from a given item is to study this field while that item is enabled.
See the Tips & Tricks chapter.
Custom_B Short See description of Custom_A field
Custom_C Short See description of Custom_A field
Custom_D Short See description of Custom_A field
Facing Horizontal Short This value is horizontal facing, i.e. looking lara from the top, it is the direction where lara is looking.

About the values you can see the description of "Facing Vertical" field.
The horizontal facing is very important because set the direction where lara (or other items) will go when player hit UP key.
The horizontal speed, for example, is computed in the dirction of horizontal facing.
Facing Rotation Short This facing is particular, and it should work only for Lara item.
You can see the image of Animation command sample to understand the rotation axis affected by this field
Facing Vertical Short This value describe the degrees respect than perpendicolar line with the floor.
In the projet sample "Variables_trng" you can see a change of vertial facing.
The values have a range from 0000 to $FFFF from 0 to 360 degrees.
For example $4000 is 90 degress, while $8000 is 180 degrees.

It's very seldom this value is different than zero, it hapens when lara run with rush.
Flags of Item Long This is a very important and very complicated field.
In this Flags field each bit set some property of current item.
The values you see here are the absolute value of each bit, i.e. if you see $0008 it means you have to set or clear the bit 3 since it has the absolute value $0008

This is the list of my discoveries:

$0001 : The item has bene enabled
$0002 : The item has the collisions or this item requires a refresh.
$0004 : Item has not yet been enabled in game.
$0008 : The item is falling down (gravity enabled for this item)
$0010 : The item has been injured . It forces the view of life bar for Lara.
$0020 : Enemy is not yet dead. He could be to enable or he is living
$0040 : The enemy has been killed with explosion
$0100 : The enemy has been poisoned
$0200 : The enemy is in AI_GUARD mode
$0400 : The enemy is in AI_AMBUSH mode
$0800 : The enemy is in AI_PATROL1 mode
$1000 : The enemy is in AI_MODIFY mode
$2000 : The enemy is in AI_FOLLOW mode
$4000 : This is a new self-created item. Like a grenade or crossbow ammo.
Frame Now Short The frame now is the current frame number in current animation.
Warning: also this vale (like the "Animation Now") is an absolute value, this means that, when an animation starts the frame now could be a big number istead of zero (like first frame)
To convert the absolute frame number in a relative (to current animation's frames) index, you have to perform following compute:

1) Read the "Animation Now" field
2) Use this value to set the Selected Animation Memory
3) Read in Selected Animation memory the field "First absolute Frame index"

And now you get relative number of frame for current animation in this way:

RelativeFrameIndex= Item.FrameNow - Animation.FirstAbsFrameIndex
Height Floor below the item Long This field contains the Y Position of floor below current item.
The value has the same format of Y Position of item and it is very often the same value, it happens everytime the item is touching the ground.
HP Vitality Short In this field there is usually the reamining vitality (life level) of current item.
If the item is not a baddy (moveable with AI features) in this field could be the value $C000 to signal that this item is not killable and targetable.
Object buttons Short In this field should be stored the bits to signals the five buttons (+ Inivisible button) you read in Object Code window.
OCB Code Short In this field there is the numeric value you typed in OCB window of this item in ngle program.
Position X Long The X position of current item.
The X axis corresponds in ngle up-down view.
The X position has always positive values
Like for other Y and Z position field, one sector is 1024 units, one click is 256 units.
Position Y Long The position Y has positive and negative values and signal the vertical position of lara (up or down respect than floor)

The upper sides have negative values while the lower sides have positive values.
Position Z Long The Z position of current item.
The Z axis corresponds in ngle at left-right view.
The Z position has always positive values
Like for other Y and X position field, one sector is 1024 units, one click is 256 units.
Room Short The index of room where is this item.
Remarks:
- The indices in tomb4 could be different than room indices you see in ngle, this depends by the presence of empty room in ngle's project.
Anyway remember you can convert a room tomb index in ngle room index or vice-versa using the correct flipeffect.

- The value of room index cann't pass over 255, so, although this field has a Short size you can store this number also in a BYTE variable if you wish.
Slot Id Short This field contain the slot number of current item. For example Lara = 0, AHMET = 102 ect
You can use this number as index to set selected slot memory.
Speed Horizontal Short This field is the speed in horizontal direction of current item.
The speed is pratically an increment that will be added to X,Z position following the current direction (facing ) of the item.

Speed Vertical Short This field is the vertical speed, i.e. it is usually the speed of falling (positive values) or jumping upward (negative values)
Remark: when lara is underwater only this speed value will be used while the horizontal speed will be ignored.
State Id Next Short This field works like "State-id now" field but this keeps the next state-id to set.
State Id Now Short This is the current State-id for this item
The state id of lara is well-known but also other enemies have a state id to singal the current phase of its action.
Transparence level Short This field describes the transparence level of current item.
When the value is 0 there is no transparency and therefor the item is fully opaque.
When the value is 126 the item will be full transparent.
Remark: you can use an action trigger to modify the transparecy of moveable. While, if you try to perform this operation with variables, remember that this field when is different than 0 will be increased by trng engine and when the value reachs 127 the item will be removed.
Pratically the engine used this field to generate the progressive transparence effect before removing a killed enemy, and in fact, if you place a non-zero value in this field the item will become transparent and then it will be removed.
If you want only set a transparence it's better use the specific action trigger because this action trigger freeze the value in this field to stop the removing phase.
Unknown (Accelleration on falling?) Short About some fields it's not sure their target. This field could keep some acceleration value but it's to verify
Unknown (Shot a granade?) Short Misterious field.
I know only that when a baddy shots a grenade in this field will be written the $C210 value.
Unknown (Sprite1 Id) Byte Misterious field.
In my old studies it seemed regard some sprites used by this moveable, so it should be a sprite index but now I don't remember very well.
Unknown (Sprite2 Id) Byte About this field look the description for other fied "Unknown (Sprite1 Id)"
Unknown CountDown Short This field require some study. It appears like a countdown but it's non sure what means. It could be a counter for delayed activation.
Unknowns (Light A - H) Long These are many unknown fields.
They could be used about the light or color of item but I don't know it in the reality.
Visible Mesh Flags Long Each set bit signals a visible mesh.
Mesh 0 bit 0 (value = $1), Mesh 1 bit 1 (Value $2), Mesh 2 bit 2 (value $4).
The default value is -1, i.e. $FFFFFFFFF with all bit enabled to show all meshes of the item.
If you want get invisible a mesh use a "Clear bit .. " flipeffect, anyway remember you have already some action trigger to get visible/invisible a mesh of some moveable.





The Savegame Memory Zone

Savegame Memory Description

In this memory there are all values saved and restore in/from savegames.
The most of values regard Inventory items but there is also some trng special value
Field Name Size Field Description
Inventory.
Keys 1 - 8
Keys 9 - 16
Pickup Items 1 - 8
Quest items 1-8
Byte All these fields work in same way: each bit signal the presence of a specific item number.

$01 = Item 1
$02 = Item 2
$04 = Item 3
$08 = Item 4
$10 = Item 5
$20 = Item 6
$40 = Item 7
$80 = Item 8
Inventory.
Laser Sight
Binocular
Crow Bar
Byte If the item is present the value is 1, if it is missing the value is 0
Inventory.
Pistols mask
UZI Mask
Shotgun
CrowBow
Greanade-Gun
Revolver
Byte All these fields work in same way.
They have a bit mask to signal the presence of respective weapon and the presence of ammo and laser-sight.

$01 = Weapon is present
$02 = Unknow (pheraps it means "the weapon is unloaded")
$04 = Weapon mounted the laser-sight
$08 = Normal ammo
$10 = Wideshot (shotgun), Super (grenade) or poisoned (crossbow) ammo
$20 = Explosive (crossbow) or flashing (grenade) ammo
Inventory.
Small medipacks
Large Medipacks
Flares
Ammo Pistol
Ammo UZI
Ammo revolver
Ammo Normal Shotgun
Ammo Wide-shot Shotgun
Ammo Normal Grenade
Ammo Super Grenade
Ammo Flash Grenade
Ammo Normal CrossBow
Ammo Poisoned CrossBow
Ammo Explosive CrossBow
Short All these fields indicate the respective quantity of that item.

Some notes:

- The shotgun ammo are slways 6 times bigger than number you read in inventory. For example if you see 5 about normal shotgun ammo, this means that in "Ammo Normal Shotgun" there will be the value 30 (because 6 * 5 = 30)

- When in some of these field there is -1, this means: unlimited quantity.
Inventory. Big Skin Bag Byte Bit mask to signal the presence and the liter for Big Skin Bag

0 = Missing
1 = Present, empty
2 = Present, one liter
4 = Present, three liters
6 = Present five liters
Inventory. Combo items 1 - 4 Byte This is a bit mask to signal the presence of two pieces for each combo item.
The combo items are items divided in two parts. Lara is able to find a single piece and when she owns both pices she can attach them getting another new item.
In this field there are informations only about single combo pieces.

$01 = Combo Item 1 for puzzle 1
$02 = Combo Item 2 for puzzle 1
$04 = Combo Item 1 for puzzle 2
$08 = Combo Item 2 for puzzle 2
$10 = Combo Item 1 for puzzle 3
$20 = Combo Item 2 for puzzle 3
$40 = Combo item 1 for puzzle 4
$80 = Combo item 2 for puzzle 4
Inventory. Combo items 5 - 8 Byte This is a bit mask to singal the presence in inventory of single combo items for puzzle items 5,6, 7, and 8

$01 = Combo Item 1 for puzzle 5
$02 = Combo Item 2 for puzzle 5
$04 = Combo Item 1 for puzzle 6
$08 = Combo Item 2 for puzzle 6
$10 = Combo Item 1 for puzzle 7
$20 = Combo Item 2 for puzzle 7
$40 = Combo item 1 for puzzle 8
$80 = Combo item 2 for puzzle 8
Inventory. Little Skin Bag Byte Bit mask to signal the presence of Little Skin Bag and also the number of liter in it.

0 = Missing
1 = Present but empty
2 = Present one liter
4 = Present three liters
Inventory. Mechanical Scarab Byte This field is a mask bit to keep the presence of single pieces of mechanical scarab.

1= Full Mechanical Scarab (key + scarb already mounted)
$02= In inventory is present the Winding Key
$04 = In Inventory is present the mechanical scarab (unmounted)
Inventory. Remaining usage of Mechanical Scarab Short This field remember how much times has been used the mechanical scarab.
When the value is 0 and lara uses another time the scarab it will explode.
When the scarab is missing in inventory or they are only the single deattached pieces (scarab and key) the value is 0
When the mechanical scarab has been just completed the engine write in this field the value 3
Everytimes the scarab will be used this value will decreased by 1
Inventory.
Examine Item 1
Examine Item 2
Examine Item 3
Puzzle Item 1
Puzzle Item 2
Puzzle Item 3
Puzzle Item 4
Puzzle Item 5
Puzzle Item 6
Puzzle Item 7
Puzzle Item 8
Puzzle Item 9
Puzzle Item 10
Puzzle Item 11
Puzzle Item 12
Byte For all these fields the value is simply the quantity.
Zero means "missing" while other values indicates how much items of this type have been picked up by Lara
Lara. Air for Lara Short This is the quantity of air yet availble for lara.
The max air (when the bar is full) is 1800, while when the value is 0 the HP bar (life level) will begin to decrease.
Lara. Current Weapon Short This field stores the current selected weapon, anyway this weapon it's not necessarily in the hand of lara.
Pratically this field says to engine what weapon has to be extracted when player use the DRAW WEAPON command (space bar)

0 = Nothing
1 = Pistols
2 = Revolver
3 = UZI
4 = Shotgun
5 = Grenade-gun
6 = CrossBow
Lara. Environment where lara is. Short This field is very important, it signals in what environment is lara: water, underwater or ground.
All procedures to manage lara will change drammatically in according with this value.

0 = Ground, but also climbing, monkey, jumping, falling
1 = Underwater
2 = Floating on the water
3 = Special: dozy, vehicle, hardcoded cutscenes
4 = Low water at ankles

Lara. Hands. Attached Lara Status Short This field describe the current action of lara about items in her hands.
1 = Special attachment: polerope, vheicle, edge wall
2 = She is taking an item (weapon,torch, flare)
3 = She is letting an item (weapon, torch, flare)
4 = She is holding in hand weapon or torch (but not flare)
Lara. Hands. Item in the Hands of Lara (current) Short It keeps the current item in the hands of lara, or 0 if no item is on her hands.
The value in this field could have following values:
0 = Nothing
1 = Pistols
2 = Revolver
3 = UZI
4 = Shotgun
5 = Grenade-gun
6 = CrossBow
7 = flare
8 = torch

Trick: if you write in this field the value 8 (=torch) and write in "Attached Lara Status" field the value 2 (=lara is throwing out item) a torch will be created in spite it was not present in lara's hands
Lara. Hands. Item in the Hands of Lara (next) Short This field has same values of "Lara. Hands. Item in the Hands of Lara (Current)" field, but in this case this field stores the item that lara will take.
Lara. Hands. Remaining time with lighted flare in the hand Short This keeps a countdown in tick frames units (one second = 30 tick frames) starting when lara takes a lightning flag in her hand.
When the countdown reaches zero (0) lara will throw out the off flare.
The max value seems 900 or 1000, and it is the max durate of flare.
Lara. Hands. Weapon in the hand Short This field describe the weapon in the hand of lara.
Remark: if lara holds an item different than weapon (flare, torch) in this field there will be 0

0 = Nothing
1 = Pistols
2 = Revolver
3 = UZI
4 = Shotgun
5 = Grenade-gun
6 = CrossBow
Lara. Item Index of Lara Short This is the index of lara Item memory. If you want perform operations on item memory of Lara you can read the value in this field and then copy it to "Item Index of Selected Item Memory".
The value in this index is in tomb format, so it may be used immediatly but in could be different than the index you see in ngle program about lara.
Lara. Poison1 Short This field shows the quantity of poison in Lara.
It will be used to set the level of deformation of screen, bigger values, bigger deformations.
This fields has always the same value of Poison2, anyway if you place different values in a short time they will be newly the same.

The poison of big scorpion is 2048


Lara. Poison2 Short This field works togheter with Lara Poison1.
It seems that this field was most important than Poison1 since if you place in this field a value different than zero, while you let 0 in Poison1 lara will be poisoned, but this doesn't happen if you do the opposite.
Lara. Rope. Speed sliding on the rope Short Lara is on the rope and she is moving to accellerate the speed of swinging.
Lara. Special Status of Lara Byte This is a bit mask with flags to signal some status of Lara:

$01 = Lara hols torch or flare (but no weapon)
$04 = Lara is on ground vehicle (to verify)
$08 = Lara is burning, is in dozy mode or she has been killed
$10 = Lara is on all fours (to veriy)
$20 = It has been performed a swapmesh on lara (to verify)
$40 = Lara is in a sector with monky attribute
Lara. Special2 Status of Lara Byte Other status for lara:

0x04 = Lara is crouched down (to verify)
0x20 = Lara holds a burning torch (to verify)
0x40 = Lara holds a rope (to verify)
Lara. Test. Climb sector Test Short This field is not very useful. It says only if the sector where lara is, has on some wall a climb attribute, but it doesn't say what is this wall or if lara is closed to this wall.
The only usage could be to remove the climb skill typing zero in this field but it's not sure that it will work since the engine will continue to update this field with the correct value.
Lara. Test. Lara has a flare in her hand Short When lara is holding a flare this field has value = 1
Lara. Test. Lara is on rope Short This field should contain the index of rope where lara is.
If in this field there is -1 lara is NOT on the rope, while if the value is different than -1 she is on the rope and the value is the index of rope item used by lara
Lara. Test. Lara is placing the weapon on the back Short When lara is removing her weapon and this weapon is one of these to place on back (shotgun, crossbow, grenade-gun) this field is 1
Lara. Test. Throw out item from the Hands Short If lara is throwing out a torch or flare, or she is putting away the weapon.
1 = she is throwing away item
Lara. Weapon on the back of Lara Short This field contains the further weapon on the back of lara: crossbow, graneda-gun, crowbar ect.
The value is a slot index, so for example if lara has on her back the crossbow in this field there will be the value 356

Remark: apparently this field could change also the presence of holsters in the lara's meshes but I've not had the time to study this matter.
Statistics.
Secrets
Used MediPacks
Byte The quanity showed in statistics screen for Found Secrets and Used medipacks
Statistics. Distance Long This field stores the current distance convered by Lara from start of the adventure.
The units used are so computed: one meter = 419 units of this value.
Statistics. Killed Enemies Short This is the value showed in statistics screen about the number of killed enemies
Statistics. Used Ammos Short This field correspond to used ammo of statistic screen
System. Auto-Aiming for Enemy Byte I don't remember very well, but this field should have some information about the current enemy aimed by lara, or pheraps if the auto-aiming mode is enabled or less. (To verify)
System. Core Game Timer Long This field is not very useful. Theorically it should store the full time elapsed from start of the adventure but in the reality this is only the value get from last load game operation.
This value will be updated only after last load/save game operation.
If you want check the active version of the core game timer you should use the "Frame 3d Counter" in code memory, or the "TRNG Organizer Timer" in Savegame memory.
System. Disable special keys Short This is a weird field.
When in this field there is the value = 15, the player will be not able to use inventory, pause, saving or loading savegame screens.
System. Fog Bulb Color Long This is the color of fog bulbs in rgb format
System. Index of enemy aimed by Lara Long This is the index of enemy currently aimed by Lara, i.e. this is the current target of Lara's weapon
If no enemy is aimed by lara this field should has the value -1
System. Number of current Level Byte It is the number of current level, following the order in script.dat of [Level] section.
The title is 0, while the first playable level is always 1.
System. Screen Timer Long This field is the same of screen time you saw in "Run for the iris" level
It is in tickframes (one second = 30 tick frames).
The engine will increase this value only when it is different than zero.
When this field is different than zero the timer will be showed on screen, while if it is 0, the will timer will be hidden and this field will be ignored (no more increased)
System. Unknown (Item chosen from Inventory?) Long This field has some link with the last item selected in inventory but if you want check for selection of inventory item I suggest to use the GT_USED_INVENTORY_ITEM global trigger.
TRNG Index. Animation Index for Selected Animation Memory Short This is the index used to locate the animation memory to check or modiy with flipeffect/conditions "variables. memory ... Selected Animation memory"
You can change this value to choose the animation structure to check/modify
TRNG Index. Index of found Item Short This is the index of item found with some trng conditions, like TestPosition command or with GT_DISTANCE_FROM_ITEM globaltrigger.
In TriggerGroup command you can force the usage of this indxe with the TGROUP_USE_FOUND_ITEM_INDEX flag, in this way the futher indices in action triggers present in the exported trigger, will be ignored and at their place will be used this index about last item found from trng functions.
This index is very importat to perform an action trigger on some item with its index stored in some of your variables: just you copy the index in this "Found Index" field and then perform an exported trigger with the TGROUP_USE_FOUND_ITEM_INDEX flag.
TRNG Index. Index of moveable performing last AnimComand Short This is the index of moveable that owns the last AnimCommand performed.
In triggergroup you can force the usage of this index with the TGROUP_USE_OWNER_ANIM_ITEM_INDEX flag.
TRNG Index. Item Index for Selected Item Memory Short This is the index used to choose what item structure modify with variable. memory flipeffect working on Selected Item Memory.
Usually you'll use an action trigger to set what is the item memory to use, but if you want pass via variables this index you can type in this index the number of the wished item and in following flipeffect about Item Memory it will be read/written the memory of this wished item.
TRNG Index. Slot Index for Selected Slot Memory Short This is a trng index.
When you perform operation about variables and Slot Memory, the trng engine uses this index to know what slot will be used.
So you can write in this index the slot index about the slot memory you want check or modify.
TRNG Organizer Timer Long This is the timer used by trng to compute the Organizer command.
This field will be always updated for each frame, indifferently if there are organizer or less.
For this reason you can use it to detect how much time elapsed from some event.
See "Tips & Tricks" chapter.

Remark: this timer will be updated in game but it will stopped while we are in inventory or pause phase.





The Code Memory Zone

Code Memory Description

Field Name Size Field Description
Audio Track Number on Channel 1 Short This field works only when you are using bass.dll features.
In this field you find the number of audio track is currently playing on channel1, or -1 if no audio track is playing.
Audio Track Number on Channel 2 Short This field works like above but for channel 2
Camera Mode Now
Camera Mode Next
Long These fields containg an indication about the kind of camera, i.e. the camera mode.

0 = Follow me camera
1 = Fixed camera
2 = Look camera
3 = Combat camera
Current Level number Byte This field stores the current level number, where 0 is the title and 1 is the first playable level.
Remark: this value is more update than "Level number" you find in savegame memory.
Dash Bar Value Short This is the value in the dash bar (with lara runs with rush).
The max value is 120
Earthquake vertical movement Long When there is an earthquake effect in this field there is a negative values about the distance on y axis of vertical movements of the camview
Frame 3d Counter Long This field works like "Frame System Counter", the only difference is that this "Frame 3d Counter" will be stopped in pause mode.
Frame System Counter. Long This is the main counter in tick frame of the game.
It works in savegame and pause mode, too.
For above reason it's not a good choice about the signed time method described in "Tips & Tricks" section, since the time goes on also in inventory.
Inventory Item required in game Long In this field will be store temporary the slot number of inventory item required by some interative object like switch (asking a key), doors (asking a crowbor), jeep (asking the key for the jeep) ect.
KeyBoard Game Command hit Long This is a bit mask where each bit signal a game command enabled from player in this moment.
You can test the values or (theorically) modify them using bit operations (set bit / clear bit)

About the values they are in absolute value the same of KEY1_ and KEY2_ constants you find in [Reference] panel of NG_Center program.
Remark: if you want test a KEY2_ value you have to add four zero "0000" at right to get the real absolute value.

For example if you want verify if currently there is the:

$4000 KEY2_DASH

You should see this value like "$40000000" (added four "0" at right)
And as bit number it will be:

Bit 30 ($40000000 ; 1073741824)

Music volume Long In this field there is instensity of volume for audio tracks.
The max value is 100.
If you modify this field trng engine will change the volume but it'll work only if you are using bass.dll features
Screen.
Width game screen in pixel
Height game screen in pixel
Short In these fields there are the current screen size of tomb raider screen
It's not very useful since it's not enough change this value to do modify the current resolution, anyway you could use it only to check if the screen is very little and to advise the player with a conditon trigger + print ng string to suggest to change the current video mode with setup program
Script Dat. Level Flags Short This is the bit mask with the flags from script.dat for current level.

$0001 = YoungLara
$0002 = Weather
$0004 = Horizon
$0008 = Layer1
$0010 = Layer2
$0020 = StarField
$0040 = Lightning
$0080 = Train
$0100 = Pulse

0x0200 ColAddHorizon
0x0400 ResetHub
0x0800 LensFlare
0x1000 Timer
0x2000 Mirror
0x4000 RemoveAmulet
0x8000 NoLevel
Script Dat. Option Flags Byte This field is a mask bit to store some setting of script.dat file.
You can read or change the single bits to your risk.

$01 = FlyCheat enabled
$02 = LoadSave enabled
$04 = There is a Title level
$08 = PlayAnyLevel enabled
$80 = DemoDisk enabled
Sound SFX volume Long The volume for sound effect.
Max value = 100
Speed Layer1
Speed Layer2
Byte These field host the values type in fourth field of Layer1 (or Layer2) script command.

Range values: -16 +16
If you use negative values the movement of animation will be inverted
Test. Disable Fog Bulbs Byte This field permits to disable via software the fog bulbs.
When this field = 1 the fog bulbs will be hidden in game
Test. How entered in current game Long In this field there are values to signal the way this game section has been started.
I don't know all values, anyway 0 = New Level and 4= loaded from savegame.
Test. There is a Flyby in progress Long When there is a flyby in progress this field is = 1, while is 0 if no flyby is in progress





The Slot Memory Zone

Slot Memory Description

Before perform operations on Slot Memory remember to select the slot index used for following operations. You can use the flipeffect "Variables. Memory. Set the <&>Slot as Selected Slot Memory"
Field Name Size Field Description
Explosion Mask. Long It is a mask bit: each bit could be a weapon able to do explode it. (to verify)
First Animation Index Short This is the absolute index of first animation used by current items.
This field is important to compute the relative number of animation about an item.
See also the "Animation Now" field of Item memory.
First Mesh Index Short This is the absolute number of first mesh of current moveable
It should be used to get the relative mesh index of some mesh of the moveable.
Currently this field is not useful
Flags. Main flags Short This is a bit mask to signal many features about current slot.

$0001 = This slot is present (if 0 is missing in this level)
$0002 = Creature. Item with AI features
$0008 = The position of these items should be saved and restored in savegame
$0010 = Unknown but pheraps it means "Moveable of ground"
$0020 = Unknown but it could be "this item could be moved in the level"
$0040 = Unknown but it could be "this item has collisions"
$1000 = Sound effect on this item (if 0 then alway in main scene)
$2000 = Creature resistant to light weapons (pistols, uzi) to verify
FootStep Short Shadow below Lara or enemies (to verify how it works)
HP. Max Vitality at start Short In this field there is the default starting vitality for all items of current slot type.
If the slot is not killable in this field could be $c000 value
Number of Meshes Short This is the number of meshes of current moveable.
Pointer for Collision Procedure Long The collision procedure check for collision between current item and Lara.
If you place 0 in this field all items with this slot will lose the collisions and lara will be able to across them
Pointer for Draw Extra Procedure Long Pointer of procedure to draw some extra optional of the item.
It used for jeep and sidecar.
Pointer for Emitter Procedure Long If the item is able to emit other items the code for this operation in this pointer.
Pointer for Initialization Procedure Long All moveable with this slot will be initialized by the procedure with address stored in this field.
It's not useful change this field
Pointer for Main Control Procedure Long Address of Main Control procedure.
The main controll procedure applies the AI, move the item, and perorm other "animated" features about current item type.
If you place a 0 in this field all items with this slot will be frozen.
Anyway if you want freeze some item it's better you use the Action trigger to freeze moveable.
Pointer for Special Ceiling Procedure Long This procedure should handle the item about the ceiling but it's a bit misterious.
Pointer for Special Floor Procedure Long The pointer for a special procedure present only in seldom moveable.
I presume it was to permit to lara to walk over these items but I'm not sure.
Test Attack Lara Short It could be a signal for moveable of enemy type, i.e. item should attack lara. (To verify)

Value 1 = attack lara
Value 0 = ignore lara
Unknown1 Short Pheraps distance to enable the MIP version
Unknown2 Short Usually it has value 50
Unknown3 Short It will be copied in Custom_B field of Item structure
Unknown4 Long No idea about this





The Animation Memory Zone

Animation Memory Descriptions

Before using the Animation Memory triggers, remember to select the current memory animation with the flipeffect: "Variables. Memory. Set <&>Animation as Seleted Animation Memory.
Remark: In this table have been described only known or useful fields, while others have been ignored, anyway you can find all fields in Selected Animation Memory flipeffects
Field Name Size Field Description
First absolute Frame index Short This field is the index of first frame used by this animation.
You can use this field to discover the current relative frame number.
See also the "Frame Now" field of Memory Item.
Frame Rate Byte This field multiply the repeated frames, so when this number is bigger the animation will seem more slow.
Frame Size Byte This field indicates the bytes required by frames, anyway you can use this field only on read to discover if current animation is present or less.
When the FrameSIze = 0 the animation is missing.
Next Animation index Short This is the index of animation that will be performed at end this.
Number of Animation Commands Short If this animation contains AnimCommands, in this field there is the number of AnimCommands, otherwise it will be 0
Number of State Changes Short In this field there is the number of State Change record for this animation.
The State ranges are a bit complicated, they are used to choose the correct frame to pass between current animation and another animation with same state-id than Next State id field of moveable.
Speed Short The speed should modify the current horizonal speed of moveable, anyway this field is very often 0.
State Id Short When the animation will be performed this state id will be set for the moveable





The Variables Demo Project

The demo project about TRNG Variables contains some demonstratio about advanced usage of variables, critical memory and some new global triggers.
If you have not yet played the demo it's better you play it now, otherwise you'll be not able to understand this chapter.


TRNG Timer and gained MediPacks

To realize this effect we used a local trng timer to perform a countdown starting from 30 seconds with these three flipeffect triggers:

Start a trng timer
; <#> : Variables. Timer. Initialize <&>TRNG Timer to (E)Seconds
; <&> : Global Timer
; (E) : Seconds= 30

; <#> : Variables. Timer. Start the <&>TRNG Timer in (E)Mode
; <&> : Global Timer
; (E) : Decreasing Timer (Countdown)

; <#> : Variables. Timer. Show <&>TRNG Timer in (E)Position
; <&> : Global Timer
; (E) : POSITION_TOP_CENTER

How you can see it's necessary:

1) set the value for timer
2) start the timer
3) and also show it, because you could use also an hidden timer in some circustances

Detect if timer reaches a given value
Then we placed a globaltrigger command to detect if the timer reach 0 time.
When this happen it means the player was not able to save seconds and we'll show simply a text to signal the end of the time:

; Exporting: TRIGGER(259:0) for FLIPEFFECT(66)
; <#> : Text. Set <&>color and (E)position for next Print String flipeffect
; <&> : Red
; (E) : Bottom line, central alignment
; Values to add in script command: $2000, 66, $103

; Exporting: TRIGGER(772:0) for FLIPEFFECT(64)
; <#> : Text. Print ExtraNG <&>string on screen for (E) seconds
; <&> : 4: The time is completed
; (E) : 5 seconds
; Values to add in script command: $2000, 64, $504

; Exporting: TRIGGER(513:0) for FLIPEFFECT(270)
; <#> : Variables. Timer. Hide <&>TRNG Timer in (E)Seconds
; <&> : Global Timer
; (E) : Seconds= 2
; Values to add in script command: $2000, 270, $201

TriggerGroup=                    1, $2000, 66, $103, $2000, 64, $304, $2000, 270, $201

GlobalTrigger=                    1, IGNORE, GT_TRNG_G_TIMER_EQUALS, 0, IGNORE, 1

Convert the saved seconds in medipacks
Differently it's most interesting when the player is able to stop the timer reaching the trigger at end of the race.
In that sector there is a trigger to perform the TriggerGroup=2 in script.dat file:

; Exporting: TRIGGER(1:1) for FLIPEFFECT(265)
; <#> : Variables. Timer. Stop the <&>TRNG Timer
; <&> : Global Timer
; (E) :
; Values to add in script command: $2000, 265, $1

; Exporting: TRIGGER(769:1) for FLIPEFFECT(270)
; <#> : Variables. Timer. Hide <&>TRNG Timer in (E)Seconds
; <&> : Global Timer
; (E) : Seconds= 3
; Values to add in script command: $2000, 270, $301

; Exporting: TRIGGER(51:0) for FLIPEFFECT(271)
; <#> : Variables. Numeric. Copy <&>Numeric Variable to CurrentValue
; <&> : Global Long Timer
; (E) :
; Values to add in script command: $2000, 271, $33

; Exporting: TRIGGER(7935:0) for FLIPEFFECT(253)
; <#> : Variables. Numeric. Divide <&>Numeric Variable by (E)Value
; <&> : Current Value
; (E) : Value 30
; Values to add in script command: $2000, 253, $1EFF

; Exporting: TRIGGER(58:0) for FLIPEFFECT(273)
; <#> : Variables. Memory. Add to <&>Savegame Memory the CurrentValue
; <&> : Inventory. Small medikit (Short)
; (E) :
; Values to add in script command: $2000, 273, $3A

; Exporting: TRIGGER(1286:0) for FLIPEFFECT(64)
; <#> : Text. Print ExtraNG <&>string on screen for (E) seconds
; <&> : 6: You saved #0800 seconds\ntherefore you gained #0800 medipacks.
; (E) : 5 seconds
; Values to add in script command: $2000, 64, $506

TriggerGroup=                    2, $2000, 265, $1, $2000, 270, $301, $2000, 271, $33, >
                                         $2000, 253, $1EFF, $2000, 273, $3A, $2000, 64, $506

We performed the operations:

1) Stop the timer
2) Hide the timer (otherwise the timer will remain on screen forever in spite it is still)
3) Then we read the resulting time from local timer variable
4) And divided that value by 30, because the timer works in tick frames unit, where each second is 30 units
5) Now we have in CurrentValue variable the number of saved seconds and we can convert it in medipacks
6) adding the currentvalue to field of savegame memory with number of little medipakcs in inventory
7) At end we show the result, using a text where we type the placefolder of CurrentValue: #0800

The skill about Jump Gain

You can see all exported triggers used for this skill in script.txt file with comments.
Here I prefer describe in natural language the method used and the problems that has been necessary to solve in this procedure.

The compute to enhance the jumping
To increase the length of jump we have different way: we could increase the horizzontal speed so to get, in same time of the jump, a bigger distance.
Another way is to keep "up" lara modifying its Y position, that set the vertical position of lara in 3d world.
The Y coordinates move up with negative values, and move down with positive values, so to keep up lara we should subtract values to her Y Position (or to add negative values, since is the same thing.
We used both method in same time to get more realistic the jump.

From where could we take the value for Jump Gain?
Once we decided how increase the jump we have to choose what value we'll use to perform this compute, i.e. the value of jump gain to use in above mathematic formula.

We chose the residual dash speed in dash bar, since we have this value in Code Memory and it is consistent with the pyshics: if lara run faster before jumping she should peform a bigger jump.
In the reality there was a boring problem in this method to get the jump gain value: the engine doesn't allow to jump when lara is in rush phase, it waits that lara comes back to normal speed and only in that moment the engine will permit to her to jump.

To avoid this problem I placed a trigger to catch the residual dash speed, on the sector closed to start jump.
In this way the trigger group used to catch the residual speed will work some instant before the real jumping and so it could have yet a meaningful value (differently when lara jumps that value is always 0).

Future enhancements
This is boring because we should place these sector strips closed to all jump zone.
Anyway this is only a sample used to describe the method to add new skills, and not the best skill you can get.
You should find anoter method to get a starting value to use as jump-gain, better if you get this value using a global trigger and some condition, both with triggers placed in all jump zones.
For example you could use a variable where add the powerness of lara and this value could be incresed with the training: more lara jumps and more jump skill she will get, like it happens in many games.

Catch the Jump Gain value
1) Lara touches the sector closed to jump zone
2) The TrigggerGroup=3 will be performed
3) In this TriggerGroup 3 will be read the value of code memory "Dash Bar Value"
4)Since when there is no dash bar the value in "Dash Bar Value" is 120, we'll perform the operation 120 - "Dash Bar Value", getting in this way our value to use as Jump Gain
5) We'll perform a condition to verify that the Jump Gain is >= 1
6) If the condition is true (Jump Gain >= 1) we'll set a bit to signal that there is a Jump Gain to use
7) We used the bit 0 (with absolute value $01) of Local Long Alfa
8) Now we start the local trng timer to remember the moment when we catched a valid jump gain. The reason of this operation is to give a max time to perform the super jump, while when this time has elapsed the jump gain will be aborted. The reason of this expiry time is to avoid that a rush value created and not used immediatly may be used many time later.

Detect the jump and apply the Jump Gain
1) Using the GlobalTrigger =2 we check if lara is jumping and in same time the bit 0 (value $01) of Local Long Alfa is set. This condition are in TriggerGroup=4 and this triggergroup will be place in ConditionTriggerGroup field of GlobalTrigger=2
2) If both conditions are true we can apply the jump gain
3) The triggers to modify speed and Y Position are in TriggerGroup=5, and we place the Id =5 in PerformTriggerGroup field of our GlobalTrigger=2
4) We replace the Horizontal Speed with the value computed in this way: Jump Gain (saved in Local Short Beta1 variable) + 75, where 75 is the common horizontal speed in forward jump, so we can increase the standard hspeed only of jump gain value. This method it's better than adding directly the Jump Gain to H_Speed value becuase otherwise we could create a huge H_Speed with a continue growing.
5) Then we decrease Y Position to move lara upward, but for this compute we cann't use the original Jump Gain in LS_Beta1 becuase it could be too big and lara could fly away instead or falling down as is the normal.
6) So we reduce temproary the jump gain value before subtracting it to Y Position
7) We divide the Jump Gain by 4 and then subtract this value to Y Position
8) Now we print a text showing the jump gain. We used a text with a time of only one second, because it will repeated continuosly until the jump mode is on
9) At end we clear and start newly the local timer. This is to have another expiry time. In this case we need to clear the bit 0 (value $01) when the jump has been completed. So, while the jump is on the timer will be continuosly cleared all will work, while when lara touches the ground and the condtiion for globaltrigger=2 will be false, the local timer will be able to continue.

Clear all when the jump has been completed
1) Now we have yet the bit 0 of LL_Alfa set to signal the jump gain, but we have to clear this variable when the jump has been completed
2) We use the GlobalTrigger=3 to clear all.
3) In GlobalTrigger3 we used the GT_TRNG_L_TIMER_EQUALS = 45 (tick frames, i.e. 1.5 seconds) condtion, so when it elapsed 1.5 seconds by the end of jump the condition will be true
4)When the local timer is at 1.5 seconds, the TriggerGroup=6 will be performed
5)In TriggerGroup=6, we clear the bit 0 of LL_Alfa, and we clear also LS_Beta1 value and the local timer
6)Now all variabels used to remember the jump gain mode have been cleared


The wooden Door: how save and restore our changes

The method to remove the collision from the wooden door is a bit idiot, ok, but that example has been necessary to describe a very important operation, about saving and restoring of our patches, that we could have to perform in some circustances.
When we modify some memory zone with the flipeffect we get immediatly some result, but these effects could be temporary since when the player will save and then will reload the game our changes could disappear.
The reason of this disappearance is that many memory fields will be not saved and restored with savegame byself, and therefore, when the player will reload the savegame all these memory zones will be reset to their default values.
To avoid this situation we have to save in savegame some signal to rmember the changes we made, to have then the chance to restore them newly when the savegame has been just reloaded.

The global triggers: GT_BEFORE_SAVING_VARIABLES and GT_AFTER_RELOADING_VARIABLES
We can use some new global triggers to detect when the game is to be saved, or when it has been just reloaded.
In this way we can perform some triggergroup (linked with GlobalTrigger) when these two fundamental operations will happen.

First step is to understand what should be saved (and then restored) in savegame.

Please, don't confuse this speech with the requirement to save and reload the trng variables: it's is not this the true. All trng variables will be saved and reloaded in automatic way.

Differently we have to save and restore only the changes we made in some memory zone and to remmeber what we made we'll use some variable where storing a signal.

When you created some new skill you should verify if it is persistent, i.e. if it remains also after the saving and then reloading of the game.
If it remains then it's perfect: you have no need of saving anything.

While when you see it disappears after reloading you'll have to perform following operations

Standard procedure to saving our patch
1) We have to decide (and noting it) what variable (and bit) we'll use to signal this patch to save/restore
2) In our demo project we used the bit 1 (value 2) of Local Long Alfa variabile, since the bit 0 (value 1) had already used to signal the jump gain mode.
3) When our patch is only about a true/false (or applied/not applied) state we can use a single bit, while if we make a change using a number that could have different values we'll have to use a whole variable, saving the specific number used in our patch in that variable
4) When the game is to be saved and the global trigger GT_BEFORE_SAVING_VARIABLES has been enabled, we have to detect if our patch is really activated in that moment, because it could be not yet applied, of course
5) If in game we discover it has been applied, we'll have to put our signal: the bit 1 (value 2) of LL_Alfa will be set.
6) In our project to verify if the patch had already applied just check the memory field that could be changed: the Slot.Pointer Collision procedure.
7) If that field is zero, this means we have already applied the patch, and we set the bit 1 in LL_Alfa

Standard procedure to reloading our patches
1) When the it will be activated the GT_AFTER_RELOADING_VARIABLES global triggers, we'll perform a trigger group to test if our signal is present.
2) In our example we have to test only the bit 1 of LL_Alfa variable, but if we had many patches we should have to test many different memory fields
3) If we found the signal, we have to apply newly the same patch, therefore we'll write newly a 0 in Slot.Pointer Collision memory field
4) While if the signal is missing, this means there was no patch applied when the game has been saved, so we have nothing to change because the defalt values will be already restored by load game procedure.




Tips & Tricks

In this chapter we'll see some little tricks to use in best way the variable features.

How discover the sense of some memory fields

The descriptions of many memory fields are missing or inaccurate, because I'm not the author of Tomb Raider engine and therefore I only tried to understand how it works but in this operation I could have wronged in many circustances.
The best way to understand how works a field is to see in what way it changes during the game.
So, if you want understand how a given field works , i.e. what values will be written in that field from the tomb4, and what those values mean, you can use this easy method:

1) Create a TriggerGroup that read the content of memory field you want study and copy this value in a common numeric variable.
2) Now, using a GlobalTrigger with the GT_ALWAYS, perform continuosly (i.e. ALWAYS) above trigger group
3) Now we'll have in some variable the content of our memory field to study
4) Now we can simply enable the diagnostic for variables to have on screen that value continuosly updated
5) Then, in the case it changes too fastly, we could show this value also in the log file created with the tomb4_log.exe utiltiy
6) To print our value in log file just we add to our triggergroup also the flipeffect "Variables. Log. Print in log file the <&>Extra NG String"
7) We use as Extra NG String a text with a variable placefolder to show the current value of that variable.
8) Now, in game we can see how the contents of that field changes in according with our actions in game.

Insert in Diagnostic messages the content of memory field
Now we'll create a pratical example of above procedure.
Let say we want study better the working of "Flags of Item" field of Memory Item.
As first step we'll place in our project the enemy we'll use for this study, and we create an action trigger on this item to set the Selected Item Memory for it.:

; Exporting: TRIGGER(54:0) for ACTION(495)
; <#> : HARPY ID:495 in sector:(10,7) of Room70
; <&> : Variables. Set the index of <#>moveable as Selected Item
; (E) :
; Values to add in script command: $5000, 495, $36

We chose the Harpy item.
Now copy above exported trigger in script.txt

Then we add other exported trigger to copy the value of "Flags of Item" field to the variable Local Long Delta

; Exporting: TRIGGER(10098:0) for FLIPEFFECT(256)
; <#> : Variables. Memory. Copy to <&> Numeric Variable the (E)Selected Item Memory
; <&> : Local Long Delta
; (E) : Flags of Item (Long)
; Values to add in script command: $2000, 256, $2772

To have a list of all changes in "Flags of Item" field we add also a trigger to print the content of LL_Delta variable in the log file created with the utiltiy Tomb4_log.exe:

; Exporting: TRIGGER(1650:0) for FLIPEFFECT(309)
; <#> : Variables. Log. Print the value of <&>Numeric Variable in (E)Format
; <&> : Local Long Delta
; (E) : Hexadecimal and Binary
; Values to add in script command: $2000, 309, $672

Now we copy all above triggers in a new TriggerGroup:

TriggerGroup= 15, $5000, 495, $36, $2000, 256, $2772, $2000, 309, $672

And, at end, we create our GlobalTrigger to perform always above TriggerGroup 15:

GlobalTrigger= 8, IGNORE, GT_ALWAYS, IGNORE, IGNORE, 15

Then we have to enable the diagnostic for variables in the [Options] section of the script:

Diagnostic=          ENABLED
DiagnosticType=          DGX_COMMON_VARIABLES, IGNORE

Well done. Now we completed the job on the script.txt file.

In the project we'll place somewhere a trigger to enable out item, the Harpy, because it will be interesting to see the value of "Flags of Item" first of activation and then we triggered the item.

Now we can build the script and the level, we'll start the "Tomb4_log.exe" utility, if we wish having the list of log file, and then we play the game.
On the screen we'll see the Delta variable changes when the "Flags of Item" changes, while in log file we'll be able to see all the list of changes in progression.

Study the log file
In our example I got these changes of values in the log:

6859: Local Long Delta = %00000000000000000000000000100110 $26 ;not yet enabled
26078: Local Long Delta = %00000000000000000000000000100011 $23 ;enabled in game
67266: Local Long Delta = %00000000000000000000000000110011 $33 ;lara shots harpy
67297: Local Long Delta = %00000000000000000000000000100011 $23 ;nothing
67609: Local Long Delta = %00000000000000000000000000110011 $33 ;lara shots harpy
67641: Local Long Delta = %00000000000000000000000000101011 $2B ;harpy touches lara
67906: Local Long Delta = %00000000000000000000000000100011 $23 ;nothing
70078: Local Long Delta = %00000000000000000000000000000100 $4 ;harpy has been killed

I chose the log of variable with binary format to recognize immediatly the single bit changing.

I added the comments at right about what I was doing when it occured that change in Flags of Item

Looking above log we can discover for example that, when lara hits the harpy the bit $10 will be added for a short instant (from $23 to $33 = + $10), so the $10 bit should mean "Current item has been injured"

Then we could discover other interesting facts (really already known, see the The Item Memory Zone )
The bit $20 is present when the harpy has not yet been enabled, and it remains when it has been enabled, but it disappears when the harpy has been killed.
So we could think about the $20 bit as "The enemy is yet interesting for the game. It is to enable or it is living". While when the bit $20 is missing the enmey is dead and it will be no more used.

Find an usage for our discoveries
Once we discovered some interesting flag, we could perform an experiment modifying with some trigger that flag to see if we can get some of interesting in this way.
For example, about above discovery, we could try to write in "Flags of Iitem" of Harpy, atfter it has been killed, the value $26, i.e. the value was present before its activation, to verify if then this operation we can enable it newly, in spite it was already killed.
These experiments are useful also like a verification about our discoveries.

Perform Experiments
Another method to discover the sense of some field or flags in a given field, is to write in that field some value and then see what happens in the game.
For example there are many flags of "Flags of Item" that I've not ever found in the game, but pheraps some of them is really usefull in some matter. A way to discover is: to try it.
For example I'm not sure about what means the bit $0002 in the "Flags of Item" field.
A mode to discover is try to enable that bit while the harpy is living to see what happen in the game in that moment.
Remember that to enable a single bit you have to use a "Bit operation". To create that bit you use "Set bit" while to remove that bit you use "Clear bit"

When you perform these experiments it's probably you'll have often the feeling that nothing happened, but pheraps you should only apply different actions on that item to test the change in better way.

For example you could place other creatures to see if your change modifies the rapport between our harpy and other enemies.
You could try to shoot the harpy to see if there are some differences in combat phase now.
You could try to place some AI items below the harpy to see if at least in this way there is some change.
Ect.

Enable the debugging for script commands

The building of new skills is a complicated matter.
You'll have to create many TriggerGroups, conditional triggers and perform mathematic operations with variabile, other (in some cases) to have to save and reload your changes in variables before saving the game.
It's probably that for these reason, your code doesn't works fine at first attempt.
When you don't understand becuase your script commands don't work it's advisable enable the debugging for script commands, so to have the chance to see what happens in the trng engine while you are testing your new skills.

Full debugging or concise debugging
To enable the debugging you use the script commands for diagnostics:

Diagnostic=          ENABLED
DiagnosticType=          DGX_LOG_SCRIPT_COMMANDS, IGNORE

When you use the DGX_LOG_SCRIPT_COMMANDS flag in DiagnosticType command, no new value will be showed on the screen but you'll have in log file created with Tomb4_log.exe utiltiy (you find it in TRLE\TOOLS folder) a long list of diagnostic mexages everytime trng performs some TriggerGroup, GlobalTrigger, Organizer or Switch.

There are two kind of script debugging: the full debug, that you enable with the command:

DiagnosticType=          DGX_LOG_SCRIPT_COMMANDS, IGNORE

And the concise debugging that you enable adding to above command the EDGX_CONCISE_SCRIPT_LOG value

DiagnosticType=          DGX_LOG_SCRIPT_COMMANDS, EDGX_CONCISE_SCRIPT_LOG

About advantages and disadvantages of this choice you can consider that:

The full debugging has more informations, so you can really find all that happens in your script commands, but it has the disadvante to create a huge log file, where it will be more difficultous find the right point to analyse.
While the concise debugging is the opposite: you have less informations but you get a more concise log file that it will more easy to read.

I suggest you to perform you first attempt with concise debugging, and only if you don't find the problem you may try with full debugging.

Example of Script Debugging
Here we have an example of concise log of demo project, when Lara stops the timer countdown and she gains some medipacks

95485: {Global Long Timer} = 900
108266: Perform TriggerGroup=2
108266:           Perform Trigger: [$2002, 265, $1]
108266:                     "Variables. Timer. Stop the <&>TRNG Timer" <<&> = 1 (E) = 0>
108266:                     TriggerResult=true
108281:           Perform Trigger: [$2002, 270, $301]
108281:                     "Variables. Timer. Hide <&>TRNG Timer in (E)Seconds" <<&> = 1 (E) = 3>
108281:                     TriggerResult=true
108281:           Perform Trigger: [$2002, 271, $33]
108281:                     "Variables. Numeric. Copy <&>Numeric Variable to CurrentValue" <<&> = 51 (E) = 0>
108281:                     {Global Long Timer} = 518
108297:                     {CurrentValue} = 518
108297:                     TriggerResult=true
108297:           Perform Trigger: [$2002, 253, $1EFF]
108297:                     "Variables. Numeric. Divide <&>Numeric Variable by (E)Value" <<&> = 255 (E) = 30>
108297:                     {CurrentValue} = 518
108297:                     {CurrentValue} = 17
108297:                     TriggerResult=true
108313:           Perform Trigger: [$2002, 273, $3A]
108313:                     "Variables. Memory. Add to <&>Savegame Memory the CurrentValue" <<&> = 58 (E) = 0>
108313:                     {Inventory. Small medikit} = 3
108313:                     {CurrentValue} = 17
108313:                     {Inventory. Small medikit} = 20
108313:                     TriggerResult=true
108328:           Perform Trigger: [$2002, 64, $506]
108328:                     "Text. Print ExtraNG <&>string on screen for (E) seconds" <<&> = 6 (E) = 5>
108328:                     TriggerResult=true


How you can see from above log, everytime a variable has been used (read, written or tested with a condition) its value will be showed in the log.
This feature is very often a big help to understand what doesn't work in your script commands.

Conditional Triggers
About that "TriggerResult=true" you see in above log, it could seem weird since they are not conditions, anyway this is normal: also the common triggers return always a result and for the command triggers it will be always "true" while for condition triggers the result could be true or false, of course.
Thanks to this method you can insert in a conditional TriggerGroup also some common (non conditional) triggers, and this chance is very important when you need to move a value from a variable to another before performing a condition.

See this example of log file in full mode:

5735: SCAN GlobalTrigger=2
5750:           GlobalTrigger=2, check for ConditionTriggerGoup=4
5750:                     Perform TriggerGroup=4
5750:                               Perform Trigger: [$8002, 112, $2C]
5750:                                         "Variables. The <#>Numeric Variable has the (E)Bit set" <<#> = 112 (E) = 0>
5750:                                         Required to use index of trigger (TGROUP_USE_TRIGGER_ITEM_INDEX)
5750:                                         {Local Long Alfa} = 1
5750:                                         TrigggerResult=true
5766:                               Perform Trigger: [$2002, 256, $4FF]
5766:                                         "Variables. Memory. Copy to <&> Numeric Variable the (E)Selected Item Memory" <<&> = 255 (E) = 4>
5766:                                         Required to use index of trigger (TGROUP_USE_TRIGGER_ITEM_INDEX)
5766:                                         {State Id Now} = 1
5766:                                         {CurrentValue} = 1
5766:                                         TriggerResult=true
5781:                               Perform Trigger: [$8002, 3, $30]
5781:                                         "Variables. The Current Value variable is = than <#>Value" <<#> = 3 (E) = 0>
5781:                                         Required to use index of trigger (TGROUP_USE_TRIGGER_ITEM_INDEX)
5781:                                         {CurrentValue} = 1
5781:                                         TrigggerResult=false
5781:                               Conditional block is false
5797:                               END TriggerGroup=4
5797:                     ConditionTriggerGroup = false
5797:           END GlobalTrigger=2
5797: XXXXXXXXXXXXXXXXXXXXX START NEW GAME FRAME XXXXXXXXXXXXXXXXXXXXX


In above conditional trigger we tested two conditions:
1) Verify if in Local Long Alfa variable the bit 0 (value 1) is set
2) And if the current state id of lara is 3

While for first condition we can perform it with a single trigger, with other condition for state id of lara is not possible because we need to move the value from "State-id" item field to a common variable before checking it with a condition trigger.
Luckly this operation is possible since the non-conditional trigger to move the value from state-id to current value don't modify anything in the conditional list.

Break and resume the debugging log
When you use the full debugging the quantity of text written in the log file is huge.
If you need of some time to reach the correct position for your test you could get some MB of log file for nothing.
In this case you can use the function key F9 to break temporary the debugging mode, and resume it later, always using the F9 key.

Force the saving of coordinates about some Moveable

If you use some variable flipeffect to change the position of facing of some moveable you could need to use an Action trigger to say to trng engine to save and then reload the coordinates (and facing) of this moveable in the savegame.
To realize this target you have to use following action trigger:

"Enemy. Save the coordinates and facing of <#>Moveable in savegame"

There some considerations we can do about this situation:

1) If it's possible it's better using the standard Action triggers to move items or change their facing, both to re-build an your own procedure to do the same thing.
The trng action triggers have been tested for a long time and they save and reload byself the position and facing of changed items.
2) It's not always necessary perform above action trigger, you have no need of it, for example, if the item is a creature, because all creatures (moveables with AI features) will be always saved and reloaed in/from savegame.

How detect time intervals without using the timer

In the variable project we used the trng timer to check when it elapsed 1.5 seconds from start of super jump.
There are many situations where we wish keep the control of elapsed time.

If we have too new skills working togheter the two trng timers could be not enough for all our requests.
Fortunately there is an easy trick to have many counter in same moment and it's not necessary using trng timers.

You can use the Organizer Timer value, you can read it in Savegame Memory.
The Organizer timer will be always updated while the program is in game mode (no inventory or pause screen).
Thanks to this timer we can save the current Organizer timer, and then verify how much tick frames have elapsed from last reading.

For example if we want compute when it will be elapsed 30 tick frames from a given moment, just we copy the Organizer Timer in a long variable, for example the Beta variable, and in following cycles we could check how much time has elapsed with the formula:

TimeNow = OrganizerTimer - Beta

This method permits to have multiple timers to syncornize our effects.