• Hey! Guest! The 39th GMC Jam will take place between November 26th, 12:00 UTC and November 30th, 12:00 UTC. Why not join in! Click here to find out more!

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!
 

FrostyCat

Member
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.
 
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