Legacy GM Parents are broken

Antikore

Member
I'm having a lot of trouble and issues when trying to use parents with my objects in my game. Until now, they were working good, but I added a level editor to my game and when importing a level into the real game, I have multiple issues when things are changed. One of them is the most obvious to say that parents are broken. I have two objects "obj_stoptile" and "obj_object". stoptile hasn't any code, but a code is run from another place to check for this object to do certain actions. Before this bug, it didn't inherit from any parent, I added obj_object as a parent that actually by itself it's only a classificatory object and also doesn't do anything but for whatever reason, the detection of the obj_stoptile when is parented with obj_object is bugged and doesn't work properly.

Code for checking the player if there is an stoptile after it:
Code:
var xx, yy;
xx = sign(hsp) * 16;
yy = sign(vsp) * 16;

if (place_meeting(x+hsp,y+vsp,obj_stoptile) && (atStoptile == noone || atStoptile != instance_place(x+hsp,y+vsp,obj_stoptile)) && !toStoptile)
{
    toStoptile = true;
    atStoptile = instance_place(x+hsp,y+vsp,obj_stoptile);
    slave_collider = instance_create(atStoptile.x+xx, atStoptile.y+yy, obj_slave_collider);
}
If obj_stoptile inherits from obj_object, the player stops when it has passed most of it. When it doesn't inherit from anything, it stops exactly where the stoptile is, just how I want.
This also seems to happen with other objects.

When it doesn't inherit from anything:
aa.png
When it inherits from obj_object (or any other, as I've tested):
aaaa.png

Things I've tried:
  • A lot of things, I don't remember, but mainly removing the parent and placing it. Changing where the check for stoptiles executes etc.
Technical Information:
  • Windows 10
  • GameMaker: Studio v1.4.1804
  • Standard Edition
Additional Note: Other of the parent bugs I have, was of a block that had a parent yet, but I changed it and even if I change to the old parent, it won't work now.
Thank you for reading :D
 

TheouAegis

Member
Should be a code error elsewhere. Nothing in that code would change with parents unless you accidentally made obj_stoptile the parent of obj_object. If obj_object is the parent, then you have code elsewhere.
 

Antikore

Member
Should be a code error elsewhere. Nothing in that code would change with parents unless you accidentally made obj_stoptile the parent of obj_object. If obj_object is the parent, then you have code elsewhere.
Probably, but the problem is that 2 of the items in the game fail because of that, both very different and I only have 3, the third I didn't check.
Also, that code is the only one that interacts with stoptiles, however, there are others that interact directly with obj_object and works fine, and I've tried to check if there was the problem but I didn't find anything.
 

TheouAegis

Member
So, you have code for interacting with obj_stootile AND code for interacting with obj_object inside the same object? It doesn't matter if you have only one code referring to obj_stoptile; if there is also code referring to obj_object, the obj_object one will also be run on obj_stoptile collisions. Any code which targets the parent will target all the children as well.
 

Antikore

Member
So, you have code for interacting with obj_stootile AND code for interacting with obj_object inside the same object? It doesn't matter if you have only one code referring to obj_stoptile; if there is also code referring to obj_object, the obj_object one will also be run on obj_stoptile collisions. Any code which targets the parent will target all the children as well.
I think it doesn't because first detects obj_object and then detects children of obj_object, and stoptile isn't detected, is detected on another script (the first one) and this object collision script if doesn't detect which one is, just overrides it and does nothing, but the other script should do the thing. I should join them but still strange because, before the editor, this worked.
I've also checked if the editor stuff was not transforming properly, but wasn't possible because the player will instead trespass anything, something that doesn't do.
 

Catastrophe

Member
You're going to have to dump a lot of code here for us to look at, I would be extremely surprised if parenting was broken. E.g. what is this level editor?
 

Antikore

Member
You're going to have to dump a lot of code here for us to look at, I would be extremely surprised if parenting was broken. E.g. what is this level editor?
I realized that a level editor in-game could be an easier to create levels for the game.
Anyways, here is the current player collision code:
Code:
var collider, xx, yy;

xx = sign(hsp) * 16;
yy = sign(vsp) * 16;

//Check for general collision with environment.
if (place_meeting(x+hsp,y+vsp,obj_object))
{
    collider = instance_place(x+hsp,y+vsp,obj_object);
    if (is(collider, obj_slave_collider))
    {
        if (collider != noone && slave_collider != noone && slave_collider == collider)
        {
            while (!place_meeting(x+sign(hsp),y+sign(vsp),obj_slave_collider))
            {
                x += sign(hsp);
                y += sign(vsp);
            }
            hsp = 0;
            vsp = 0;
            isMoving = false;
            toStoptile = false;
            instance_destroy(slave_collider);
            slave_collider = noone;
        }
    }
    else if (is(collider, obj_spikes))
    {
        if (slave_collider == noone)
        {
            if (collider.dir == dir || collider.dir == 4)
            {
                if (!place_meeting(collider.x+xx,collider.y+yy,obj_solid))
                {
                    slave_collider = instance_create(collider.x+xx,collider.y+yy,obj_slave_collider);
                }
                death_on_stop = true;
            }
        }
    }
    else if (is(collider, obj_solid))
    {
        while (!place_meeting(x+sign(hsp),y+sign(vsp),obj_solid))
        {
            x += sign(hsp);
            y += sign(vsp);
        }
        hsp = 0;
        vsp = 0;
        isMoving = false;
        toStoptile = false;
    }
    else if (is(collider, obj_stoptile))
    {
        check_for_stoptile();
    }
}

//Check for collision players
if (place_meeting(x+hsp,y+vsp,obj_player))
{
    var p = instance_place(x+hsp,y+vsp,obj_player);
    check_collide_players(p);
}
The only thing I changed from when it worked is that now detects the stoptile here instead of the other place.

PD: is() is a script in my game.

PD2: I noticed that the slave_collider (which makes you stop over a stoptile) seems to not be created, when I put it visible, its not visible in-game, but if I remove the parent from obj_solid, the player doesn't stop in any form, so it's there but Idk in what way.
 

Catastrophe

Member
Well, a frequent issue with parenting is forgetting event_inherited(). Does your parent/child object have code in the same events?
 

Antikore

Member
Well, a frequent issue with parenting is forgetting event_inherited(). Does your parent/child object have code in the same events?
As I said, obj_stoptile, obj_object, obj_solid and obj_slave_collider doesn't have any event. All it's done by scripts in the player.
 

Catastrophe

Member
Hmm.. well it depends on what your definition of "is" is.

Heh, sorry. I'm wondering if that code is incorrect. I'm guressing it's

return (argument0.object_index = argument1 || is_ancestor(argument1,argument0.object_index))?

Also, the problem with the code is unlikely to be here if this started with the level editor you're using, that's why I wanted to know what that code was.
 

Antikore

Member
This actually works fine, I probably can compress it more.
Code:
///is(object, type);
var _i, _i2;

_i = argument0.object_index;
_i2 = argument1;
if (_i == _i2 || object_is_ancestor(_i, _i2))
{
    return true;
}
return false;
Actually, the editor are multiple objects, multiple scripts, multiple events. Which part will be more likely to have an issue with parents?
 

Catastrophe

Member
No idea lol. If it's that huge let's not bother then.

This sounds super complicated, we'll need some debugging help. Usually with a complicated issue you'd throw in a bunch of logging to see if some code is incorrectly triggering. Put some show_message("got here") or show_message(string (varName)) in some places of the character code. So log out xx,yy, the sprite origin maybe, etc. When you stop, log out the stopping object and player's x and stuff like that.
 
Last edited:

Antikore

Member
No idea lol. This sounds super complicated, we'll need some debugging help. Usually with a complicated issue you'd throw in a bunch of logging to see if some code is incorrectly triggering. Put some show_message("got here") or show_message(string (varName)) in some places of the character code. So log out xx,yy, the sprite origin maybe, etc. When you stop, log out the stopping object and player's x and stuff like that.
Ok, thank you, I will try that. If the issue persists, I will return here again for some help.
 

Antikore

Member
I've found the source of the error, and it's very dumb so I don't know how to fix it.
I noticed that the player collides correctly with the stoptile and the collider is created, the collider is in the correct position also, but the player for whatever reason trespasses over the collider until it is over most of it, then executes the colliding. That means, the collision with the obj_slave_collider, it's wrong. The problem is that the collision with obj_slave_collider is exactly the same as the solid, so it might be the same, but the normal solid works fine and this no. Maybe it is related to the collision mask/hitbox etc, but it's the same as any solid because it inherits from obj_solid and the sprite is the same, and "obj_object" also has the same sprite.

So, I think it's probably GameMaker Studio bugged, at least it's the most probable thing.
 

Antikore

Member
Current code:
Code:
var collider, xx, yy;

xx = sign(hsp) * 16;
yy = sign(vsp) * 16;

//Check for general collision with environment.
if (place_meeting(x+hsp,y+vsp,obj_object))
{
    collider = instance_place(x+hsp,y+vsp,obj_object);
    if (is(collider, obj_slave_collider))
    {
        if (slave_collider != noone && slave_collider == collider)
        {
            while (!place_meeting(x+sign(hsp),y+sign(vsp),obj_slave_collider))
            {
                x += sign(hsp);
                y += sign(vsp);
            }
            hsp = 0;
            vsp = 0;
            isMoving = false;
            toStoptile = false;
            instance_destroy(slave_collider);
            slave_collider = noone;
        }
    }
    else if (is(collider, obj_spikes))
    {
        if (slave_collider == noone)
        {
            if (collider.dir == dir || collider.dir == 4)
            {
                if (!place_meeting(collider.x+xx,collider.y+yy,obj_solid))
                {
                    slave_collider = instance_create(collider.x+xx,collider.y+yy,obj_slave_collider);
                }
                death_on_stop = true;
            }
        }
    }
    else if (is(collider, obj_solid))
    {
        while (!place_meeting(x+sign(hsp),y+sign(vsp),obj_solid))
        {
            x += sign(hsp);
            y += sign(vsp);
        }
        hsp = 0;
        vsp = 0;
        isMoving = false;
        toStoptile = false;
    }
    else if (is(collider, obj_stoptile))
    {
        check_for_stoptile();
    }
}
I managed to find that obj_stoptile is executing even if it should do the first if, so it tresspasses the slave collider due to it's checking stoptile even if it should check first for the slave collider.
 
Top