With regards to this here "variable" talk... as always, it just doesn't have to be that complicated, at least not in the beginning.
The basic idea behind attributes (and local variables in scripts) is that they are place where you can store things and then get them back later. What can you store? Lots of different types of things. (Check out the "attributes" tab on an object, create an attribute and see all the various types it can be. And there are even some missing there.) The most common types of attributes you'll see are strings, numbers (integers and "real" numbers) and booleans (on/off, true/false, yes/no, does/doesn't).
What is the difference between an attribute and a variable? In Quest parlance, an attribute is data stored on an object. Only objects in Quest persist (e.g. if you save and reload a game), and only their attributes stick around. You can define variables in your scripts that come into existence when you use them, but they will disappear as soon as the script exits... If you want something to hang around during the game, it has to be an attribute on some object.
What can you use attributes for? Well, it turns out you have been using them already! The Quest GUI is an easy front end for assigning attributes to your objects. Things like room descriptions, object aliases, whether to show hyperlinks or not, etc are all just stored as attributes.
And that points out an important thing: attributes don't have to be *variables*. You can easily put data values in attributes that never changes during your game. Why would you want to do that (beyond the obvious ones of room names and things)? Well, consider your earlier code snippets of checking for a password. You might have something like:
if (result = "1234") {
// They entered the password correctly.
}
Now let's say you wanted to change that password. You would have to go and find the script where it's used and modify it in the script. That's doable, but not the most fun thing in the world.
The alternative is to store the password in an attribute. Let's say you create a string attribute on the game object called "secretpassword", and you give it the value "1234". Then your script would be:
if (result = game.secretpassword) {
// They entered the password correctly.
}
Is that clearer or easier? It might look a bit more confusing up front (or maybe not), but then later when you need to change the password, you can just look at the attributes on your game and easily change it without having to look at script. It's especially handy if you have the same thing used in multiple places. For example, if you needed to use the same password in multiple rooms, if you create an attribute somewhere and use it everywhere, then you can change all the passwords at once by changing that one attribute instead of going to all the room scripts and making sure you change them all.
If you get a chance, the next time you run your game in the Quest desktop GUI, while it's running click on the button near the top that says "Debugger". It might sound scary, but it really isn't. What the debugger does it let you peek at all your objects and their attributes. By perusing this a bit, you might get a better feel for how Quest is put together - and how your objects change over time. (An interesting attribute to look at is "parent", which says what room something is in (or what container)).
Marzripan's example above even gave me pause, and I know variables and all that. The reason why is that the complexity lies not with the use of variables as such but in the algorithm. There are much simpler algorithms that you will use in your code in the beginning (e.g, setting and testing variables and flags). As you advance, you'll probably graduate to more advanced usages. By the time you need what Marzipan is describing, you'll already understand why, because you had the need and worked out what you want to do.
And when it comes to them thar scripts, them varmints don't need to be so complicated neither. There is a tenet in coding that has been around for decades (whether arising as Donald Knuth's "Literate Programming" or the more recent "code should read like well written prose") which is that you should try to make your code as simple and clear as possible. *Readability* is a key part of that. You probably don't need to worry about that now (just getting scripts to work is an achievement; I can remember when I was first writing C code), but it's good to keep in mind.
As an example, let's dissect this bit of code from above:
if (not john_smith.hair_color = "brown") {
msg (john_smith.first name + " has changed his hair color.")
} else if (john_smith.hair_color = "brown") {
msg (john_smith.first_name + "'s natural hair color is brown.")
}
It's a fairly simple "if" written in a fairly convoluted way. To see that, consider reading it as English: "If it's not the case that John Smith's hair is brown, then say "John has change his hair color." Otherwise, if John Smith's hair is brown, say "John's hair color is brown."
(One easy change is to move the split "not" and "=" together into "<>" for (not equal), but that tends to be a pain at the script level as the "<" and "> characters force you to wrap CDATA around the script. Don't worry about that. I'm just babbling a bit. But if you did that, then the code would at least read "If John Smith's hair is not brown", which is somewhat better.)
The awkward bits are twofold and hint why you'd never say it in English like that. First, it needlessly duplicates the condition. Second, it has a negative in the if part of an if/else. The former should be fairly clear. (If not, consider would you ever say, "If John, Mary and Tony are going to the party, then I will as well. Else if John, Mary and Tony are not going to the party, I'll stay home." Not only is it harder for a listener to parse, but people will look at you funny. lol)
The latter might is more subtle and might not be as clear. Consider whether it seems awkward to say "If the TV is not on, I'll read a book; otherwise, I'll watch it." Contrasted with: "If the TV is on, I'll watch it; otherwise, I'll read a book." It might be me, but the second sentence seems clearer.
Putting those two together, and approaching it from "write in code what I mean", it helps to actually state, first, in English, and clearly, what we mean. I would say, 'If John's hair is brown, say "John's natural hair color is brown". Otherwise, say "John has changed his hair." ' That translates into code as:
if (john_smith.hair_color = "brown") {
msg (john_smith.first_name + "'s natural hair color is brown.")
} else {
msg (john_smith.first name + " has changed his hair color.")
}
Less typing. Easier to input with the GUI. Easier to understand. More natural to read. And easier for someone reading it to take in.
Keeping it simple will make your life so much easier. And if that "someone reading it" is you six months from now trying to work out what you did, you'll be thanking yourself instead of cursing yourself!
And you'll have a lot more fun.
More advice: I love writing code, but the best code is the code you don't have to write. Things like use the text processor over writing hard-coded formatting script. And don't use attributes just for their own sake. Decide what you want to do, and then see what you need to make it happen. Sometimes you don't need attributes at all, or maybe much fewer than you thought.