Wall Hugging / Pixel Strafing / Automatic Repositioning

Good day all!

I have a three-tiled table; the middle tile has a smaller hitbox than the other two tiles. With a simple “separate player from object” action, the player won’t move when pressing left or right while standing in front of the middle tile, as the hitboxes from the other two tiles collide with them:

ezgif.com-crop

The player has to press down + right / down + left to leave the table, which doesn’t feel very satisfying when playing, especially since it takes a second for you to realize that you’re stuck and have to press another button.

My idea, and something that a lot of other top-down games do, is to automatically move the player along the corner of a hitbox if said hitbox is smaller than 1 tile (in my case 32x32) when they press against it. This would greatly impact the game feel as the table is only one of many examples.

If I understood correctly, the community extension Top-down corner sliding by @davy does something similar already, but unfortunately it seems to only work with single objects. When using it with a whole tilemap collision, instead of moving you along the corner of a single tile, it teleports you to the corner of the whole map :rofl:

I have played around a bit with different approaches but to no avail, especially because I can’t find a way to check for hitbox size in a condition. Does anyone have a solution to this problem?

Thanks in advance!

Never used tile maps
But if i am correct you can select which objects will have collisions and which not

So why not remove collision in tile map from table
And fake invisible object and place it where you want collision with table to be
And you are pretty much done

It looks like the table is made up of 3 rectangles and there’s a notch. The player is getting hooked in between the legs. Can you change the collision to 1 rectangle?

Does the player also get stuck to the couch?
image

I should have specified more, sorry!

The table is not my problem, it was just one of many examples; if it was only the table I could easily replace it with a custom collision mask like @ZeroX4 said or make the collision more uniformed like @Keith_1357 said. The problem is that there are many objects like that and many are not solvable by an uniformed collision mask.

Here is a very grueling example:
ezgif.com-crop (1)

This is what happens if I press right + up / right + down while standing in front of this wall. The collisions on the wall tiles are unchanged 32x32 squares, so there should be no way the player gets stopped between two tiles. I double checked if all collision masks for the player are the same and even set up a small unanimated square as the player to make 100% sure that my collisions aren’t off, but the results stayed the same.

From what I have found online, this is a known bug that sometimes happens with Tiled hitboxes across many engines. Unity for example has a Composite function to fix this, but I haven’t found anything for GDevelop so far. That’s why I think a small repositioning function might be the easiest solution.

The fact that it stops right at an edge makes me think the one shape or mask is sticking out a pixel or 2.

Are the squares separate objects or a tilemap. If they’re separate objects, I’d check their x and y coordinates either in the editor or add an event that displays the position of the object under the cursor either to the debugger or add a text object. You could also display the boundingBoxLeft values under the cursor. It just looks like it’s getting snagged. Maybe, it’s a bug. Maybe they’re out of alignment. That could also be a bug.

@Keith_1357 The squares are part of a tilemap. The tiles in question are all 32x32 big and were placed on a 32x32 grid (Tiled automatically places them on a grid), so there is no chance one of them was placed one pixel to the left or something like that. I am pretty positive this is a bug, but I am unsure if it is on GDevelop’s or on Tiled’s side. As I said I have found forums entries for other engines complaining about a similar issue when using Tiled, so it could very well be a Tiled bug that has to be circumvented by smart use of events.

1 Like

I have very convoluted work around

You could make 4 points OUTSIDE of your player collision mask
Each for different direction

Now you check if point is inside object which you check collision for

And on top of that you check which buttons are pressed

So if point right from your players collision mask is inside object with which you are colliding
W and D keys are pressed

In action you move your player UP instead of UP RIGHT
This way you disable D (right key) from pushing your player to object collision mask
And you can freely walk up

Now convoluted part
Do it for each possible direction for each possible key combination
And manage disabling enabling keys per condition
Using remap for topdown behavior is the key here for success
But i guess even so it will take A LOT of work to be perfect
You will do it only ONCE
And once you have it done you will never need to touch it again

From what I have found online, this is a known bug that sometimes happens with Tiled hitboxes across many engines. Unity for example has a Composite function to fix this, but I haven’t found anything for GDevelop so far. That’s why I think a small repositioning function might be the easiest solution.

The Top-down corner sliding extension you mention earlier solves this for Sprite objects.
Tilemap collision mask objects didn’t exist when I wrote this extension. I guess it could be improved to handle them, but I don’t know when I’ll have the time to do it (I have a lot of extensions in my todo list).

Corner sliding is a lot more complicated than it looks. The extension handles this:

  • Inertia is handled to make sharp turn on corners without any speed loss
  • Players are not be blocked by pass-way of their exact size
  • Players don’t slide if the detour is greater than the hole depth (so it doesn’t look silly)
  • and a lot of other tricky cases that I don’t have in mind.

I guess the best workaround is to put hidden sprites manually for collisions and use the extension.

1 Like

@ZeroX4 Thank you for the suggestion, I think it can be simplified a bit by using raycasting instead of the 4 points. Maybe I will try to set it up.

@davy Thanks for the explanation. I’m looking forward to your future extensions and maybe the update to the corner sliding extension :slight_smile: