GML [SOLVED] var instance_create() doesn't change instance variables

N

NeZvers

Guest
I have a game master object that is creating controller objects and player objects in Room Start event but for some reason, It doesn't change needed variables (they stay as they are defined by default). All I need it to toggle what inputs controllers should respond.
I don't get it, I thought that's how you can tweak created objects.

Code:
/// SPAWN CONTROLLERS & PLAYERS

var controller1 = instance_create(x,y,par_controller);
var sp = instance_find(oSpawn, irandom(instance_number(oSpawn) - 1));
var p1 = instance_create(sp.x,sp.y,obj_player);

// Doesn't work like this
p1.controller = controller1;
p1.character = global.player1character;
p1.touchCtrl = 0;
p1.keyboardCtrl = 0;
p1.gamepadCtrl = 1;
p1.gamepadIndex = 0;

obj_display_manager.target = p1;


while(sp.x == p1.x && sp.y == p1.y){
    sp = instance_find(oSpawn, irandom(instance_number(oSpawn) - 1));
}

var controller2 = instance_create(x,y,par_controller);
var p2 = instance_create(sp.x,sp.y,obj_player);

// And doesn't work like this
with(p2){
    controller = controller2;
    character = global.player1character;
    touchCtrl = 0;
    gamepadCtrl = 0;
    keyboardCtrl = 1;
    gamepadIndex = 1;
}
 
Last edited:

Pfap

Member
What does the create event of obj_player look like?

Code:
//create event of obj_player
controller = noone;
character = -1;
//etc....
Do you have them set to initial back to what they were each time the are created?
Then each new room would set them back to defaults, you could make a persistent object and then save the obj_players state and then update the create event with the saved variables.
 

samspade

Member
I have a game master object that is creating controller objects and player objects in Room Start event but for some reason, It doesn't change needed variables (they stay as they are defined by default). All I need it to toggle what inputs controllers should respond.
I don't get it, I thought that's how you can tweak created objects.

Code:
/// SPAWN CONTROLLERS & PLAYERS

var controller1 = instance_create(x,y,par_controller);
var sp = instance_find(oSpawn, irandom(instance_number(oSpawn) - 1));
var p1 = instance_create(sp.x,sp.y,obj_player);

// Doesn't work like this
p1.controller = controller1;
p1.character = global.player1character;
p1.touchCtrl = 0;
p1.keyboardCtrl = 0;
p1.gamepadCtrl = 1;
p1.gamepadIndex = 0;

obj_display_manager.target = p1;


while(sp.x == p1.x && sp.y == p1.y){
    sp = instance_find(oSpawn, irandom(instance_number(oSpawn) - 1));
}

var controller2 = instance_create(x,y,par_controller);
var p2 = instance_create(sp.x,sp.y,obj_player);

// And doesn't work like this
with(p2){
    p2.controller = controller2;
    p2.character = global.player1character;
    p2.touchCtrl = 0;
    p2.gamepadCtrl = 0;
    p2.keyboardCtrl = 1;
    p2.gamepadIndex = 1;
}
The code seems like it should work, except that if you are using a with statement, you don't need the instance id. Have you put a breakpoint in and run the debugger to check and see if the variables are being set (or used show_debug_message, etc.)? If I had to guess, I would say either your code isn't being run or something is resetting them.
 

kburkhart84

Firehammer Games
I think you are going about things the wrong way. Using the var keyword will result in creating variables that disappear each time that code block is done running. It is called a "local variable" and will recreate itself each time you run the code block, and won't be around later if you try to find it(either with the dot syntax or with the "with" syntax). To get variables that stay around(called instance variables), you would do the same thing you are doing now, except get rid of the var keyword. So if you create those variables in the create event, it will then be a variable you can later access in the step event.

The other issue I see in your 2nd version that isn't working is that you are combining the dot syntax with the "with" syntax. When you put "with(p2){}, the stuff in the brackets works as if it was part of that object instance, so you don't want the "p2." when accessing the variables. However, to access variables that are on the "original" object instance, you would be able to use "other." to do that while you are inside the with() brackets. In this case though, using the dot syntax is likely the best way to go, once you figure out the stuff I mention in the first paragraph.
 

samspade

Member
I think you are going about things the wrong way. Using the var keyword will result in creating variables that disappear each time that code block is done running. It is called a "local variable" and will recreate itself each time you run the code block, and won't be around later if you try to find it(either with the dot syntax or with the "with" syntax). To get variables that stay around(called instance variables), you would do the same thing you are doing now, except get rid of the var keyword. So if you create those variables in the create event, it will then be a variable you can later access in the step event.
This is only half true, he is doing at least that part correctly. While you are right that var makes a temporary variable, what is temporary is the variable. instance_create returns an instance id. That id is not temporary. It is the instance id of that instance. When he does p1.controller = controller1; He isn't saving the temporary variable to p1.controller he is saving the value stored in the temporary variable. That value is just a number, and in this specific case it is the instance id number.

Or to put it another way, controller1 is a box, the contents of this box is set to a real thing. p1.controller is a box. the contents of this box is set to the real thing in the first box. Then the first box is thrown away. But the second box (p1.controller) exists, so that's fine.[/QUOTE]
 

kburkhart84

Firehammer Games
This is only half true, he is doing at least that part correctly. While you are right that var makes a temporary variable, what is temporary is the variable. instance_create returns an instance id. That id is not temporary. It is the instance id of that instance. When he does p1.controller = controller1; He isn't saving the temporary variable to p1.controller he is saving the value stored in the temporary variable. That value is just a number, and in this specific case it is the instance id number.

Or to put it another way, controller1 is a box, the contents of this box is set to a real thing. p1.controller is a box. the contents of this box is set to the real thing in the first box. Then the first box is thrown away. But the second box (p1.controller) exists, so that's fine.
[/QUOTE]

You would be right...except that "p1" is also created as a local temp variable, which means that it also disappears. Besides that part you are correct, you can assign temp variable values to regular variables and they stay there, but assigning temp var values to other temp variables results in the data still being lost.
 

samspade

Member
The same thing is true for p1. Or perhaps I don't understand what you mean. You should do a simple test:

Code:
///obj_test create event
test_var = 0;
show_debug_message("created, test var = " + string(test_var));

///obj_test space bar event
show_debug_message("test var = " + string(test_var));

///mouse click event of some object
var inst = instance_create(mouse_x, mouse_y, obj_test);
inst.test_var = 1;
show_debug_message("modified, test var = " + string(inst.test_var));
You will get:
created, test var = 0
created, test var = 1

and whenever you push space you will get

test var = 1
 
except that "p1" is also created as a local temp variable, which means that it also disappears.
I'm not quite sure what you are getting at either. The local variables p1 and p2 will disappear only once the event/codeblock is completed - true - but the instances that were created and had initially been assigned into those variables will still exist. I use the method of assigning the id of the created instance into a local (var) variable just as is being done and then accessing the necessary instance-variables using that local variable to access the instance - no problems with that.
 
N

NeZvers

Guest
@kburkhart84 I'm executing this cone ONLY in Room Start and ONLY for purposes to create instances, bind controller instances to player instances and I need to toggle switches for the created controller.
I don't need to keep saved IDs for them after the fact.

with(p2) {} doesn't work either (after removing p2. ).



OMG!! I'm moron :D :D
I tried to switch toggles on a character that I was supposed to change on controller :D
Weird I thought that GM:S2 should show that there are no such variable I'm trying to change.
Thanks, guys for hustle!
 
Last edited:

TheouAegis

Member
Where are you setting the decault values for theplayer objects? And are you sure you did not manually add any players into the room yourself earlier?
 

samspade

Member
Weird I thought that GM:S2 should show that there are no such variable I'm trying to change.
Since you're setting, not using, there's no error. You can 'create' variables, even instance variables like this at any time (you just don't generally want to).
 

samspade

Member
@samspade can you please direct me to place for info how to create variables when creating a new instance.
I'm not exactly sure what you mean? If you mean my comment, I just meant that saying variable_name = something makes variable_name an instance variable in that object if it wasn't before. So if you say:

Code:
with (some_instance) {
    test = true;
}
If some_instance didn't already have a variable named test that equaled true, it does now.

If you mean ways of setting variables when you're creating an instance, then any of the following three will work:

Code:
with (instance_create(x, y, object)) {
    test = true;
}

var inst = instance_create(x, y, object);
inst.test = true;

var inst = instance_create(x, y, object);
with (inst) {
    test = true;
}
If you mean how to create an instance so that the instance's variables are set in the object's create event, you could read this: https://yal.cc/gamemaker-create-event-arguments/
 

kburkhart84

Firehammer Games
I apologize...I somehow got the idea that "p1" was also being used later after this code block.......not sure why as that wasn't the case looking back at the posts there. So yes, the "p1" variable would disappear, but the variables that were put on it, controller, etc... even though the p1 disappears, of course because p1 is just a temp pointer to the instance, not the actual instance.. I'm not sure why I misread that. That's on me.
 
Top