How to make descriptions that change

The Pixie
Note: In Quest, everything is an object, even rooms. To try to avoid confusion, I will use "item" to refer to things the player can manipulate, "room" to refer to rooms (obviously) and "object" to refer to everything, including the game and the player!

Often you want the description of an object to change, depending on what the player has done. Perhaps she has blown a hole in the wall, and the room description needs to reflect that. Perhaps she has turning on the bizarre machine, and the item description needs to mention that.


Step 1

First you need a Boolean attribute, also called a flag, which will be used to remember the state of the room or item. Attributes are attached to objects, and it does not matter what object you pick. It could be the game object, it could be the player object, it could be some other object. Generally, it is easiest to set an attribute on the object in question (the room or item). Whatever you choose, the procedure is more or less the same.

Go to the Attributes tab of the object, and look at the lower section, also called Attributes. Click on Add, and type a suitable name. If this is a room or item, "flag" is probably good enough, if this is the game or player object, choose something more descriptive so you know what it is for in three months time.

Right at the bottom, click on the button that says "String", and set it to "Boolean" instead.

A Boolean, by the way, is an attribute that is either True or False.


Step 2

For now, I am assuming we have a Boolean flag called "flag", on the object itself.

Go to the description for the item (on the Setup tab) or room (Room tab). If you have already typed something there, copy-and-paste it somewhere first. Click on "Text", and select instead "Run script".

Click the "Add new script" button, and select "If...", and then click the "Add" button. A box with lots of stuff will appear within the object description area, with "If: expression" at the top. In the text box to the right of that type "this.flag" (no quotes).

Click "Add new script", select "Print a message", and in the new text box type in the description the player should see after the flag has been set.

Click "Add Else", then click the new "Add new script" button, and select "Print a message" again. In the new text box type in the description the player shoud see before the flag has been set.

It should look like this:

desc1.png


So what does it mean?

The expression is what Quest will use to decide what to do. Quest has a special word, "this", that refers to the current object (the object that the script belongs to), in this case your room or object. It does not matter what you called the object, "this" will refer to it. The dot indicates that what follows will be an attribute, and "flag" is just the name of the attribute we set up in step 1.

So if the flag is set to True, the top section of the box is done, and if it is set to False, the bottom section (the "Else" section) is done. And all each section does is print a message.

While we are here, look just under "Run script", and click on the seventh icon, "Code view". You will see this:

if (this.flag) {
msg ("A big room, with wood-panelled walls. There is a large hole in the west wall, where the wood is blackeden.")
}
else {
msg ("A big room, with wood-panelled walls.")
}


It is exactly same set of instructions, just displayed differently. If the flag is True do the first bit, if it is False, do the other bit. It is useful to get familiar withy this code view, as it is much easier to use on the forums.


Step 3

The final set is to have something trigger the change. You are kind of on your own here as there are so many ways this might happen, but I will go through an example.

Let us suppose breaking a teapot causes something to explode in a room called "room". On the Verb tab of the teapot, "Add" a new verb, and change "Print a message" to "Run a script". From the "Add new script" menu, select "Set object flag", set the object to be the room (because that is trhe object with the flag attribute), and the flag name to "flag". You will probably want to print a message too.

desc2.png


For reference, the code view looks like this:

SetObjectFlagOn (room, "flag")
msg ("As the teapot breaks, the chamberpot suddenly explodes in a suicidal act of sympathy.")


And if I was typing it in,I would write this:

room.flag = true
msg ("As the teapot breaks, the chamberpot suddenly explodes in a suicidal act of sympathy.")


It is all the same, the first line is setting the flag to have a have of true.

The Pixie
I want one flag to affect several descriptions

This is easy, you just select one object as the master object, and have all the other objects check the flag on that.

For example, a table in the room might have a description like this (note that "this" in the first line has been replaced by "room"):

if (room.flag) {
msg ("A mahogany table, now showing some scorching and soot.")
}
else {
msg ("A mahogany table in excellent condition.")
}





I want several different states

Let us say you want your external locations to change depending on the time of day and weather. In this case you are prbably better setting an attribute on the game object. You do this just the same as before, but give it a meaningful name, let us say "external_state", and set it to be an integer, rather than a Boolean. It will default to zero, which is fine.

This attribute will track the state of the game, so a value of 0 might indicate that it is sunny, 1 could be dusk and 3 could be nighttime (4 could be thunderstorm, etc.).

Now go to your room description, and change "Text" to "Run script". This time, select "Switch..." from the "add new script" menu. In the switch text box, type "game.external_state" (no quotes).

For each possibility, you need to click on the Add button, type in a number for the key, then click Add new script, select "Print a message", and type in the room description for that state.

desc3.png


Here is the code view:

switch (game.external_state) {
case (0) {
msg ("The path looks pretty in the sunshine.")
}
case (1) {
msg ("The path stetched west towards the setting sun.")
}
case (3) {
msg ("There was something spooky about the path now it was night time,")
}
}


Now you need some triggers. Perhaps as the player gets to a certain location, the game state is updated, and time moves on. The possibilities are endless, but here, briefly, is one way:

desc4.png


Code view:

game.external_state = 1

jaynabonne
You can also use {if:} conditionals in the text processor if you don't want to write the conditional code in script.

Marzipan
I gushed about this already in the other thread but just wanted to say thanks again. Though I think I'm learning more than ever now that I just can't wrap my head around some of this stuff, I was basically approaching it completely backwards...the little I did pick up about variables and things on another site I think I'd better unlearn ASAP.

Also I'm curious now if there's a game on the site that's made good use of your 'several different states' example, having rooms change based on weather or other factors would be one way to really draw a player in.

HegemonKhan
90% of everything that you want to do in your games, is done with 'checks' (the 'if' Script) and 'indicators' (the 'set a variable or attribute' Script; aka setting~altering Attributes).

(I know this is code, well pseudo-code, but just see if the logic makes sense to you)

Setting and~or Altering an Attribute: Object_name.Attribute_name = Value_or_Expression

Examples

examples of simple '=Value' Attributes:

String Attribute: player.haircolor = "black"
String Attribute: player.life = "999"
Integer Attribute: player.life = 999
Double (Float;Floating Point) Attribute: player.damage = 58.194
Boolean (a true~false Flag) Attribute: orc.dead = false
Boolean Attribute: player.flying = false
Object Attribute: player.head = helmet

example of a simple '=Expression', using a Stringlist Attribute:

Stringlist Attribute: player.favorite_colors = split ("black;red", ";")

example of a complex '=Expression' Integer Atrtibute:

player.damage = player.weapon.damage + player.weapon.damage * player.strength / 100 - orc.armor.defense - orc.armor.defense * orc.endurance / 100

or, in the GUI~Editor, JUST TO SET 'INITIALLY (at~for game start)' ONLY:

'whatever' (Object) -> Attributes (Tab) -> Attributes -> Add -> (see below

(Object Name: player)

Attribute Name: strength
Attribute Type: int (integer)
Attribute Value: 100

Attribute Name: condition (or statuseffect)
Attribute Type: string
Attribute Value: normal (or 'poisoned' or 'silenced' or 'confused' or 'petrified' or 'dead' or 'paralyzed' or 'asleep' or etc etc etc)

Attribute Name: head
Attribute Type: object
Attribute Value: helmet (an Object in your game)

Attribute Name: flying
Attribute Type: boolean (a True~false Flag)
Attribute Value: false

-------

Object_name.Attribute_name = Value_or_Expression

if (Object_name.Attribute_name = Value_or_Expression) {
-> msg ("1")
} else if (Object_name.Attribute_name = Value_or_Expression) {
-> msg ("2")
} else {
-> msg ("3")
}

examples:

player.strength = GetRandomInt (0,2)

if (player.strength = 0) {
-> msg ("You are weak in strength.")
} else if (player.strength = 1) {
-> msg ("You are average in strength.")
} else {
-> msg ("You're strong in strength.")
}

---

orc.dead = false

if (orc.dead = true) {
-> msg ("The orc is already dead, silly.")
} else if (orc.dead = false) {
-> msg ("You attack and kill the orc.")
-> orc.dead = true
}

----

player.cash = 0
player.life = 999
player.damage = 100

orc.dead = false
orc.cash = 100
orc.life = 500
orc.damage = 50

if (orc.dead = true) {
-> if (orc.cash > 0) {
->-> msg ("The orc is dead, you loot its corpse of cash.")
->-> player.cash = player.cash + orc.cash
->-> orc.cash = 0
-> } else {
->-> msg ("The orc is dead, and you've already looted its corpse, silly.")
-> }
} else if (orc.dead = false) {
-> msg ("You attack the orc.")
-> orc.life = orc.life - player.damage
-> if (orc.life <= 0) {
->-> msg ("You killed the orc.")
->-> orc.dead = true
-> } else {
->-> msg ("The orc attacks you.")
->-> player.life = player.life - orc.damage
->-> if (player.life <= 0) {
->->-> msg ("The orc has killed you.")
->->-> msg ("GAME OVER")
->->-> finish
->-> }
-> }
}

-----

room.description_flag = 0
room2.description_flag = 0

room.description_flag = GetRandomInt (0,2)
room2.description_flag = GetRandomInt (0,4)

'room' Description (run as script):
if (room.description_flag = 0) {
-> msg ("sunny")
} else if (room.description_flag = 1) {
-> msg ("cloudy")
} else {
-> msg ("dark: night time")
}

'room2' Description (run as script):
if (room2.description_flag = 0)
-> msg ("forest")
} else if (room.description_flag = 1) {
-> msg ("dungeon")
} else if (room2.description_flag = 2) {
-> msg ("cave")
} else if (room2.description_flag = 3) {
-> msg ("town")
} else {
-> msg ("inside a shop")

HegemonKhan
also, there's a bit of confusion of terms in~with quest:

VARIABLES:
-> Variables (local, not 'attached' to Objects, so they're not 'saved'~stored, and thus can't be 'loaded'~used within another different script block)
->-> Examples:
->-> value = (whatever)
->-> result = (whatever)
->-> y = (whatever)
->-> handled = false // (or: true)
->-> you_go_first = true // (or: false)
-> Attributes (global, are 'attached' to Objects, so as long as the Object exists, they're 'saved'~stored, and thus can be 'loaded'~used within another different script block)
->-> Examples:
->-> player.strength = 100
->-> orc.strength = 10
->-> game.event_flag = 0
->-> game.turns = 0
->-> table.material = "wood"
->-> game.player_flying = false
->-> game.player_strength = 100
->-> game.orc_strength = 10

the 'NAME' String Attribute is the 'ID' Attribute for quest, so the 'NAMES' must be unique

-----------

ELEMENTS (the 'things' in quest):

they all have the 'tag blocks' in code, an example (horizontally shown): <xxx xxx="xxx">xxx</xxx>

Objects (holds other Objects and~or Attributes) (the special Game Object, Player Objects, Room Objects, Other-Object Objects, and for Gamebook quest: Pages)
Verbs (local Commands: for that specific Object only. Uses the hyperlinks or Object's buttons)
Commands (Global Commands: uses input by the person playing the game)
Functions (holds scripts)
Attributes (but they must be within another different ELEMENT)
Object Types (a group: holds Attributes) (confusingly shortened to 'TYPES', as don't confuse this with the use of 'type' in the tags, for example: <attr name="strength" type="int">100</attr> )
Turnscripts (a Function, but also able to hold Attributes, and internally coded to use a 'turns' feature)
Timers (a Function, but also able to hold Attributes, and internally coded to use 'tick~clock' time)
Exits (connectors for the Room Objects)

Attributes (data ~ Game Mechanics):

String
Integer (int)
Double (Float; Floating Point)
Boolean (a true~false Flag)
Object
Script
List (Stringlist or Objectlist)
Dictionaries (arrays) (Stringdictionary, Objectdictionary, or Scriptdictionary)

Scripting (actions~events):

Verbs (Objects' Script Type Attributes)
Commands
Functions
Timers
Turnscripts
Object Types (Script Type Attributes)

-----------

and a lot more stuff too... but I'm tired now, lol.

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

Support

Forums