The NGLE Manual
Level Endings: the Classic
Style
By AkyV
I think everybody who played Tomb Raider
before TR4 knows what “classic level-ending” means:

So, the game freezes, the list of statistics pops up and we
can hear a typical audio file. And, after that, the game
loads the next level, of course.
And we can do the same in NGLE:

It’s easy:
1. Don’t use FINISH trigger where you want the end of the
level. Instead of that, place a FLIPEFFECT there that
activates a TriggerGroup – for example, TriggerGroup#1:
; Set
Trigger Type - FLIPEFFECT 118
;
Exporting: TRIGGER(257:0) for FLIPEFFECT(118)
; <#>
: TriggerGroup. Perform <&>TriggerGroup from script.dat in
(E)way
; <&>
: TriggerGroup= 1
; (E)
: Single performing (to use when in TriggerGroup there are
only commands)
;
Values to add in script command: $2000, 118, $101
2. Place the entry of that TriggerGroup in the Script:
TriggerGroup= 1, $2000, 130, $0, $2000, 129, $2C, $2000,
223, $0, $2000, 82, $2
; Set
Trigger Type - FLIPEFFECT 130
;
Exporting: TRIGGER(0:0) for FLIPEFFECT(130)
; <#>
: Sound. (CD) Stop CD track of <&>Channel
; <&>
: Channel 1 (Background track)
; (E)
:
;
Values to add in script command: $2000, 130, $0
; Set
Trigger Type - FLIPEFFECT 129
;
Exporting: TRIGGER(44:0) for FLIPEFFECT(129)
; <#>
: Sound. (CD) Play <&>CD track in (E) way on channel2
; <&>
: AUDIO\044
; (E)
: Single playback
;
Values to add in script command: $2000, 129, $2C
; Set
Trigger Type - FLIPEFFECT 223
;
Exporting: TRIGGER(0:0) for FLIPEFFECT(223)
; <#>
: Show Statistics Screen
; <&>
:
; (E)
:
;
Values to add in script command: $2000, 223, $0
; Set
Trigger Type - FLIPEFFECT 82
;
Exporting: TRIGGER(2:0) for FLIPEFFECT(82)
; <#>
: Delay. Load <&>level in (E)seconds
; <&>
: 2
; (E)
: Forever (use other action/effect to disable it)
;
Values to add in script command: $2000, 82, $2
So that’s what happens when TriggerGroup#1 has just been
activated:
1. The background audio stops.
2. Then that “typical audio” of audio folder starts. – In
this example that audio file has ID 044. (But it could be
anything else.)
3. Then the game freezes and the Statistics Screen pops up.
4. Hit ESC. – This is the way to close Statistics Screen and
make the TriggerGroup go on.
So, if you hit ESC, then the Statistics closes and the game
starts to load the level that has the given [Level] block in
Script. In this example that block is the second one. (But
it could be anything else.)
Notes:
1. Now we use “single playback” for the typical audio, as in
TR2. But you can use loop mode, as in TR3, if you want.
(Still on channel2.)
2. Nothing will be activated if the game awaits the player
to hit ESC.
That’s why you can’t place the audio triggers between the
triggers of the Statistics and the level-jump.
3. When the player hits ESC then the game will be active for
a short moment, after the frozen state expired, before the
loading starts.
In some situations it could be a bit ugly. – Just think
about it with this example:
Lara has just jumped back, to grab a ledge and hang down.
Under her, there’s the square with the
TriggerGroup#1-activator trigger. So the game freezes, the
Statistics Screen pops up. The player releases CTRL and hit
ESC. The game will be active for a moment so the player will
see Lara falling down before the level-jump, because CTRL
isn’t just pushed down.
4. It’s not a problem if you use that setup at the
“temporary end” of a level – i.e. if you can get back to
that level later.
Moreover, actually, you can use the setup anywhere in the
level (reform that to work properly under the new
circumstances: for example, you don’t need level-jumping
trigger in this case, of course), “just to show the
Statistics for the player, before (s)he continues playing”.
5. Don’t forget to clear up and adjust the usual specialties
of the level-jump:
Is ResetHUB needed?
Is Lara just riding a motorbike when jumping to the other
level?
Etc.
New
type statistics
You don’t need to use the Statistics Screen everyway. I.e.
you can use your own statistics, if you want.
Now I show in a simple example how to make your own
statistics:
a, You will use a background picture where the statistics
entries will be written on. – Save the picture in Pix
subfolder of Level Editor main folder, with name “Image”, an
ID and BMP extension, for example, as Image11.bmp.
I mean, in fact, this is only a frame, because the picture
will cover the texts, so the picture is transparent at the
points where it is overlapped with the texts. – This time
the frame is very simple:

The magenta part should be transparent in the game.
You need an Image command in Script for that bmp:
Image= 1, 11, IF_TRANSPARENCE+IF_QUIT_ESCAPE,
IGNORE, IGNORE, 250, 250, 500, 500
The Image#1 command says it will use Image11.bmp, placed it
in “250, 250, 500, 500” position. IF_TRANSPARENCE means the
magenta part will be transparent.
The presence of the picture will freeze the game (if it
doesn’t, then the Image#1 command had an IF_POP_IMAGE
constant).
IF_QUIT_ESCAPE means you will delete the picture off the
screen by hitting ESC.
The picture will be drawn on the screen by this trigger:
; Set
Trigger Type - FLIPEFFECT 217
;
Exporting: TRIGGER(1:0) for FLIPEFFECT(217)
; <#>
: Images. Show image with data in <&>Image script command
for (E)Seconds
; <&>
: Image= 1
; (E)
: Forever (use other action/effect to disable it)
;
Values to add in script command: $2000, 217, $1
----------------------------------
b, The Statistics will show now these things:
- title (“Statistics”) with the name of the level
- how many big medipacks Lara’s used in the level so far
- how many enemies Lara’s shot in the level so far
This trigger will print the title and the level name on the
screen:
; Set
Trigger Type - FLIPEFFECT 203
;
Exporting: TRIGGER(256:0) for FLIPEFFECT(203)
; <#>
: Text. Print formatted text <&>ExtaNg string with
(E)formatting data
; <&>
: 0: Statistics\nCOASTAL RUINS
; (E)
: Parameters=PARAM_PRINT_TEXT, 1
;
Values to add in script command: $2000, 203, $100
As you see, the title and the level name come from ExtraNG
#0 entry now. (“\n” means: “I hit ENTER”.)
This is the PARAM_PRINT_TEXT that the trigger uses:
Parameters= PARAM_PRINT_TEXT, 1, CL_RED, IGNORE, IGNORE,
IGNORE, 300, 300
So the text will be red, and in “300, 300” position.
----------------------------------
The medipack amount will be calculated with this
GlobalTrigger now:
GlobalTrigger= 1, IGNORE, GT_USED_BIG_MEDIPACK, IGNORE,
IGNORE, 4, IGNORE
So, if Lara uses a big medipack then TriggerGroup#4 will be
activated:
TriggerGroup= 4, $2000, 231, $148
; Set
Trigger Type - FLIPEFFECT 231
;
Exporting: TRIGGER(328:0) for FLIPEFFECT(231)
; <#>
: Variables. Numeric. Add to <&>Variable the (E)value
; <&>
: Local Byte Delta1
; (E)
: Value 1
;
Values to add in script command: $2000, 231, $148
It means 1 will be added to Local Byte Delta1 variable every
time when Lara uses a big medipack.
This trigger will print the entry of the big medipack on the
screen:
; Set
Trigger Type - FLIPEFFECT 203
;
Exporting: TRIGGER(513:0) for FLIPEFFECT(203)
; <#>
: Text. Print formatted text <&>ExtaNg string with
(E)formatting data
; <&>
: 1: Big Medipack Used #0048
; (E)
: Parameters=PARAM_PRINT_TEXT, 2
;
Values to add in script command: $2000, 203, $201
As you see, the “Big Medipack Used” text and its actual
value (#0048 means the value of Local Byte Delta1) – i.e.
how many big medipacks Lara’s used so far in the level -
come from ExtraNG #1 entry now.
This is the PARAM_PRINT_TEXT that the trigger uses:
Parameters= PARAM_PRINT_TEXT, 2, CL_GOLD, IGNORE, IGNORE,
IGNORE, 300, 400
So the text will be colored gold, and in “300, 400”
position.
----------------------------------
The killed (shot) enemies will be calculated this way now:
First of all, place this trigger on a square where LARA
object is placed:
; Set
Trigger Type - FLIPEFFECT 244
;
Exporting: TRIGGER(20560:0) for FLIPEFFECT(244)
; <#>
: Variables. Memory. Copy to <&>Numeric Variable the
(E)Savegame Memory value
; <&>
: Local Short Alfa1
; (E)
: Statistics. Killed Enemies (Short)
;
Values to add in script command: $2000, 244, $5050
So, if Lara starts this level then the data about how many
enemies she’s killed so far will goes to Local Short Alfa1
variable. (Be careful: this trigger is not allowed to be
activated again.)
When the level ends, this trigger records the data about how
many enemies Lara’s killed so far – and puts the value into
Current Value variable:
; Set
Trigger Type - FLIPEFFECT 244
;
Exporting: TRIGGER(20735:0) for FLIPEFFECT(244)
; <#>
: Variables. Memory. Copy to <&>Numeric Variable the
(E)Savegame Memory value
; <&>
: Current Value
; (E)
: Statistics. Killed Enemies (Short)
;
Values to add in script command: $2000, 244, $50FF
Then this trigger subtracts the starting value (Local Short
Alfa1) from the ending value (Current Value), giving a new
value to Current Value:
; Set
Trigger Type - FLIPEFFECT 286
;
Exporting: TRIGGER(80:0) for FLIPEFFECT(286)
; <#>
: Variables. Numeric. Subtract from CurrentValue the
<&>Numeric Variable
; <&>
: Local Short Alfa1
; (E)
:
;
Values to add in script command: $2000, 286, $50
(So, for example, if the starting value is 18 and the ending
value is 27, then 27-18=9 will be the new value of the
Current Value that means Lara’s shot 9 enemies in the
level.)
This trigger will print the entry of the killed enemies on
the screen:
; Set
Trigger Type - FLIPEFFECT 203
;
Exporting: TRIGGER(770:0) for FLIPEFFECT(203)
; <#>
: Text. Print formatted text <&>ExtaNg string with
(E)formatting data
; <&>
: 2: Enemy Killed #0800
; (E)
: Parameters=PARAM_PRINT_TEXT, 3
;
Values to add in script command: $2000, 203, $302
As you see, the “Enemy Killed” text and its actual value
(#0800 means the value of Current Value) come from ExtraNG
#2 entry now.
This is the PARAM_PRINT_TEXT that the trigger uses:
Parameters= PARAM_PRINT_TEXT, 3, CL_GOLD, IGNORE, IGNORE,
IGNORE, 300, 450
So the text will be colored gold, and in “300, 450”
position.
(See more about these Script commands and constants in NG
Center\Reference, and about the variables in Variables demo
project of Paolone.)
And the solution is:

Attention!
As you
see, the example above shows level data and not game data.
And now, let’s see the whole script setup:
TriggerGroup= 1, $2000, 127, $1
TriggerGroup= 2, $2000, 130, $0, $2000, 129, $2C, $2000,
203, $100, $2000, 203, $201, >
$2000, 244, $50FF, $2000, 286, $50, $2000, 203, $302
TriggerGroup= 3, $2000, 217, $1, $2000, 82, $2
TriggerGroup= 4, $2000, 231, $148
Organizer= 1, FO_TICK_TIME, IGNORE, 0, 2, 1, 3
Image= 1, 11, IF_TRANSPARENCE+IF_QUIT_ESCAPE, IGNORE,
IGNORE, 250, 250, 500, 500
Parameters= PARAM_PRINT_TEXT, 1, CL_RED, IGNORE, IGNORE,
IGNORE, 300, 300
Parameters= PARAM_PRINT_TEXT, 2, CL_GOLD, IGNORE, IGNORE,
IGNORE, 300, 400
Parameters= PARAM_PRINT_TEXT, 3, CL_GOLD, IGNORE, IGNORE,
IGNORE, 300, 450
GlobalTrigger= 1, IGNORE, GT_USED_BIG_MEDIPACK, IGNORE,
IGNORE, 4, IGNORE
And that’s what will happen in the game:
First of all, Lara activates TRIGGER(20560:0) for
FLIPEFFECT(244) trigger at the start of the level to define
the killed enemies actual value.
Later, when Lara activates TriggerGroup#1 at the end of the
level by TRIGGER(257:0) for FLIPEFFECT(118) trigger, then it
means Organizer#1 will be activated ($2000, 127, $1). – We
need an Organizer to split the operation into two parts with
some time slip now, or else it won’t work properly. (As you
see – by FO_TICK_TIME constant and the second 1 in the
Organizer= 1 command – the time slip is very small, only 1
frame.)
The first part of the operation is defined in TriggerGroup#2
that is activated at once (see “0, 2” in Organizer= 1) when
Lara reaches the end of the level.
TriggerGroup#2 stops the background audio ($2000, 130, $0),
starts 044.wav ($2000, 129, $2C), prints the title+level
name ($2000, 203, $100), and prints the bigmedi data ($2000,
203, $201). Then calculates the “killed enemies” data
($2000, 244, $50FF, $2000, 286, $50) and prints that ($2000,
203, $302).
The second part of the operation is defined in
TriggerGroup#3 that is activated (see “1, 3” in Organizer=
1) 1 frame after TriggerGroup#2 has been activated.
TriggerGroup#3 puts Image11.bmp on the screen ($2000, 217,
$1), and - if the player hits ESC so that TriggerGroup#3 can
continue - loads Level#2 ($2000, 82, $2).
Note:
Be cautious with the setup if it contains level data and not
game data.
For example, do you want that value of the big medipack
(Local Byte Delta1) to be zero when Lara comes back to the
level? Because, if you make that zero (somehow), then the
Statistics will show you partial data when Lara leaves the
level (finally, this time). But if you don’t make that zero
then the partial data of the first level part and the
partial data of the second level part will be added in the
Statistics at the final end of the level and shows total big
medipack data on the level.
Forming the texts
As you see above, you can do text-forming customization on
your Statistics (color, position etc.) – anyway, whether you
use the original Statistics or some new one.
Caring about forming texts is a bit complicated in NGLE so I
decided I’d show you all the forming rules, and not only the
ones about the Statistics.
First
of all, I’ll define the text types I’ll use in the
description below:
- OLD TEXT: texts you can also find in TRLR or TRLE: texts
in the inventory, in the Statistics Screen etc.
- NGLE TEXT: texts (except Ammo and Feature Text) that the
new NGLE features use: the amount of done rotations
(parallel bars), the text for the standby effect, the timer
of “Enemy. Timer. Show the trigger count-down for <#>enemy
using (E)format” ACTION trigger etc.
- AMMO TEXT: text that is used for showing ammo amount on
the screen (this time it is not the ammo amount in the
inventory)
- FEATURE TEXT: texts of text/picture NGLE features (diary,
new savegame panel)
- INDEPENDENT TEXT: texts that you write mostly into ExtraNG
section of Strings to print them by Text FLIPEFFECTs
To form the texts, these are the tools:
- Defining basic fonts (except Feature Text) for all the
levels of the game: see font.pc in graphics\wads folder.
- Defining fonts (except Feature Text) for a given level:
put a FONT_GRAPHICS object into the WAD of the level (see:
new font demo project of Paolone), then use NG Font Editor
in NG Center\Tools.
- Defining fonts for Feature Text: see WindowsFont Script
command.
- Customizing Old Text colors: see CUST_SET_TEXT_COLOR
Script constant. (It works only on the kind of Old Text you
give in the command.)
Customizing of the level texts, the customization command
must be placed in a [Level] block usually.
Customizing of the level texts – if you want the validity of
the customization for the whole game – or the title texts,
the customization command must be placed in [Title] block.
- Customizing (in Script) Old Text sizes: see TextFormat
Script command (only SizeCharacterMenu field is valid now),
placing that in [Title] block. Valid for all the Old Texts
of the game (except: the text of Legend Script command).
- Customizing (in Script) NGLE Texts: see TextFormat command
(every field is valid now, except SizeCharacterMenu),
placing that in a [Level] block. – Using an NGLE feature
like that in the title you can use TextFormat in [Title]
block to form the text of the feature.
(I think this operation doesn’t work on all the NGLE texts.
It works, for example, for the standby effect text or the
enemy timer etc.)
- Customizing (in the game) NGLE Texts, if they can be
affected by TextFormat command: use “Text. Set” FLIPEFFECTs.
It overwrites (on that level) TextFormat command values or
the latest similar “Text. Set” trigger of that level. It
works for the texts that are just written or the texts that
will be written. It is valid only on that level, until the
next FLIPEFFECT like that.
- Annulling (on the actual level) every effect of TextFormat
command or all “Text. Set” FLIPEFFECTs for the NGLE Texts
that are just written or the NGLE Texts that will be
written: see “Text. Reset all text formatting settings with
default values” FLIPEFFECT.
- Customizing Ammo Text: see CUST_SHOW_AMMO_COUNTER Script
constant. Place it in a [Level] block usually. Place it in
[Title] block, if you want it to be valid for the whole
game.
- Customizing (in Script) “A” type Independent Texts: see
TextFormat command (every field is valid now, except
SizeCharacterMenu), placing that in a [Level] block. – Using
a text like that in the title level you can use TextFormat
in [Title] block to form the text.
“A” type Independent Texts are the texts that will be
written on the screen by a FLIPEFFECT that doesn’t use a
PARAM_PRINT_TEXT Script constant.
- Customizing (in the game) “A” type Independent Texts: use
“Text. Set” FLIPEFFECTs. It overwrites (on that level)
TextFormat command values or the latest similar “Text. Set”
trigger of that level. It works for the texts that will be
written. It is valid only on that level, until the next
FLIPEFFECT like that. – Only the proper FLIPEFFECT can be
used.
- Annulling (on the actual level) every effect of TextFormat
command or all “Text. Set” FLIPEFFECTs for the “A” type
Independent Texts that will be written: see “Text. Reset all
text formatting settings with default values” FLIPEFFECT.
- Customizing “B” type Independent Texts: see
PARAM_PRINT_TEXT Script constant.
“B” type Independent Texts are the texts that will be
written on the screen by a FLIPEFFECT that uses a
PARAM_PRINT_TEXT Script constant.
Made using TRNG 1.2.2.6
Back to Top