1. Hello Guest! It's with a heavy heart that we must announce the removal of the Legacy GMC Archive. If you wish to save anything from it, now's the time! Please see this topic for more information.
    Dismiss Notice

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

Discussion in 'Programming' started by Danei, Apr 10, 2018.

  1. Danei

    Danei Member

    Joined:
    Mar 23, 2018
    Posts:
    278
    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!
     
    Lord KJWilliams likes this.
  2. Bayesian

    Bayesian Member

    Joined:
    Sep 13, 2016
    Posts:
    423
    Vars inside a script have a 'global'-ish scope and will work through with statements.
     
    Lord KJWilliams likes this.
  3. Danei

    Danei Member

    Joined:
    Mar 23, 2018
    Posts:
    278
    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: Apr 10, 2018
  4. Hyomoto

    Hyomoto Member

    Joined:
    Jul 7, 2016
    Posts:
    1,078
    @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.
     
    Lord KJWilliams likes this.
  5. Danei

    Danei Member

    Joined:
    Mar 23, 2018
    Posts:
    278
    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: Apr 10, 2018
  6. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    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.
     
  7. Hyomoto

    Hyomoto Member

    Joined:
    Jul 7, 2016
    Posts:
    1,078
    @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.
     
  8. bsabiston

    bsabiston Member

    Joined:
    Jun 21, 2016
    Posts:
    217
    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.
     
  9. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    The var needs to be inside the script itself.

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

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice