Legacy GM Variable calling problem that I can't understand

M

Mapped

Guest
Hello,
I am relatively new to programmation and coding, and GameMaker has been of huge help to start learning and practicing.
I started testing out coding manually, but I've encountered an error that I can't seem to fix and I haven't been able to find the answer to it...
Basically, I started by making this sort of random pattern generator (really basic stuff), that used black and white boxes to generate this QR-code looking thing. Then, I tried to make a colored palette using make_color_hsv. Here's the object used for making the boxes (obj_boxmaker):
Code:
///Creation
for(row=0; row<22; row++)
    {
    instance_create(x,y+(32*row), obj_box);
    var column = 0;
    for(column=0; column<22; column++)
        {
        instance_create(x+(32*column), y+(32*row), obj_box);
        }
    }
And the boxes being colored (obj_box):
Code:
image_blend = make_color_hsv(obj_boxmaker.row*11,255,obj_boxmaker.column*10);
However, whenever I try to call the 'column' variable of the boxmaker, using obj_boxmaker.column, an error pops up and says :
Variable obj_boxmaker.<unknown variable>(100002, -2147483648) not set before reading it.
For some reason, there's an error with that part but not with the 'row' variable. How come?
Thanks for the help.
 

TsukaYuriko

☄️
Forum Staff
Moderator
You're declaring your variable in a local (var) context in your creation code. This means that they will be removed from memory after the code block they were declared in ends.
 
M

Mapped

Guest
Is there any way I can declare it so it can be fetched from outside the block? Thanks for your patience
 
M

Mapped

Guest
Remove the var
I did, but the same error happens... They are not in the same object, so should I find a way define the color of the next box in my 'boxmaker' object? Or should I just change the location of "var column"?
 

TsukaYuriko

☄️
Forum Staff
Moderator
When making changes to your code in between posts, please always post all relevant, updated code to ensure that your actions match the instructions you were given, as problems resulting from this can not be ruled out from our side without seeing the updated code.


When not declared using var, variables will default to instance scope and therefore persist. Take a look at your row variable, for example. You're not declaring that one as local and it persists just fine, so there is no reason why the same shouldn't apply to the other one. If you can't refer to it after that code completes, it's still being declared as local, the names don't match or the instance holding them doesn't exist.

That aside, if you're at a point where you're looking for that sort of workarounds, nothing aside from a restructuring of your code will help or you will get yourself and your code into an unimaginable mess.


Keep the column variable local and make the row one local as well. Move the code that colors the boxes into the box maker, wrap the instance_create into a with statement like in the ball example in the manual and perform the coloring right then and there. row and column will be accessible inside the with statement's body because they were declared as local to the code block, you won't have to mess around with keeping them around after the event finishes and there won't be any margin for errors.
 
M

Mapped

Guest
Alright, it works! Though There's one last issue, the first column is completely white, am I using the with wrong? Here's how I used it:
Code:
for(row=0; row<22; row++)
    {
    instance_create(x,y+(32*row), obj_box);
    for(column=0; column<22; column++)
        {
        with (instance_create(x+(32*column), y+(32*row), obj_box)) image_blend = make_color_hsv(obj_boxmaker.row*10, 255, obj_boxmaker.column*10);
        }
    }
Again, thanks a lot!
 

Simon Gust

Member
You are using it wrong still. The instance_create() after the first for loop isn't neccessary.

Also, your code can be expressed in many different ways.
Because right now, it's not really efficient at all.
Code:
for (var row = 0; row < 22; row++)
{
  for (var column = 0; column < 22; column++)
  {
    var xx = x + (32 * column);
    var yy = y + (32 * row);
    var inst = instance_create(xx, yy, obj_box);
    inst.image_blend = make_color_hsv(row * 10, 255, column * 10);
  }
}
Basically, as long as you declare the variable with var before you read it, it doesn't throw an error.
But be aware, local variables (the ones declared with var) cannot be written or read using dot-operators
Example
Code:
var my_variable = 10;

obj_boxmaker.my_variable = 11;
This will throw an error.

Code:
my_other_variable = 10;

obj_boxmaker.my_other_variable = 11;
This won't

However, when using a with statement, the rules change
Code:
var my_variable = 10;

with (obj_box)
{
  my_own_box_variable = my_variable;
}
This will not throw an error even though the scope changed to obj_box.

Code:
my_other_variable = 10;

with (obj_box)
{
  my_own_box_variable = my_other_variable;
}
This will throw an error as game maker tries to find my_other_variable as a variable inside obj_box, but my_other_variable is a variable created in obj_boxmaker and it's scope is instance based.
In this case you would use
Code:
my_other_variable = 10;

with (obj_box)
{
  my_own_box_variable = obj_boxmaker.my_other_variable;
}
or
Code:
my_other_variable = 10;

with (obj_box)
{
  my_own_box_variable = other.my_other_variable;
}
other refrencing the object outside the with statement.

If you have multiple of obj_boxmaker, you may only use the second variant as game maker doesn't know which boxmaker to refrence when you just call obj_boxmaker.my_other_variable.
 
Top