Creation/Dev/GS1 To GS2: Difference between revisions

From Graal Bible
No edit summary
Line 1: Line 1:
'''http://www.antiunixmad.com/
== Introducing the new scripting engine ==


Viper's Graal Issues.
This document is describing some problems and solutions
when switching from the old Graal scripting engine (GS1) to
the new engine (GS2). The new scripting engine has been
designed to on the one hand be compatible to the old
engine, and on the other hand provide new functionality
to make it easier to write Graal scripts and do more
interesting things with it. Those new things include
a windowing system (GUI), a particle engine, multi-dimensional
arrays, function parameter passing, true object orientation.


Hello everyone, as of late, many people have been attacking me on the issues and matters, trying to lie about things, bend the truth, and downright spin to make me and others of my cause look bad, in this text document i will discuss and lay to rest the issues that matter.
Since the old engine has been designed 7 years ago, a lot
of functionality has been added to that engine while the basic
design has not been changed, so a lot of modifications can be
more seen as a "hack" and are not very easy to use. For example
numeric variables and string variables must be accessed
in a different way, even more complex operations need to be
used to access numeric arrays and string lists.
The new scripting engine tries to stay compatible with the old
functions, but also add easier ways to access the variables.
Numeric and string variables can now be accessed the same way,
as well as numeric arrays and string lists.


I have been involved graal for over three years now, and i used to really like Graal and its admins alot, then slowly after about a year Graal and its admins went in a bad downward spiral, i still stuck with graal in hopes graal would pull itself out of this hole and unixmad would go back to the right path, this however did not happen, instead unixmad and even stefan went fouler and lower than i could have imageined, First with fireing Pachuka and Fuitad, two of the BEST graal admins ever in my view for no other reason than disagreeing with his future plans, then if just fireing them was not bad enough, he threatend to sue them and kill they're families, this was so wrong and bad Fuitad even said he would punch unixmad in the face for saying that if he met him in real life, but that was just the beginning of the downward spiral unixmad foolishly invoked onto graal, he then blatantly STOLE a domain name graal.net from Owl Shimy which costed over 30$ US Dollars, and never gave it back to him and never paid him for the cost of the domain, he also threatend to sue Owl Shimy and kill his family although it was Unixmad which stole the domain from Owl Shimy, then around Graal1.3.1 he blocked off Gservers officially and threatend to sue anyone that ran the former Gservers, although they were released as "Freeware" and actually used to encourage people to use the Gservers, this was a blatant attempt to monopolise , threaten, and intemidate that players that actually helped graal and supported him, he then made claims he copyrighted "Graal" and would contact so called "Lawres" about anyone that used the name "Graal" or had "Graal Files" on there websites, although graal was distributed as "Freeware" or "Shareware" and had no official software copyrights related to it, and that the name "Graal" was actually the name of a holy sacred golden cup used in some religion, and in that he has commited blasphemy against whatever religion has the so called "Holy Graal", then later on Unixmad fired SuperNick, because of his country and his origion and called him an American Asian slut, this was the first sign of racism on the part of Unixmad, towards Graal1.4.1 Unixmad was secretly unwrapping his sadistic plans, he then started claiming credit and claiming to own the copyrights to graal, although unixmad has done nothing but host some stupid weak as servers, and yet Stefan Knorr has done all the real work for Graal, and was the one to make ZeldaOnline , GraalOnline in the first place and has written every bit of codeing for the Graal Client , Gserver, RC, ect, yet unixmad the worthless pile of trash that he is steals all credit for Graal, then in February 2001, Unixmad and Antago release Graal2001 and the start of the "Pay to Play" system, now i have no problem with the fact that it is pay to play, the issue is when you PAY for something you actually expect to get the worth while of your money in this product, but instead they got a shittily made level generated land that was 99% empty, the NPCs were and are laggy as hell, and there were no quests, and there is only two shitty things today for hearts that suck so much i refuse to even call them quests, and to add to that about 40% of everyone that paid and gave unixmad there credit card number NEVER got the accounts they paid 27$ or more for, and those that did clearly got chumped out by a cheap peice of crap that aint worth paying for, it sucked so badly that most people played on Graal Classic still, even those that foolishly paid for pay to play accounts, and in an attempt to "FORCE" people to pay for a shitty product they do not want against they're will Unixmad hired "Tyhm" to deface and ruin GraalClassic in an attempt to make it buggier and less fun than even Graal2001, about this time i was disgusted with unixmad and most of the other admins and decided to downright turn against Graal and for the most part stop playing the peice of crap in general. People starting getting angry, complaining, asking for help, and asking for refunds, of coarse unixmad gave noone a cash refund, and simply deleted and banned "PAID ACCOUNTS" of those who complained, asked for help, or asked for a refund these are PAYING CUSTOMERS, they have the rights of basic service that they PAID for, unixmad promises pay to play players a quality product and customer service, but instead gives them a grade F product and ripps off his customers and delete they're accounts that they PAID HIM money for, his excuse? Credit card fraud, when infact at least 90% of the people he bans for credit card fraud pay legitamately with there OWN credit cards or pay via paypal by check, and yet Unixmad has stolen and used others credit card numbers to buy things for himself on several occassions, he also claims he needs pay to play money to keep graal alive and running, yet there has been evidence that he makes at least 90% profit out of the monies he gets, and that he uses illegal porn ad banners and illegal cookie style web tracking and giveing email adresses of the players and even phone numbers of every player to spam and telemarketting companies without there permission, he even keeps personal player info, includeing email, adress, and phone number on unsecure servers which have already been leaked out, such info about people should not be on a public webserver accessable to the internet in anyway, then after all that Unixmad starts banning african american people, asians, koreans, and or people with images of people of that race from the Graal2001 forums and graal itself, yet again they are paying customers and this is another sickening act of racism on the part of Unixmad and GraalOnline, and then even more disgusting is what Stefan posts on the Graal2001 forums, he makes several anti american, racist, pro terrorist, pro nazi, and pro taliban comments on that post and goes on and on several pages bashing americans, this post was offense, obcene, and disgusting to many people includeing myself . If all that does not make you sick to your stomache or dislike unixmad yet, i am far from done, then Unixmad proceeds to illegally DDOS webservers of mafukie and make threats to him over the phone, and has phone assaulted me over 40 times a day between midnight and 5am, and has made threats to sue dozens of people, kill there families, and shut down innocent websites and servers, while hosting illegal stuff and doing illegal things himself with the use of his own wanadoo.fr servers, stuff which includes child porn, bestiality porn, DVD Piracy, DDOS Attacks, theft of copyrighted materials from gameing companies such as nintendo, Credit Card fraud, theft, spamming, phone harrassment, useage of illegal pirated corperate softwares, all this just to start the list of what Unixmad, Stefan, and they're servers are doing 24/7 for nearly 4 years now , anyone that likes unixmad or thinks he is a good person even after all this is clearly a fool, everything in this document is the truth and why i hate unixmad so much, if you like unixmad after all these sickening things he does, then you are no better than a KKK or Neo Nazi member and should go kill yourselfs, i do not tolerate facists, racists, or nazis, they are all bad people, and unixmad is one of the worst of the worst, and no person with any morales could tolerate or support such a person like Stephane Portha or Stefan Knorr. The people that spin, lie and bend the truth in support of unixmad will always exist, but i will always reveal the truth about unixmad, and EVERYTHING said in this document is true, despite what any assclowns try and say about this, and this supriseingly enough is only 1% of the bad things Unixmad has done, how some people even tolerate, none the less support such a bad person is beyond me... I fight against bad people like unixmad, why? Because unlike many others in this world i actually care about other people, and i will do everything in my power to stop unixmad from hurting graal or its innocent players, many say i want to destroy and kill graal, this is NOT true, i used to love graal, i only wish to stop unixmad's evil sadistic illegal actions and restore graal to the great game it used to be when it was "for the players, by the players" , but if i have to destroy GraalOnline in exchange to stop unixmad's tyranny, it will be regreteable, but sometimes some sacrifices have to be made for the greater good, lets just hope that unixmad drops dead and that sacrifice never has to be made... I love graal and lots of its players, and i wish to someday restore it to the grandness it once had, but bad people like unixmad must be gotten rid of if that is to be achieved...'''
To make the new functionality easy to use, some old "hacky" ways of
accessing variables are not supported anymore. If scripts are
written correctly without using those methods, then they will work
fine in the new engine. If not, then they need to be fixed manually.
In generally there are not a lot of scripts using those problematic
ways of accessing variables, but sometime scripters just use
copy & paste and so also copy the error to a lot of scripts. Then
the only solution will be to edit those scripts manually, copying
the fixed code part to the other affected scripts, or directly use
classes and the ''join'' function.
 
== Using the correct syntax ==
 
The new scripting engine finally reports syntax errors, when
modifying scripts you see the error output on RC chat (RC is
short for [[RC|RemoteControl]], an admin tool for Graal). If there
are errors while the npcserver is starting up, then the errors
are written in to logs/syntaxerrors.txt.
The new engine also reports errors while running the scripts,
including endless loops (loops are limited to 10000 cycles)
and call of non-existing functions. On clientside those
errors are output into the F2 window, on serverside they
are displayed on RC chat, but can also be redirected to
file using the [[server options|server option]] ''logscripterrorstofile=true'',
the errors will then appear in logs/scripterrors.txt.
 
While some people might get headache when seeing a lot of
script errors, that error reporting is actually giving you
the possibility to track errors easily. While the new engine
is not accepting as many syntax hacks as the old engine,
it is actually easier now to fix them.
 
=== Closing brackets ===
 
An error that often happens is a missing opening bracket or
missing closing bracket. The best way to not accidently do
that error is to follow a constant and ordered scripting
style, indenting scripting lines, using spaces between
operators. Each time you open a '''{''' bracket you indent the
following lines by 2 spaces. You can also use 4 spaces, that
doesn't matter as long as you keep the same number of spaces
in the whole script. Tabulators are not recommended since
special characters are automatically removed by the engine.
When you afterwards use a '''}''', then you stop the indenting.
That way you can check the correct number of opening and closing
brackets by just watching if the last closing bracket appears
at the very beginning of a line.
The Graal script compiler doesn't require that indenting, but it
is still recommended.
 
=== Semicolon ===
 
A thing that is quite simple to keep care of but is often
done wrong is to add semicolons behind commands. That must
be done to separate the commands from each other.
In the old scripting engine it was possible to forget the
semicolon if the next character was a closing bracket '''}'''.
The bracket was automatically finishing the last command.
In the new engine that it possible too as long as the last
command is a function call, it's not working if the last
command is an assignment:
 
<pre>
Bad:  if (playerenters) {x=3}
Good: if (playerenters) {x=3;}
</pre>
 
Scripters also often think that a closing bracket '''}'''
never needs a semicolon behind it, although the semicolon is
required if the brackets are used for defining an array or
subscript:
 
<pre>
Bad:  setshape2 2,2,{0,0,0,0}
Good: setshape2 2,2,{0,0,0,0};
</pre>
 
That mainly affects the function calls ''setshape2'', ''showpoly''
and ''putnpc2''. Those always require a semicolon at the end,
no matter if the function parameters are finishing with a
closing bracket '''}'''.
 
=== Syntax incompatibilities ===
 
While most old scripts compile fine when having no syntax
error, there is one exception when a correct old script
is not working with the new scripting engine: the
in-operator is different:
 
<pre>
Works in GS1:  i = (playerx,playery in <20,40>);
Works in both: i = (playerx in <20,40> && playery in <20,40>);
Works in GS2:  i = ({playerx,playery} in <20,40>);
</pre>
 
== Variable lookup ==
 
As described in chapter one, the variable lookup has been
changed in the new scripting engine. Lookup means the
behaviour how variable names are translated into actual
object attributes, or to be more close to the hardware,
lookup is the translation into memory addresses.
That means that a variable that was formerly connected
to one value, is now connected to another value, and
eventually having different behaviour when modifying it,
and is so changing the logic of the script or even
mess it up.
 
=== Example ===
 
Several scripts were using the variable ''this.x'' to store
temporary data, or just as for-loop variable.
While in the old engine ''this.x'' was just a numeric scripting
variable, it is now redirecting to the ''x'' value of the
current script object (''this''). So if you modify it, then
the npc is magically starting to move, which was
probably not the intention of the scripter.
In that case the variable name must be modified to something
like ''i'' or ''temp.i''.
 
=== Variable types in the new scripting engine ===
 
The new scripting engine (GS2) has basicly 3 types of variables:
 
* Object variables: objectname.variablename <br> Object can be ''this'' for the current object, or ''player'' or an NPC name like ''DB_Items''. The variable will then access the attributes of the object if there is a built-in attribute with that name (e.g. ''this.x''), or a script variable belonging to that object (e.g. ''this.i'')
 
* Attributes of the active object: attributename <br> If there is no leading, then the attributes of the current script object (for which the script is executed) are accessed, if there is an attribute with that name, e.g. ''x''.
 
* Global variables: variablename <br> If the variable name has no leading and is not matching a built-in attribute of the current script object, then it is taken from the global variable pool. This is different to most other scripting languages where variables without leading are seen as local variables, but this behaviour is required to be compatible with the old scripting engine. Also it is a simple way to share data between scripts - you can set a flag in one script and read the flag in another script without needing to know where it is stored. Global variables are not saved, so they are not persistent and disappear after a server restart.
 
There are a few exceptions to this lookup scheme, e.g.
function parameters can be accessed without a leading in
front of the variable name. Also the ''with'' operator can
temporary modify the current script object (''this'').
In generally you don't need to care about those exceptions,
to be sure that everything is working fine you should
prefer to add a leading in front of variable names
though.
 
=== Change of variable lookup ===
 
==== Attributes of the current object ====
 
As described in chapter 3.1., the built-in attributes of the
current object can be accessed by ''this.x'', ''this.y'' etc. now.
In the old scripting engine that was not possible, those
variable names were used for normal variables. That means
if your scripts are using such variables, make sure that it is
used for the correct thing. That includes numeric variables
(''this.x = 3;'') as well as string variables (''setstring this.x,3;'');
 
Most common variables that need to be changed:
* ''this.x'', ''this.y'', ''this.dir'', ''this.hp'', ''this.ap''
* ''this.hp'' on serverside
* ''this.width'', ''this.height'', ''this.image''
 
==== Global variables ====
 
Variables without leading are global now. While on clientside
that was already the case in the old scripting engine, on
serverside those variables were formerly only accessible in the
current script. If you are using such variables, don't trust
that other scripts are not modifying it. Eventually rename
those variables, or use ''this.variables'' which are only working
for the current object, or ''temp.variables'' which are only working
in the current function body.
 
==== With-Operator ====
 
The ''with'' operator is temporary changing the current
script object (''this''): all ''this.'' variables inside the
opening and closing bracket are redirected to the
with-object instead of the executing script object.
Example:
 
<pre>
this.myvar = 3;
with (findplayer("Max")) {
  this.myvar = 5;
}
</pre>
 
After executing that code, ''myvar'' of the npc has
the value 3, while ''myvar'' of the player "Max" has 5.
The player "Max" is the with-object in this case.
While both variables are accessed using the same
variable name, they are directing to different
variables.
In the old scripting engine ''this'' was only modified
when the with-object is another npc. In the new
engine any script object can overwrite ''this''.
 
Another thing that you need to keep care of is that you
can also access the built-in variables of the with-object
without using the ''this'' leading:
 
<pre>
x = 20;
with (findnpc("Turret")) {
  x = 30;
}
</pre>
 
In this case the ''x'' position of the current npc will
be changed to 20, while the ''x'' position of the Turret
will be changed to 30.
The only exceptions for this behaviour are the variables
''x'', ''y'', ''dir'' and ''ap'' when using a player as
with-object: an ''x'' without leading will never direct
to the ''player.x'' variable, it will always take the
npc for which the script is executed, or the npc that is
positioned highest in the ''with''-stack when using several
''with''-operations inside each other.
 
=== Numeric variables, string variables and array using the same name ===
 
One major improvement in the new scripting engine is that
you can easier access string variables and arrays. One
drawback is that if you have used numeric variables, arrays or
string variables with the same name, those are now directing to
the same variable. So you will need to modify the variable
names if they are supposed to hold different data:
 
<pre>
Bad:
  this.myvar = 1;
  setstring this.myvar,2;
  this.myvar = {1,2,3};
 
Good:
  this.mynumericvar = 1;
  this.mystringvar = "2";
  this.myarrayvar = {1,2,3};
</pre>
 
== Easier access to string variables ==
 
You only need to read this chapter if you want to use the
new way of accessing string variables, it is not
required to make old scripts compatible.
 
String variables can be accessed easier now:<br>
Writing string variables:
<pre>
Old: setstring this.myvar,text;
New: this.myvar = "text";
</pre>
 
Reading string variables:
<pre>
Old: #s(this.mvyar)
New: this.myvar
</pre>
 
You can see that string variables can now be accessed
similar to numeric variables. Sometimes the variable
name must have a different leading though to access
the same variable:
<pre>
Old: setstring varwithoutleading,text;
New: player.varwithoutleading = "text";
</pre>
 
Also constructing dynamic variable names for string
variables is different now, you need to use the
new syntax. This documentation is not for explaining
the complete syntax, but it might help to lead you
to the correct path:
<pre>
Old: setstring this.item#v(itemnumber),apple;
New: this.("item" @ itemnumber) = "apple";
</pre>
 
You need to keep care on following things:
* you concat strings using @
* if you want to concat a string to another variable, don't forget to put "" around it to mark it as string
* never put a dot inside the dynamic variable name:
<pre>
Bad:  ("this.item" @ itemnumber)
Good: this.("item" @ itemnumber)
Good: ("Party" @ partynumber).name
</pre>
* never use array brackets in the dynamic variable name:
<pre>
Bad:  this.("item[" @ index @ "]")
Good: this.item[index]
Good: this.("itemstats_" @ itemnumber)[index]
</pre>
 
== Server-side and client-side ==
 
The new scripting engine is reporting the calls of
non-existing functions. As described in chapter 2,
you can redirect those error reports to file using
[[server options|server option]] ''logscripterrorstofile=true'', or you
set the variable ''this.scriptlogmissingfunctions'' to
false in case a script wants to call functions of
unknown objects and doesn't want to flood the
RC chat.
Still it is not good to call non-existing functions,
most of the time that function call actually
was meant to have a purpose and is causing problems
if it's not executed. In some cases the object
might have disappeared or was accessed using a
bad name.
It might also be possible that the function
actually doesn't exist: on many servers scripts
are executed on server-side which are meant for
client-side, and vice-versa. There are lists of
available scripting functions, check those if
you are not sure if the function is existing
([[Creation/Dev/Script Functions: NPC Server|Script Functions: NPC Server]], [[Creation/Dev/Script/Client|Script Functions: Client]]).
 
You can add a line ''//#CLIENTSIDE'' in front of a
script if it's meant for clientside execution,
or remove that line if its meant for serverside
executing. If you call the non-existing function
on the bad side but rely on executing that function,
then you will need to send a trigger to the other
side or modify a variable, which can be read on
the other side and reacted probably.
 
Common functions that are client-side only:
* '''play'''(soundfile);
* '''hurt'''(hurtpower);
* '''addtiledef'''(image,levelstart,tilestype)
* '''addtiledef2'''(image,levelstart,x,y)
* '''showtext'''(index,x,y,font,style,text); <br> also ''showani'', ''showpoly'' etc. <br> those might be added soon to serverside though, currently only ''showimg'' and ''changeimgcolors'' etc. is available on serverside
 
Common functions that are server-side only:
* '''setlevel2'''(levelname,newx,newy);
* '''putnpc2'''(newx,newy,script);

Revision as of 03:49, 1 July 2007

Introducing the new scripting engine

This document is describing some problems and solutions when switching from the old Graal scripting engine (GS1) to the new engine (GS2). The new scripting engine has been designed to on the one hand be compatible to the old engine, and on the other hand provide new functionality to make it easier to write Graal scripts and do more interesting things with it. Those new things include a windowing system (GUI), a particle engine, multi-dimensional arrays, function parameter passing, true object orientation.

Since the old engine has been designed 7 years ago, a lot of functionality has been added to that engine while the basic design has not been changed, so a lot of modifications can be more seen as a "hack" and are not very easy to use. For example numeric variables and string variables must be accessed in a different way, even more complex operations need to be used to access numeric arrays and string lists. The new scripting engine tries to stay compatible with the old functions, but also add easier ways to access the variables. Numeric and string variables can now be accessed the same way, as well as numeric arrays and string lists.

To make the new functionality easy to use, some old "hacky" ways of accessing variables are not supported anymore. If scripts are written correctly without using those methods, then they will work fine in the new engine. If not, then they need to be fixed manually. In generally there are not a lot of scripts using those problematic ways of accessing variables, but sometime scripters just use copy & paste and so also copy the error to a lot of scripts. Then the only solution will be to edit those scripts manually, copying the fixed code part to the other affected scripts, or directly use classes and the join function.

Using the correct syntax

The new scripting engine finally reports syntax errors, when modifying scripts you see the error output on RC chat (RC is short for RemoteControl, an admin tool for Graal). If there are errors while the npcserver is starting up, then the errors are written in to logs/syntaxerrors.txt. The new engine also reports errors while running the scripts, including endless loops (loops are limited to 10000 cycles) and call of non-existing functions. On clientside those errors are output into the F2 window, on serverside they are displayed on RC chat, but can also be redirected to file using the server option logscripterrorstofile=true, the errors will then appear in logs/scripterrors.txt.

While some people might get headache when seeing a lot of script errors, that error reporting is actually giving you the possibility to track errors easily. While the new engine is not accepting as many syntax hacks as the old engine, it is actually easier now to fix them.

Closing brackets

An error that often happens is a missing opening bracket or missing closing bracket. The best way to not accidently do that error is to follow a constant and ordered scripting style, indenting scripting lines, using spaces between operators. Each time you open a { bracket you indent the following lines by 2 spaces. You can also use 4 spaces, that doesn't matter as long as you keep the same number of spaces in the whole script. Tabulators are not recommended since special characters are automatically removed by the engine. When you afterwards use a }, then you stop the indenting. That way you can check the correct number of opening and closing brackets by just watching if the last closing bracket appears at the very beginning of a line. The Graal script compiler doesn't require that indenting, but it is still recommended.

Semicolon

A thing that is quite simple to keep care of but is often done wrong is to add semicolons behind commands. That must be done to separate the commands from each other. In the old scripting engine it was possible to forget the semicolon if the next character was a closing bracket }. The bracket was automatically finishing the last command. In the new engine that it possible too as long as the last command is a function call, it's not working if the last command is an assignment:

Bad:  if (playerenters) {x=3}
Good: if (playerenters) {x=3;}

Scripters also often think that a closing bracket } never needs a semicolon behind it, although the semicolon is required if the brackets are used for defining an array or subscript:

Bad:  setshape2 2,2,{0,0,0,0}
Good: setshape2 2,2,{0,0,0,0};

That mainly affects the function calls setshape2, showpoly and putnpc2. Those always require a semicolon at the end, no matter if the function parameters are finishing with a closing bracket }.

Syntax incompatibilities

While most old scripts compile fine when having no syntax error, there is one exception when a correct old script is not working with the new scripting engine: the in-operator is different:

Works in GS1:  i = (playerx,playery in <20,40>);
Works in both: i = (playerx in <20,40> && playery in <20,40>);
Works in GS2:  i = ({playerx,playery} in <20,40>);

Variable lookup

As described in chapter one, the variable lookup has been changed in the new scripting engine. Lookup means the behaviour how variable names are translated into actual object attributes, or to be more close to the hardware, lookup is the translation into memory addresses. That means that a variable that was formerly connected to one value, is now connected to another value, and eventually having different behaviour when modifying it, and is so changing the logic of the script or even mess it up.

Example

Several scripts were using the variable this.x to store temporary data, or just as for-loop variable. While in the old engine this.x was just a numeric scripting variable, it is now redirecting to the x value of the current script object (this). So if you modify it, then the npc is magically starting to move, which was probably not the intention of the scripter. In that case the variable name must be modified to something like i or temp.i.

Variable types in the new scripting engine

The new scripting engine (GS2) has basicly 3 types of variables:

  • Object variables: objectname.variablename
    Object can be this for the current object, or player or an NPC name like DB_Items. The variable will then access the attributes of the object if there is a built-in attribute with that name (e.g. this.x), or a script variable belonging to that object (e.g. this.i)
  • Attributes of the active object: attributename
    If there is no leading, then the attributes of the current script object (for which the script is executed) are accessed, if there is an attribute with that name, e.g. x.
  • Global variables: variablename
    If the variable name has no leading and is not matching a built-in attribute of the current script object, then it is taken from the global variable pool. This is different to most other scripting languages where variables without leading are seen as local variables, but this behaviour is required to be compatible with the old scripting engine. Also it is a simple way to share data between scripts - you can set a flag in one script and read the flag in another script without needing to know where it is stored. Global variables are not saved, so they are not persistent and disappear after a server restart.

There are a few exceptions to this lookup scheme, e.g. function parameters can be accessed without a leading in front of the variable name. Also the with operator can temporary modify the current script object (this). In generally you don't need to care about those exceptions, to be sure that everything is working fine you should prefer to add a leading in front of variable names though.

Change of variable lookup

Attributes of the current object

As described in chapter 3.1., the built-in attributes of the current object can be accessed by this.x, this.y etc. now. In the old scripting engine that was not possible, those variable names were used for normal variables. That means if your scripts are using such variables, make sure that it is used for the correct thing. That includes numeric variables (this.x = 3;) as well as string variables (setstring this.x,3;);

Most common variables that need to be changed:

  • this.x, this.y, this.dir, this.hp, this.ap
  • this.hp on serverside
  • this.width, this.height, this.image

Global variables

Variables without leading are global now. While on clientside that was already the case in the old scripting engine, on serverside those variables were formerly only accessible in the current script. If you are using such variables, don't trust that other scripts are not modifying it. Eventually rename those variables, or use this.variables which are only working for the current object, or temp.variables which are only working in the current function body.

With-Operator

The with operator is temporary changing the current script object (this): all this. variables inside the opening and closing bracket are redirected to the with-object instead of the executing script object. Example:

this.myvar = 3;
with (findplayer("Max")) {
  this.myvar = 5;
}

After executing that code, myvar of the npc has the value 3, while myvar of the player "Max" has 5. The player "Max" is the with-object in this case. While both variables are accessed using the same variable name, they are directing to different variables. In the old scripting engine this was only modified when the with-object is another npc. In the new engine any script object can overwrite this.

Another thing that you need to keep care of is that you can also access the built-in variables of the with-object without using the this leading:

x = 20;
with (findnpc("Turret")) {
  x = 30;
}

In this case the x position of the current npc will be changed to 20, while the x position of the Turret will be changed to 30. The only exceptions for this behaviour are the variables x, y, dir and ap when using a player as with-object: an x without leading will never direct to the player.x variable, it will always take the npc for which the script is executed, or the npc that is positioned highest in the with-stack when using several with-operations inside each other.

Numeric variables, string variables and array using the same name

One major improvement in the new scripting engine is that you can easier access string variables and arrays. One drawback is that if you have used numeric variables, arrays or string variables with the same name, those are now directing to the same variable. So you will need to modify the variable names if they are supposed to hold different data:

Bad:
  this.myvar = 1;
  setstring this.myvar,2;
  this.myvar = {1,2,3};

Good:
  this.mynumericvar = 1;
  this.mystringvar = "2";
  this.myarrayvar = {1,2,3};

Easier access to string variables

You only need to read this chapter if you want to use the new way of accessing string variables, it is not required to make old scripts compatible.

String variables can be accessed easier now:
Writing string variables:

Old: setstring this.myvar,text;
New: this.myvar = "text";

Reading string variables:

Old: #s(this.mvyar)
New: this.myvar

You can see that string variables can now be accessed similar to numeric variables. Sometimes the variable name must have a different leading though to access the same variable:

Old: setstring varwithoutleading,text;
New: player.varwithoutleading = "text";

Also constructing dynamic variable names for string variables is different now, you need to use the new syntax. This documentation is not for explaining the complete syntax, but it might help to lead you to the correct path:

Old: setstring this.item#v(itemnumber),apple;
New: this.("item" @ itemnumber) = "apple";

You need to keep care on following things:

  • you concat strings using @
  • if you want to concat a string to another variable, don't forget to put "" around it to mark it as string
  • never put a dot inside the dynamic variable name:
Bad:  ("this.item" @ itemnumber)
Good: this.("item" @ itemnumber)
Good: ("Party" @ partynumber).name
  • never use array brackets in the dynamic variable name:
Bad:  this.("item[" @ index @ "]")
Good: this.item[index]
Good: this.("itemstats_" @ itemnumber)[index]

Server-side and client-side

The new scripting engine is reporting the calls of non-existing functions. As described in chapter 2, you can redirect those error reports to file using server option logscripterrorstofile=true, or you set the variable this.scriptlogmissingfunctions to false in case a script wants to call functions of unknown objects and doesn't want to flood the RC chat. Still it is not good to call non-existing functions, most of the time that function call actually was meant to have a purpose and is causing problems if it's not executed. In some cases the object might have disappeared or was accessed using a bad name. It might also be possible that the function actually doesn't exist: on many servers scripts are executed on server-side which are meant for client-side, and vice-versa. There are lists of available scripting functions, check those if you are not sure if the function is existing (Script Functions: NPC Server, Script Functions: Client).

You can add a line //#CLIENTSIDE in front of a script if it's meant for clientside execution, or remove that line if its meant for serverside executing. If you call the non-existing function on the bad side but rely on executing that function, then you will need to send a trigger to the other side or modify a variable, which can be read on the other side and reacted probably.

Common functions that are client-side only:

  • play(soundfile);
  • hurt(hurtpower);
  • addtiledef(image,levelstart,tilestype)
  • addtiledef2(image,levelstart,x,y)
  • showtext(index,x,y,font,style,text);
    also showani, showpoly etc.
    those might be added soon to serverside though, currently only showimg and changeimgcolors etc. is available on serverside

Common functions that are server-side only:

  • setlevel2(levelname,newx,newy);
  • putnpc2(newx,newy,script);