| Uncle
Dan's Quest Language Dictionary (A94) Overview The Well of Souls Quest Language is used to define what takes place in a WoS SCENE. A scene consists of a background graphic with movable sprite ACTORs drawn on top of it. Special effects and weather may be added to a scene. The player-controlled heroes are also animated within the scene. Players and NPC Actors interact via dialog and token-directed script execution. In multiplayer mode, when there is more than one player in a scene, the scene commands are executed by the player who is hosting the scene and all IF conditionals are based on that player. Objects which are GIVEn or TAKEn in the scene affect all players in the scene. The following are the currently supported commands within the language. Your world must contain a file called QUEST.TXT which holds both your Quest Scene scripts and all the tables which define your world. (To organize your thoughts, you may break this up into many files which you then #include in your QUEST.TXT file.) For examples, please refer to the wos/worlds/evergreen folder.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Anatomy
of a Scene Scenes must be placed within the +SCENES table of your world's quest.txt file. Each scene begins with a SCENE command and ends with an END command. Generally you define the background ambience of your scene first, then declare any NPC actors your scene requires, and then begin delivering scripted dialog based upon which tokens the player has. Without explaining in advance, here is a typical scene script (this would be "scene 45"):
Note that each scene script must have a unique <Script ID#> and this is the number by which you will use the Link Editor to bind particular scenes to particular links on your world's maps. Use the semicolon character to embed notes in your scene script, to remind you later how it was supposed to be working. Stick your TOKEN definitions anywhere you like in the +SCENES table. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ACTOR <ID #.layer>,
<name>, <skin>, <pose>, <x>,
<y> {, <colorTable>} {,<pain.wav>} This command creates an ACTOR in the scene. Actors can walk around and deliver scripted lines of text. Each actor in the scene needs a unique ID number (unique to that scene, not to ALL scenes :-) You may have up to 64 actors in a scene at the same time, numbered 0 - 63. But only actors 0-9 will be able to deliver dialog easily. (higher numbered actors are probably scene 'props' like a dropped coin to be discovered, or a campfire to be lit, etc). You give the character a name, the name of a skin file with its image in it, and the pose (offset within that file). These 'villager' skin files are stored in the world's MONSTER folder and are long filmstrips with many different villagers in a single file. The far left pose of a filmstrip file is pose #0 (and often is a credits frame. Use the /villagers command to rummage through the available monster/actor skins.) You also give the actor an initial position to be standing on the screen. X and Y vary from zero to 100 which relate to the max size of the window (so x=100 is always the far right edge of the screen, no matter what size the window has been stretched to.) Using values sufficiently outside the range will start the actor 'off screen' so that a subsequent 'MOVE' command can have them appear to walk in from off stage. If you leave out the <x>, <y> (or set them both to 0), then a 'standard' location will be used (different for each actor ID#). The colorTable argument is used to re-color the actor skin. The <pain.wav> argument specifies a sound effect you would like player when the actor is 'attacked' You usually define an ACTOR or two right at the start of the screen, but you can use the command at any time, in case you have an actor which is only present if certain conditions have been met. For example:
Here the scene starts by creating "Old Carl" as actor #1 standing at the lower left of the screen. Then if the player does NOT have token 12 ("-T12") it jumps to the label and skips the creation of "Young Carl" who otherwise would be standing in the lower center of the screen. You may re-use an actor slot at any time, simply by giving the ACTOR command again later in the scene, using the same actor ID number. The previous actor with that ID# will simply disappear and be replaced with the new one. This is useful if you want an actor to be revealed as a different character, and need to switch to a different skin file. In that case, you would use the same X,Y for the new actor. Otherwise, you probably would wait until the actor had walked off screen before re-using its actor ID number. Actors don't have to walk and talk to be useful. You can use actors to place a crackling fire in the background, some grazing sheep, a painting on the wall, etc. Layers The first argument (the ID) now supports a dotted sub-argument (optional and assumed to be 0) which indicates the actor's display layer. The higher the layer value (-1000 to +1000), the more 'in front' the actor is. For example, all actors on layer 4 are 'in front of' actors on layer 2, no matter what the 'y' coordinate of their position is. Within a layer, actors are still sorted by their Y value, so actors lower on the screen are in front of those higher on the screen. This feature allows you to place foreground items like boulders and trees that actors can 'hide behind' (though you will probably still see nametags and chat bubbles). You might also use it to place a cave entrance 'in the background' Player characters are always on layer 0. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ASK <seconds> {1} This command makes the script engine wait a while for the player to type something ("yes" or "no" flags set in response, depending on what the player typed. Only the player who is hosting the scene is evaluated.) This command is used when you want to ask the player a question and actually read his or her answer and do something based on the response. The actual question is asked using the normal speech bubble stuff. You just follow that command with an ASK command as in this example:
Here the king poses a question. The "ASK 20" pauses the script for up to 20 seconds (or until the host player types a line of chat). If a line of chat is entered before the timeout, and it starts with something resembling a yes, then the "YES" condition will be true and the "IF" command will jump to the label where the king is unhappy with us. Otherwise (nothing was typed, or what was typed did not look like a yes) the king is happy enough and the scene ends. The "Qword" conditional lets you scan the host player's response for particular words or letter sequences ("yes" would be found inside of "yesterday" for example), so you could have complicated processing like:
If you add a second argument whose value is 1, as in:
Then Host's answer to that question will NOT be shared with other members of the scene (or players outside the scene). |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BKGND <JPEG filename> This command causes the scene's background jpeg to switch. Note that the background specified in the SCENE command will probably be shown first, so if you need to avoid a flash of the default background before you determine (via tokens, perhaps) which background is appropriate, be sure to set the default background to something like all black, or whatever works for your world.
You don't actually need the ".jpg" extension here, but it might help you to leave it in. Only .jpg files are supported for scene backgrounds. The file in question should be located in your World's SCENES folder. If it is missing, then the root WoS SCENES folder is searched instead. If it isn't there either, you get whatever you deserve :-) |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CALL scene#@Label All good languages need some sort of function, or subroutine support. That allows you to re-use code snippets rather than having to put extra copies into every scene. The CALL command invokes such a function. The function itself is just a @label in some scene, but should end with a RETURN command instead of an END command. So, a scene like this:
Would end up having actor 1 say:
As if all the lines of the function itself had been stuck inside the original script, in place of the CALL command. In this example, the function was defined inside the same script which CALLed it. That might occasionally be useful, but probably you will want to define your functions in a separate script (or separate scripts) and for performance reasons you might want to do that in the first scene which gets loaded by your quest.txt file. With the addition of the CALL command comes a change in the way @labels are defined. You may now (and this is for ANY command which uses a @label) include a scene number to the left of the at-sign, so:
Will look for the label "hiThere" inside of scene 47, no matter which scene contains the CALL instruction. Function Arguments: Most languages allow you to pass arguments when you call a function (and receive results back from the function). In Quest this means using cookies. So you can set a cookie before making the CALL, and then the function can just look in that cookie for the argument you passed in. As a convenience to you, you can include up to 10 arguments on the CALL line itself, and they will be automatically stuffed into cookies with the names "arg0" through "arg9" (in order). These are just regular cookies, and every use of the CALL command (or RETURN command) will blow away their contents. So just use them inside the function and don't expect them to live forever.
So here we would ultimately see actor one say "I enjoy eating apple, butter, and cheese" |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| COLOR <color command> This command lets you change the color table currently in effect in the scene. Initially a scene starts out with no color table, unless one was specified in the SCENE command. In the simplest case:
Just declares 15 to be the color table, and all existing actors, monsters, and heroes in the scene are repainted as their original skin plus this color table applied. But if you add 1000 to the color table index, it means "Apply a second coat" as it were, so:
would apply color table 15 not to the original skins, but to the currently colored skins. So if you had previously dimmed the skins (for example), this would dim them even further. (please note that the colorings are not reversible. Dimming a skin three times and then brightening it 3 times will NOT return the skin to its original appearance.) This command can also recolor the BKGND jpeg for the scene. To do that you add 2000, as in:
This would apply color table 15 to the current background (effects are always cumulative for backgrounds). It will leave the characters alone, so if you want to dim BOTH the background AND the characters, you need two commands, as in this simple 'fade' example:
This would apply the colortable 13 (mild dim) to both the background and the characters, 10 times in a row. Note the necessary WAIT command (100 milliseconds should do it) to give the viewer a chance to see the fade. To restore the background to its original state, use:
To restore the characters to their original state, use:
One nice thing about the scene's colortable is that it is applied on top of any actor or monster coloring which might be used. Hence if you have created a 'red slobber' by defining a colortable in the MONSTER table, you can still use a scene colorTable to dim it, and it will be a dimmed red slobber (and not a dimmed gray slobber). Limitations: If the player resizes their window, the current scene background jpeg will lose any coloring you might have done to it (while the characters will remember their color changes). If someone new enters the screen, they will only see the most recent colorTable setting applied exactly once to their characters (and they won't see any previous background coloring at all.) You have to actually be in the scene at the time the COLOR command is issued, to see the coloring effect. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| COLOR TABLES Color tables are used in the ACTOR command, the COLOR command, the SCENE command, and in the MONSTER TABLES. When you assign a skin to an actor or a monster, that skin contains artwork rendered in the 256 colors of the standard WoS palette. Say you had a monster skin which was largely greenish. By assigning a color table, you could use that same skin, but the monster which appeared on the screen might be largely bluish instead. The skin itself hasn't changed, it is just dynamically re-colored on its way to being displayed on the screen. Most color tables preserve the artistic quality of the skin, it's outline, shadow, and transparency. Some are just plain freaky. The actual effect a color table has on a skin will be influenced by the colors used in the original skin, so a world developer should artfully pick the color table which meets his or her needs. To color an actor, you add an extra argument to the actor command, as in:
In this example, the actor skin "joshRoyalty, frame 3" is recolored using color table 4. Let's pretend this makes the normally rosy cheeks of the king look a bit ill in coloration. Colors are each made of a combination of 3 pigments: Red (R), Green (G), and Blue (B). A color table translates one color to another by modifying one or more of those pigments. The available color tables are:
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
COMPARE COMMANDS
The COMPARE command subtracts B from A and saves the result in a special place which doesn't get munged until the next time you use the COMPARE command (or one of the math commands: ADD, SUB, MUL, DIV and MOD) that place is called the CONDITION CODE. The three IFx commands test the CONDITION CODE and jump to the label if the result was as indicated. So your IFx command doesn't HAVE to immediately follow the COMPARE command, though I suspect it generally will. Arguments A and B are interpreted as signed decimal numbers. For now you are stuck with constants and cookies. So, you can do:
For example:
Of course, you will seldom test all three cases, so this example is silly. F_COMPARE Note that COMPARE will treat A and B as if they were integers (by which I mean whole numbers). If your math is uing the F_xxx math instructions to do its work, you should use the F_COMPARE command instead of COMPARE, in order to properly compare small values. For example COMPARE of 1.002 and 1.004 will declare they are EQUAL (because they both start with '1'). But F_COMPARE will correctly notice that 1.004 is larger. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| COUNTDOWN <seconds> This command starts a COUNTDOWN timer (displayed on the main screen) which counts down to zero. When it hits zero, it disappears. Cool huh? To make it useful, you need a couple scenes... One which starts the countdown:
... and one which which tests it with the 'XP' conditional, as in:
You can turn the counter off prematurely by setting it to zero ("COUNTDOWN 0"). Also, the countdown automatically terminates if you leave the game, or change characters. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Dialog> ACTORs in a scene may deliver dialog which is read by the player both in the chat window and also as a little cartoon balloon above the actor's head in the scene. There are several ways of making your actors talk, but I think I will only document the preferred method, which is to have a line consisting of:
For Example:
Be sure to declare your actors BEFORE you have them say any dialog. Only actors 0-9 can be made to speak in this way, since the number before the colon can only be a single digit. On the off chance that you need to get some dialog from actors 10 through 15, you have to use the 'current actor' metaphor and provide a current actor selection, followed by unlabeled chat. As in:
But that's clumsy and sucky, so use the preferred way and let actors 10-15 be mute. Each line of text you put in creates a speech bubble over the head of the actor who said it. Only one actor can have a speech bubble up at a time, so the script will automatically pause before executing the next speech line until the previous bubble disappears. Bubbles disappear after a brief timeout, or can be cleared by right-clicking in them. Obviously you don't want to cram TOO much into each line, so expect lots of short lines of dialog in a row. The time a bubble will remain, before it auto-pops, depends on how many characters are inside it. Cute Trick - HOST Chat By using the code "H:" at the start of the line, you can put words in the mouth of the scene host. So, say your character is returning to a scene after having achieved his goal. The script detects the token meaning he has killed the dragon, so your actor wants to reward him, but has to say something clumsly like:
How much cooler it is to say instead:
So, in this case the sentence "Why Yes, I ..." appears above the PLAYER'S head, instead of above an actor. It behaves just like a regular actor speech bubble. It's cool. The percent sign symbol (%) is used as a special character. The number following it lets you stick in real-time information about the current players.
For example:
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EJECT <conditions required to
remain in party and scene> This command is identical to the PARTY command and lets you define what an acceptable party member should look like, and causes players who do not match that condition to be kicked from the party. A world designer would use this command just before executing a GOTO LINK command where only qualified people were allowed to go. Unlike the PARTY command, this one will also eject the non-members from the scene. As in:
This would kick anyone from the party AND THE SCENE who was not class 5 or did not possess token 23. The conditions are the same as for the IF command, but are evaluated AT THE CLIENT. (cool, huh?) I mean each individual player is checked for their OWN copy of token 23, rather than just riding along on the scene host's token 23 (as the IF command does). To stay in the party,
the condition must evaluate to TRUE for you. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| END This command terminates the execution of a scene script. It does not, however, take you out of the scene and back to the map. (Use GOTO EXIT for that.) You are simply left standing in the scene as it was when the END happens. Any actors in the scene will still be standing where they last were. Please note that you can't use items on yourself (or give things to other players) until the script stops executing. So you have to wait for the scripted portion to END before your sword, spell, or item cursors will begin to 'smoke' again.
For your convenience, the button commands: OFFER, OFFER2, and GAME create buttons which continue to work even after the scene script has ENDed. (Only one such button can be active at a time, however, and it will be the last one executed in the scene script.) |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EVENTS (Asynchronous Events) This is not a command exactly, but a technique for adding value to your scene. Normally when a scene ENDs, that is the end of it, and no more lines of script code will ever be executed. However, as of version A63, there is at least one way to wake a script back up, after it has ENDed. (note: it MUST have ENDed before these EVENTs can do their job) Each Event is defined by a label. The label of the line of script which execution will GOTO when the event takes place. @eventActorClickN This event is triggered when the scene host RIGHT-clicks on an actor in the scene. Each actor has a unique ID number and the actual label which is sought will have that ID number at the end. For example, right-clicking on actor 4 will cause the script to resume at label @eventActorClick4. What you do in response to this event is up to you, but one fun thing to do is use the MENU command to bring up a set of choices appropriate for manipulating the actor in question. Remember than an ACTOR can be anything. A treasure chest, a door, a chair, a fireplace, etc. And MENU options you might provide are OPEN, PICK LOCK, LIGHT FIRE, etc. For example:
|