Question regarding local/global variables. *SOLVED*

Started by lizzlebizzle, Sun 08/05/2011 21:40:53

Previous topic - Next topic

lizzlebizzle

Why, hello.

So, I'm working on a Maniac Mansion Mania-type game, just a simple room escape game for my first attempt at figuring out AGS. I know the basics of C++.

Still trying to understand how the global script and room scripts interact with one another. Are room scripts "nested" in the global script? Or do they kind of run parallel and the room calls things from the global script? Vague question, I know.

Right now, I'm trying to have my character try to open a door, and then say, "Ugh, it's locked." But the second time she tries to open the door, and thereafter, she says something different. I tried declaring a local bool variable and initializing to false (then changing to true after she tries to open the door), but it's not workin'.

Does this bool variable need to be a global variable (like in the global script)? And if so, why? I really appreciate the help, and pardon the newbieness for a couple years. :)



lizzle


Snippet o' code:

Code: ags


  else if (UsedAction (A_OPEN))
  {
    bool hasTried = false;
    if (!hasTried)
    {
      Display ("Ugh. It's locked.");
      FaceDirection (GetPlayerCharacter (),  DIR_DOWN);
      Display ("And there's no doormat to hide a key under.");
      hasTried = true;
    }
    else if (hasTried)
    {
      Display ("BERNARD!!! You little twit! Let me out of here!");
      Display ("...");
      Display ("Guess he's long gone by now.");
    }
  }


Snarky

#1
For the bigger question, my mental model (and I'm not guaranteeing that this is correct in every particular detail) is that all the scripts are essentially different "buckets" of code. The global script bucket is always accessible, and the room script bucket is accessible when that room is active. Code in these buckets doesn't run by itself, it actually gets run in response to events, i.e. things that happen (user clicks on something, etc.), except for the code in the various "repeatedly execute" functions, which get called every time the game refreshes - usually 40 times every second.

The room code doesn't call things from the global script, usually. You can create functions that can be called from every room using "import" headers, but I'd typically place those in a separate script.

Anyway, I don't think that's your problem in this case. Looking at your code, you're setting the hasTried value to false right before you're checking it, so of course it's going to be false. Also, you're defining the variable inside the function, so its scope is only that function: as soon as the function completes, it disappears, and the next time you call the function it's defined again, with no memory of the value you set it to last time.

What you have to do is define and set the variable outside of the function, probably at the top of your room script. That way it gets initialized to false just the one time, instead of every time you call the function.

So you were kind of on the right track: the variable does need to be "global" (i.e. not local to the function), but only within the room. It doesn't need to be global to the whole game (belong to the global script), as long as you'll never set it or check the value of it from another room.

lizzlebizzle

Uh...Wow.

I think I need more coffee. Can we say logic error...?? Thanks, Snarky. Done and done. I did a little more research so I knew I didn't need a global variable, but even when I set a breakpoint and debugged it, I didn't see the darned error I had made. Went ahead and put it at the top of my room script, as you suggested.

Sometimes it takes a second pair of eyes! Thanks! :)


lizzle

monkey0506

Well the same logic applies to C++, with the exception that C++ has the option of static variables which AGS does not.

In any case, you got it sorted out in the end, and, you're absolutely right that sometimes a second pair of eyes can be very useful.

Welcome to AGS!

Khris

Just for the sake of completeness, there's Game.DoOnceOnly which you can use for things like this:

(I've also translated the commands to new-style code, maybe you're using an old tutorial/starter pack? I'd recommend highly not to use outdated packs or tutorials.)

Code: ags
else if (UsedAction (eActOpen))  // not sure about this one
  {
    if (Game.DoOnceOnly("open room door"))
    {
      player.Say ("Ugh. It's locked.");
      player.FaceDirection (eDirDown);
      player.Say ("And there's no doormat to hide a key under.");
    }
    else
    {
      player.Say ("BERNARD!!! You little twit! Let me out of here!");
      player.Say ("...");
      player.Say ("Guess he's long gone by now.");
    }
  }


The starter packs are set so that Display commands also produce LucasArts speech but it can't hurt to use the correct command.
Also, using just "else" is already equivalent to "else if (![what you used after if])", so if there's just A and !A, else alone is fine.

lizzlebizzle

#5
Ah! Thanks! Didn't know there was a built-in function. I will use that in my code. I also already changed my "else if" to "else" on my own.

You've all been a great help!


Addendum: Also, regarding old tutorials, thanks for the heads-up. I'm playing around with a starter pack I got from the Maniac Mansion Mania website, and not only are some things German, but obviously they've used an older version of AGS. I've been mostly reading the Dynamic Help in AGS itself. Trying to keep the versions straight is something I'm still getting used to. :-\ I'll translate to newer code.

Calin Leafshade

Since we're in correct code mode I should point out that: 

Code: ags

player.FaceDirection (eDirDown);


is not built-in AGS code but a custom function.

Khris

So is UsedAction() btw.

lizzlebizzle:
There are quite a few useful additional functions in the starter packs none of which are mentioned in AGS's helpfile obviously.
If you have any questions, feel free to use this board:
http://www.maniac-mansion-mania.de/forum/index.php?board=12.0

If you can bear to follow a google translated tutorial, look at this post by Endres.

SMF spam blocked by CleanTalk