RMRK is retiring.
Registration is disabled. The site will remain online, but eventually become a read-only archive. More information.

RMRK.net has nothing to do with Blockchains, Cryptocurrency or NFTs. We have been around since the early 2000s, but there is a new group using the RMRK name that deals with those things. We have nothing to do with them.
NFTs are a scam, and if somebody is trying to persuade you to buy or invest in crypto/blockchain/NFT content, please turn them down and save your money. See this video for more information.
[RM2K3] Stealth

0 Members and 1 Guest are viewing this topic.

Rep: +0/-0Level 75
Let's Player
DON'T PANIC! When reading this - or scrolling down
and wetting yourself at it's size, please remember that I uh... talk a lot.

Keep with this, and you will be well rewarded :D

Things of important note: I am using this system in my game and I spent a
great deal of time creating it. And, in an effort to add to the community,

I am posting this before the release of my game - hence, inevitably,
stealing some of its thunder. I don't mind doing this, but I would
appreciate some form of note or credit - ie. adding a special thanks to...
or something somewhere, would be fine. The term "dynamic" is a programming
term used to describe one or more variables that (if there's more then one)

work together by sharing ever-changing data. The opposite is "static"
which refers to one or more variables that do not change unless
specifically told too.
This is an example of a static variable:
Variable = 1.

But enough. Let's get onto the scripting!

Step 1 - the overview.

The Dynamic Stealth System works like this:
1) a series of variables are initiated detailing the number, range of
vision, and other necessities of what we shall call, "the guards".
2) the main loop takes this information and uses it to set up and activate
3) the main loop calls the current guard which relays to it it's location,
facing direction and ros (range of sight).
4) the sub-common-event detailing the guard's los (line of sight) then
takes the current information from the loop and uses it to perform los
5) the main loop goes onto the next iteration (in this case - the next
6) should the section be completed, or the player caught, this loop will
terminate ("break") and react appropriately.

When this is all finished, you'll have a fairly realistic, lagless (give a
couple of the guards a wait 0.1 seconds at the end of their list of
commands), and easily re-usable stealth system! This is technically version

3 of the stealth system and by far the best, as it will allow you to
determine the number of guards you desire, the range of sight for each
guard, the location of the starting point (done by variables so it doesn't
need a separate long series of switch cases!) and pretty much anything you

...settle pride. Let's actually get this tutorial going :P lol.

Step 2 - the setup.
First of all, create the new switches you'll be needing:

...and the new variables:
Guard_X (for the guard's X co-ordinate)
Guard_Y (for the guard's Y co-ordinate)
Guard_Facing (for the direction the guard is facing)
Guard_ID (for the loop to track the current/next guard event).
First_Guard_Num (for the loop to know which event to start at.)
Last_Guard_Num (for the loop to know which event to start-over/end at.)
Guard_ROS (for the common events to know the range of the guard's sight.)

Hero_X (for the hero's X co-ordinate)
Hero_Y (for the hero's Y co-ordinate)
STH_Cur_Map_Num (number of the map where the player starts and will restart

if captured).
STH_Start_Hero_X (X co-ordinate where the player starts and will restart if

STH_Start_Hero_Y (Y co-ordinate where the player starts and will restart if


Stealth_One (A useless variable containing the number - "1.")
Stealth_Tries (A useful variable that tracks the number of attempts it
takes the player to successfully complete the stealth section - perhaps for

a prize? :) )
Stealth_Sys_Useless (Shockingly, this value is useless! :O ).

Now that you've done all that I must issue to you a few warnings:
1. When implementing this system ensure that you have finished placing any
other events beforehand... or at-least, please do not place a non-guard
event with an ID larger then the First_Guard_Num and smaller then the
Last_Guard_Num (between the two) or you will get an error. Errors are bad.
This is due to the natural setup of the loop and cannot be helped.

Step 3 - actually doing something.
Let's dive right in now and get all the unpleasantness - the common-event
scripting out of the way. It's a lot of code and you may find it hard to
follow at first, but stick with me and you'll be well-rewarded.

Common Event:
Name: LOS_Stealth_Sys_Main
Trigger: Call

Memorize Location: STH_Cur_Map_Num, STH_Start_Hero_X, STH_Start_Hero_Y
Variable Oper: Guard_ID Set equal to: First_Guard_Num.
Variable Oper: Stealth_One Set equal to: 1.

[This completes the initialization placed in the common event.]
>Memorize Location: STH_Cur_Map_Num, STH_Start_Hero_X, STH_Start_Hero_Y
>Branch if (Switch[STH_Sys_Found] is ON)
>>[The player has been caught.]
>>Break Loop.
>Branch if (Switch[STH_Sys_Complete] is ON)
>>Break Loop
>>End Event Processing
>>[Yea! The Player made it through! I'm not sure if the end event]
>>[processing part is required but meh.]
>Branch if (Guard_ID is Last_Guard_Num or more)
>>Variable Oper: Guard_ID set equal to: Guard_First_Num
>>[This is to loop over once the last guard has been reached.]
>:Else Handler
>>Variable Oper: Guard_ID +1.
>Call Event: Guard_ID, Stealth_One.
>[Get the needed information from the current guard.]
>Call Event: Stealth_Sys_GSearch
>:End Loop

[end of common event]

That wasn't so bad, was it? ...I hope :grin: I've added comments in some of

the less obvious places to inform you that there is a reason for that
command to be there and that I do not, in fact, smoke anything. lol.

It will probably scare you to know that that wasn't the largest of the 3
events. The next is the largest, so get ready, grab a beer (unless you're
under 18) and get ready to click... a lot... :D

Step 4 - a-LOS-a, jhonny a-LOS-a... hehe...

This is the most confusing part of the coding, so let me explain to you
exactly how the LOS calculations work.
1) take the guard and the hero’s x-location.
2) if they are the same, then there is a possibility the guard can see the
hero (vertically).
3) subtract the larger of the two y-co-ordinates from the other.
4) provided the result is less then the guard's range of vision, the hero
has been seen.

If this confuses you, think of it like this:

The Guard can see the tiles in the brackets (the number of which is
determined by the ROS).
In this case the tiles affected by the ROS do not contain the hero - the
hero and the guard are too far apart.

But in this case...

After the calculation is preformed, we can tell that the hero is occupying
a tile in the guard's line of sight.

I hope that made sense... 'cause if not, this could get really confusing
for ya! :)

[Comment: First check to see if the guard is on a valid x coordinate to see

the hero on the y coordinate.]
Branch if(Guard_X is equal to Hero_X)
>Branch if(Guard_Y is greater then or equal to Hero_Y)
>>Variable Oper: Guard_Y - Hero_Y
>>Branch if(Guard_Facing is 4 (down) Not.)
>>>Branch if(Guard_Y is less then or equal to Guard_ROS)
>>>>[The hero has been seen! (vertical up).
>>>>Switch Operation: STH_Sys_Found turn ON.
>>[Restore the Guard_Y to it's correct value.]
>>Variable Oper: Guard_Y + Hero_Y.
>:Else Handler
>>Variable Oper: Hero_Y - Guard_Y.
>>Branch if(Guard_Facing is 1 (Up) Not)
>>>Branch if(Hero_Y is less then or equal to Guard_ROS)
>>>>[The hero has been seen! (vertical down)
>>>>Switch Operation: STH_Sys_Found turn ON.
>Variable Oper: Hero_Y + Guard_Y.
[Vertical check is complete - now check horizontally.]
Branch if(Guard_Y is Hero_Y equal)
>Branch if(Guard_X is Hero_X or more)
>>Variable Oper: Guard_X - Hero_X.
>>Branch if(Guard_Facing is 3 (Right) Not)
>>>Branch if(Guard_X is less then or equal to Guard_ROS)
>>>>[The hero has been seen! horizontal left.]
>>>>Switch Operation: STH_Sys_Found turn ON.
>>Variable Oper: Guard_X + Hero_X.
>:Else Handler
>>Variable Oper: Hero_X - Guard_X
>>Branch if(Guard_Facing is 2 (left) Not)
>>>Branch if(Hero_X is less then or equal to Guard_ROS)
>>>>Switch Operation: STH_Sys_Found turn ON.
>>Variable Oper: Hero_X + Guard_X.

[end of common event].

Step 5 - "Game over, man! Game over!"- Aliens XD
Well guys, we're nearly there! All that's left is our final common event,
our init_event, and of course the guards (they're all identical, so I'm
just giving you a blueprint.)

Common Event:
Name: Stealth_Sys_Found
Trigger: Auto-Start
Trigger Switch: STH_Sys_Found
[put some dialog here if you want].
[start a battle here if you want].
Variable Oper: Stealth_Tries + 1
Tint Screen: R000,B000,G000,S000, 0.0 Sec (Wait)
Recall to Location: STH_Cur_Map_Num, STH_Start_Hero_X, STH_Start_Hero_Y
Tint Screen: R100,B100,G100,S100, 2.0 Sec (Wait)
Switch Operation: STH_Sys_Found turn OFF
Switch Operation: STH_Sys_Called turn OFF

[End of common event!]

nice and simple there. You're probably cheering over the finished common
events right about... NOW. :)

6) Initiating all the freakin' code.
It's been a long haul - but you're nearly there. The end is in sight!

Event: Stealth_Op_Start
Trigger Condition: Parallel Process
Event Layer: Below Hero
Do not Forbid Event Overlap
Variable Oper: STH_Cur_Map_Num set equal to [Map ID of map this event is
placed on.]
Variable Oper: STH_Start_Hero_X set equal to [Set your starting X coord
Variable Oper: STH_Start_Hero_Y set equal to [Set you starting y coord
Switch Operation: STH_Sys_Called turn OFF
Switch Operation: STH_Sys_Complete turn OFF
Variable Oper: First_Guard_Num set equal to [your first guard event's ID].
Variable Oper: Last_Guard_Num set equal to [your last guard event's ID].
Call Event: LOS_Stealth_Sys_Main
Switch Operation: STH_Sys_Called turn ON

Make a second page requiring STH_Sys_Called to be on,
change the start condition to action key, and leave the rest blank. (dummy


7) And for a fine deed to your country...

Congratulations to all of you who made it here. I know it hasn't been
easy. You've endured hardship, snow, rapid aging... and wtf am I talking
about? XD


The last piece of code I'll need to retype for this tutorial >:)

This is the blueprint for the guards:
Name: Guard.
Trigger Condition: Collision with Hero (he can't bump into them and expect
to go home free now can he?)
Event Layer: Same Layer as Hero

(You can make patrol routes for a guard by giving them a custom pattern
under movement type. This will not prevent their LOS from working properly


Variable Oper: Guard_X Set equal to This Event X Coord.
Variable Oper: Guard_Y Set equal to This Event Y Coord.
Variable Oper: Guard_Facing Set equal to This Event Facing
Variable Oper: Guard_ROS Set 6 (or whatever value you want).

...That really is it!

Simply copy-paste your new guard as much as you please - but play test it
to ensure you can still succeed! :D
Oh yes, and to remove any lag - simply give one (stationary works best)
guard a 0.1 second wait.

There are a few bugs - ie. Guards can currently see you through obstacles
(if it's smaller then their ROS), but it should be easy for you to fix this

By HeavyBlade