hello 3run

Increasing the player_controller's max_z solved the problem for me:

my->scale_z = 0.5;
wait(1);
c_setminmax(my);
my->max_z += 10; ///----------------------NEW EDIT HERE


Increase the max_z so that the top of the player controller's bounding box is flush with the XY controller max_z.

However, I have to ask, what's the reason you want to split it into 2 entities? Is there a way to code it that the XYZ is handled in one entity? I think this is the root of your problem:

if(hero_ent)
{
hero_ent->x = my->x;
hero_ent->y = my->y;
my->z = hero_ent->z + 16;
}

Youre manually moving an entity that is part of collision and requires collision, but still manually moving it anyway. This isnt good in my opinion.

The Z entity is moving the XY entity manually, and the XY entity is moving the Z entity manually. Sooner or later, inaccuracies in the frame time will cause the Z entity to move upward, not registering the collision response of the XY entity when it hits a wall.

In my opinion this may only get worse down the line as you flesh out the character. Combine the two entities into 1, and calculate the XYZ using a single consistent bounding box.