• 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!

Legacy GM Weird "with" statement behaviour

M

Maisenberg

Guest
Hey guys,

so in my game I'm implementing a menu where the player selects certain stuff and I pass some important values to a "level creator" object which will set up a level when I'm done. (For example, the player selects a character and I give this object a character index and name to use it later).

I've ran into a weird issue regarding with statements. In my character selection menu, once the player selects a character I wrote:

Code:
with (obj_level_setup) {
      character[i] = other.on_character[i];   //This line works fine
      character_name[i] = other.menu[on_character[i]];   //This has a problem
}
Let me explain quickly. The character selection menu runs a for loop with the amount of players participating, and each player can select a character. The code I just provided is inside this loop. on_character[i_] is a variable which holds the index of the character that the i-th player is on in the menu. "menu" is an array that holds strings with the names of the characters, so calling menu[on_character] gives me the string of the on_character[i_]-th entry.

(using [i_] with the underscore because it sets the text to italic without it lol)

However, this code gives me an error:
"trying to index a variable which is not an array: character_name = other.menu[on_character];"

This is really weird and for some reason if I do:

Code:
name = menu[hovering[i]];
with (obj_level_setup) {
      character[i] = other.hovering[i];
      character_name[i] = other.name;
}
it works perfectly fine. However, I cannot use "var name", it gives me another error: "Variable <unknown_object>.<unknown variable> not set before reading it: character_name = other.name;".

I'm guessing that there's a problem with getting local variables from other objects in a with statement, which wouldn't surprise me (although that brings me to the question: "i" is also a local variable created for the loop and it seems to use it well), but I have no clue why my original code does not work and why it says the variable I'm trying to index is not an array. Any idea why this might occur? It's fixed with this last piece of code, but I'd still like to know what's going on. Thanks!
 
J

JFitch

Guest
You have to use "other" again.
Code:
character_name[i] = other.menu[other.on_character[i]]
 

FrostyCat

Redemption Seeker
Rules on how to reference a variable from within a with block:
  • Local variable (i.e. declared with var): variable
  • Instance variable belonging to the calling instance: other.variable
  • Instance variable belonging to the called instance: variable
  • Standard global variable: global.variable
  • Deprecated globalvar-declared global variable (strongly discouraged): variable
  • Instance variable belonging to an unrelated subject (e.g. a controller) or a fixated subject (i.e. instance ID stored in a local variable): subject.variable
Following the rules above, if you decide to declare name using var, you must get rid of the other. dereference.
Code:
var name = menu[hovering[i]];
with (obj_level_setup) {
     character[i] = other.hovering[i];
     character_name[i] = name;
}
I suggest that you start declaring your temporary variables using var from now on. They have an easier time getting across a with block, play cleaner with scripts, and leave your instance scope free of irrelevant junk.
 

xDGameStudios

GameMaker Staff
GameMaker Dev.
Hey guys,

so in my game I'm implementing a menu where the player selects certain stuff and I pass some important values to a "level creator" object which will set up a level when I'm done. (For example, the player selects a character and I give this object a character index and name to use it later).

I've ran into a weird issue regarding with statements. In my character selection menu, once the player selects a character I wrote:

Code:
with (obj_level_setup) {
      character[i] = other.on_character[i];   //This line works fine
      character_name[i] = other.menu[on_character[i]];   //This has a problem
}
Let me explain quickly. The character selection menu runs a for loop with the amount of players participating, and each player can select a character. The code I just provided is inside this loop. on_character[i_] is a variable which holds the index of the character that the i-th player is on in the menu. "menu" is an array that holds strings with the names of the characters, so calling menu[on_character] gives me the string of the on_character[i_]-th entry.

(using [i_] with the underscore because it sets the text to italic without it lol)

However, this code gives me an error:
"trying to index a variable which is not an array: character_name = other.menu[on_character];"

This is really weird and for some reason if I do:

Code:
name = menu[hovering[i]];
with (obj_level_setup) {
      character[i] = other.hovering[i];
      character_name[i] = other.name;
}
it works perfectly fine. However, I cannot use "var name", it gives me another error: "Variable <unknown_object>.<unknown variable> not set before reading it: character_name = other.name;".

I'm guessing that there's a problem with getting local variables from other objects in a with statement, which wouldn't surprise me (although that brings me to the question: "i" is also a local variable created for the loop and it seems to use it well), but I have no clue why my original code does not work and why it says the variable I'm trying to index is not an array. Any idea why this might occur? It's fixed with this last piece of code, but I'd still like to know what's going on. Thanks!
as you already accessed

Code:
other.on_character[i];

and placed its value on the

character

you should be good by removing the "on_" from the second line where the problem was

Code:
with (obj_level_setup) {
      character[i] = other.on_character[i];   //This line works fine
      character_name[i] = other.menu[character[i]];   //This is where the problem WAS :)
}
 
Last edited:
M

Maisenberg

Guest
You have to use "other" again.
Code:
character_name[i] = other.menu[other.on_character[i]]
Oops, of course. Totally forgot that new other. Thanks!

Rules on how to reference a variable from within a with block:
  • Local variable (i.e. declared with var): variable
  • Instance variable belonging to the calling instance: other.variable
  • Instance variable belonging to the called instance: variable
  • Standard global variable: global.variable
  • Deprecated globalvar-declared global variable (strongly discouraged): variable
  • Instance variable belonging to an unrelated subject (e.g. a controller) or a fixated subject (i.e. instance ID stored in a local variable): subject.variable
Following the rules above, if you decide to declare name using var, you must get rid of the other. dereference.
Code:
var name = menu[hovering[i]];
with (obj_level_setup) {
     character[i] = other.hovering[i];
     character_name[i] = name;
}
I suggest that you start declaring your temporary variables using var from now on. They have an easier time getting across a with block, play cleaner with scripts, and leave your instance scope free of irrelevant junk.
Thanks a lot! I use temporary variables all the time but for some reason I never needed them in a with statement so I just got confused and didn't know I didn't have to use other.
 
Top