How To Use Change Scripts

The Pixie
A change script is a script linked to an attribute. The script runs whenever the attribute changes. It is most useful when you have an attribute that can change in several different situations, but in all of them, you want the same thing to happen. A good example is in an RPG-style game, where you want to check the player's hit points to see if he is dead. The hit points might change when the player is attacked, drinks a poison or sets off a trap. Each of those events can modify the hits, but you have one just one change script that checks if the player is alive.

Quest has some change scripts already built in. If you change the parent attribute of the player, a change script fires that calls the OnEnterRoom function. This ensures the function gets called every time, rather than replying on game creators calling it each time the player moves.

Change scripts can be created for attributes on any object, not just the player, by the way.

As an example, let us create an attribute called "hitpoints" on the player object. You can do that on the Attributes tab by clicking Add just above the bottom box. Set it to be an integer. Once it is in the list, click on it and then click the "Add Change Script button. Quest will add a new attribute, "changedhitpoints". Easy as that.

Now make the script display the new hit points:
msg ("Hits points now " + player.hitpoints)


Here is an example of a change script in action in action:
<!--Saved by Quest 5.6.5621.18142-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="test_change">
<gameid>cd4d850f-af71-4e87-ba68-f97fb87284ee</gameid>
<version>1.0</version>
<firstpublished>2015</firstpublished>
</game>
<object name="room">
<inherit name="editor_room" />
<description>Type "drink poison" to see the change script in action!</description>
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
<hitpoints type="int">55</hitpoints>
<changedhitpoints type="script"><![CDATA[
if (player.hitpoints > 0) {
msg ("Hits points now " + player.hitpoints)
}
else {
msg ("You died!!!")
finish
}
]]></changedhitpoints>
</object>
</object>
<command name="poison">
<pattern>drink poison</pattern>
<script>
player.hitpoints = player.hitpoints - 10
</script>
</command>
</asl>


Quest recognises an attribute as a change script if it is a script and its name starts with "changed". There are just standard scripts, and you can use them as such:
do (player, "changedhitpoints")



Lists

Changing the contents of a list does not trigger a change script. Quest will consider it to be the same list. Say we have an attribute called "listofstuff".
// This will not trigger a change script
list add (player.listofstuff, "item")
// This will
player.listofstuff = NewStringList()
player.listofstuff = Split("first item,item", ",")



Ordering

The change script will fire when the attribute changes, so be careful where you make the change in your code. In the hit points example, this is wrong:
player.hitpoints = player.hitpoints - 20
msg("You drink the liquid... and realised it was poison!")

If it kills the player, she will see this:

You have died!!!
You drink the liquid... and realised it was poison!


You need to adjust the hit points after the message.


Change inside change


Be careful changing an attribute inside its own change script, you can easily end up in an infinite loop!


The "parent" Attribute

An attribute you may well want to react to if it changes is the "parent" attribute, as this determines where an object is, what room it is currently in. You will find, however, that it already exist. You will need to click on "Make Editable Copy" to be able to do anything with it.

If the object in question is not the "player" object and will never be the player, you can just delete the existing code, and put n your own. If this is the "player" object or can be the player, you will need to add your code to the end of the existing code.


The oldvalue variable

There is a special variable that holds the previous value of the attribute your change script is following, and this is called "oldvalue". A good example of that in use is the change script on the "parent" attribute that was just mentioned:
if (game.pov = this) {
if (IsDefined("oldvalue")) {
OnEnterRoom (oldvalue)
}
else {
OnEnterRoom (null)
}
if (game.gridmap) {
MergePOVCoordinates
}
}

The first line means that this code only applies if this object is the current player point-of-view (usually that is the "player" object). If this is the player, then the player has moved. It checks to see if oldvalue exists (which it should do, but is good to check). If it exists, it is passed to OnEnterRoom, which can then run the leaving script for the old room if necessary.

HegemonKhan
Are there any conflicts when using 'changed' Scripts' and global Turnscripts' operations, such as in how~when they're activated~work ???

for example if you have a bunch of complex stuff in a global Turnscript, and you also got 'changed' Scripts, do those 'change' Scripts activate instantly upon the changing of the Attribute (no matter the source of the cause of the change of the Attribute) or do they only activate just as the Turnscripts do via the 'internal turns', which, especially if the former, could interfere~disrupt with your Turnscript's operations, or vice versa, your Turnscripts interfere with your 'changed' Scripts' operations.

--------

hmm... this might not be the best example, meh..., oh well...

let's say the game ends when your main character dies (and you use a 'changed' Script for that). But, you also got party~team members too (though you don't care about them being alive or dead, only the main character dying ends the game. You don't want the game to end when your entire party~team is dead, as is common in most rpgs), and you want them to be able to revive the main character (or the other party~team members too) before the end of the Turnscript (and then if the main character isn't revived, its game over).

will you have a conflict: the 'changed' Script ends the game, before the Turnscripts gives you the chance (if you can do so) to revive the main character ??

or other common examples would be complex mathematical expressions~operations, would the 'changed' Script intefere with those (depending on when~how it activates) ???

----

P.S.

thanks again for another library~guide! :D
pixie the library~guide SPAMMER! (the good kind of spamming, hehe)

The Pixie
A change script fires when the attribute is changed. If that is in another script, then that script will stop while the change script runs. Once the change script has finished, the original script will resume from that point (just like calling a function).

A turn script fires at the end of a turn. If it changes an attribute with a change script, the same thing will happen. The turn script will stop, and the change script will run through. Once over, the turn scrip will resume.

I am not sure I follow your RPG example. Does the game only terminate when everyone is dead? Probably the best way to do that would be to have change scripts on the hit points for each character, and set them all to call the same function, and then that function tests whether everyone is dead, and only end the game then.

HegemonKhan
no, my scenario was just for when the main character dies, the game ends (I was trying to emphasive that it wasn't the more common design of the, 'game over' occuring when the entire party~team dies ~ my badly worded post ended up having the opposite effect, you thought I meant having the scenerio of the entire party~team death resulting in the game over, sighs, Anyways, I just wanted to use the scenario~example to set up my question about the possible conflict, which was my point in my post, as I wasn't sure of how they worked. The 'changed' Script basically takes priority, everything~anything else stops~pauses, until the 'changed' Scripts are done executing. thank you for the answer.

People~I do still need to be careful though in setting up our systems, as you explain in your answer, or we~I can indeed have issues~conflicts in terms of the proper operations and~or order of operations.

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums