• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker [SOLVED] Question about local variable scope and the 'with' construction

D

Danei

Guest
So, I have a turn-based RPG in development where you have an overworld map and local encounters which you will be able to exit in a variety of ways, and I use essentially the following code, in a script that is called from a player object not referenced in the code.

Code:
//scr_tryToLeave(direction);

var dir = argument0;
var dirStr = "test";
if (dir == 360) dirStr = "East.";
if (dir == 270) dirStr = "South.";
if (dir == 180) dirStr = "West.";
if (dir == 90) dirStr = "North.";

// Determine whether we're fleeing or traveling normally (not yet implemented)
 
[INDENT]var exitType = "Flee";[/INDENT]



with (obj_encounter){ //exit encounter and move back to world map
 instance_destroy();
}


with (obj_cursor){
    actionString = exitType+dirStr; //set exit message
    scr_pushMessage(actionString); //display exit message
 
   
}
Anyway, as I was coding this I realized, "wait, this probably won't work because I'm declaring the local variables dirStr and exitType in my player object, but trying to access them in my cursor object", but I tried it on a whim and to my surprise it works just fine. So my question is why does it work? Not that I'm complaining. But I would have expected the local variables not to be available to the object that is calling them. I could have sworn I ran into that exact issue a lot when I was first learning with 1.4. Does the fact that all of this is occurring within one script have anything to do with it? I'm using the current version of GMS2.

Just curious. Thanks!
 
D

Danei

Guest
Oh ok, cool, that's good to know. I think that'll simplify some of my scripts.

I think a long time ago I kept trying to use something like: with (object) { variable = other.localVariable } to attempt to access local variables outside the With and found that it couldn't get them.

Thanks!

I can't figure out how to mark this thread solved. I guess I just edit the title. I'm a problem solving champion.
 
Last edited by a moderator:

Hyomoto

Member
@Danei - Just to clarify that a bit. The 'scope' of variables is global, instance and local. Global can be accessed anywhere, instance variables can be called from the instance they were made in, and local variables are available for the script they are written. Yes, that includes things such as with statements. As for global and instance, there's only a minor distinction here. Namely consider this:
Code:
global.variableName = 10;
instance.variableName = 10;
Global variables are really just instance variables attached to the 'global' object. I bring this up because you might hear the semantics bantered about, and they aren't wrong. When dealing with other languages that have a stricter definition of scope, it's quite simply not possible to access certain variables from beyond their scope. In GM if you have the instance id, you can access it's variables. It does simplify things, but it means that variables in GM are really just local and instance.

I know this goes beyond the scope of your original question, but hopefully this gives little more context as to what scope means in GM.
 
D

Danei

Guest
Thanks, that makes sense. What constitutes a 'script' for purposes of local vars if I wasn't using a script asset? An event? Also, if you don't mind a bunch of random questions about variables, is there any difference in processing/performance between any of the following things?
  1. Accessing a global variable within an instance.
  2. Accessing an instance variable of a different instance using instanceid.variable.
  3. An instance accessing its own (instance) variable.
 
Last edited by a moderator:

TheouAegis

Member
Scripts and Code actions, afaik. Once the code you declared var in ends, the variable is freed, so it should be unusable in the next Code action even innthe same event. But test it.
 

Hyomoto

Member
@Danei - A script is pretty easy to define as a page of code. If it's in the same page, it's the same script. There are some limits to this that mostly arise because of how GM highlights variables, but if you define a var it at the top it's available until the bottom.

Global variables are slowest, because GM has to do a lookup. I don't remember threat semantics and supposedly you can speed it up, and GM2 might be better at it than GM1, but as a simplification they are the slowest. Then another instance, then a local variable. Now, it should be noted the time loss is limited and likely unnoticeable. However if you have a lot of variables in a different instance to change, using the with statement will change the scope and you can avoid writing the dot notation over and over.

However, and I stress this part, the takeaway should be variable lookup is fast enough it is really only a consideration in exceptional cases. Generally you'll save more time not doing something than changing which type of variable you are using.
 

bsabiston

Member
Vars inside a script have a 'global'-ish scope and will work through with statements.
Is this true? It does not seem to be. I have a local variable defined outside my 'with', and the IDE is complaining that it's only used once. All my usage is inside the 'with', where it is showing the variable in blue as if it is an instance variable.
 

TheouAegis

Member
The var needs to be inside the script itself.

Code:
var a;
with obj_cat
if y>room_height/2
   a = id;
return a
 
Top