This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Collision: Preventing it VS. Fixing it when it happens

Collision: Preventing it VS. Fixing it when it happens
by on (#224693)
Hi.

I was wondering. Some games like Mario pushes the player out of the wall when they detect that he's inside it (afaik). I would be more tempted to prevent the collision in the first place.

What are the pros and cons of both options?

Seems like for a simpler (less physics-based game) prevent collision from even happening might be doable. But it might get crazy for a platformer where the character is constantly being pushed around.

Thanks!

-Mat
Re: Collision: Preventing it VS. Fixing it when it happens
by on (#224696)
Mario usually does prevent you from being inside the wall. At least, with most straight-on collisions, it does this. Landing on the ground, running directly into a pipe, etc.

Mario also has a contingency for if you happen to get inside a wall (by various ways). In a lot of games it's hard to avoid there being some situations where you can get pushed into a wall. Physics design is complicated, and it's usually not a good idea to assume you can "guarantee" this will never happen. There should be some way to deal with what happens when you're unexpectedly inside a wall.

SMB1 mario also treats corners of blocks as "soft" in some situations, like jumping into a block from underneath. If you're not too far past the corner it will gradually push you out and let you ascend easily. This is intentional to make it easier to jump up around/between things.

Then there's the case where you're just completely inside a wall... it pushes you to the right to get you out.

So... this is really a combination of a couple of different things. Not an either/or decision. You might also know that SMB1's physics engine is full of very exploitable flaws around this kinda stuff, which are easily exposed by romhacks, or maybe by TAS/etc., but were for the most part carefully avoided by the game's level design... it's extremely hard to make it bulletproof, but you can try to avoid the bad situations by not placing them in your game.


There's other ways to deal with being stuck inside things. Games that assume it never happens tend to leave you completely stuck inside that wall and probably have to reset the game (e.g. Battletoads?). In my most recent game, there was a natural consequence of the way I implemented collision that if you're inside something, trying to move will push you out against the direction you're trying to move (so if stuck in a wall, pressing left will move you right).
Re: Collision: Preventing it VS. Fixing it when it happens
by on (#224698)
Thanks man, that makes a lot of sense!

-Mat
Re: Collision: Preventing it VS. Fixing it when it happens
by on (#224702)
bleubleu wrote:
I was wondering. Some games like Mario pushes the player out of the wall when they detect that he's inside it (afaik). I would be more tempted to prevent the collision in the first place.

Being inside a wall is just a state that you detect and fix as part of the movement logic, before you process any other objects or draw any sprites, so it's not something noticeable by any other game entities or people playing the game. When you detect an invalid position, you fix it immediately, so it doesn't cause any undesirable side effects.

You could just as well calculate the new position to a different set of temporary variables and verify the validity of those before actually updating an object's coordinates, so you'd technically never put an object inside a wall, but that's just an implementation detail that will require extra variables and the final outcome will be exactly the same.
Re: Collision: Preventing it VS. Fixing it when it happens
by on (#224724)
Prevention has a flaw.

If A and B are both moving to a point where they will collide if they are both there.
Either you check A and then say A is allowed to move there and hence move it. Then Check B and say No B you can't move there. Which might be or might not be what you want.
Or you check A and say yes it can move, check B and say yes it can move, then move both and suddenly the intersect.

Imagine A is the player and B is a moving platform.

So if you check and move A, then check and move B. The player gets shunted into the platform.
If you check A and B, then move A and B. The player might fall through the platform as the platform is no longer where the layer is standing.

Basically no gameplay will allow for you to do just either, you need to customise the order and methods used for each piece of the game. Unless you have floating points, SIMD and can afford to move things back along penetration vectors and even then we have all seen enough games where that goes wrong ;)
Re: Collision: Preventing it VS. Fixing it when it happens
by on (#224725)
Back when i hacked metroid to learn the ropes (2013-14) of level design in particular, i was thrilled to discover that it actually works on an 8x8 pixel fidelity. But you don't see this in the level design, which is always 16x16 blocks (with the exception of the chozo statue, iirc). Note that this has little to do with the attribute grid since metroid is just using colour 0 for the far background field. There is one case where the 8x8 fidelity doesn't work flawlessly: If samus is in morph-ball mode, and there is a ceiling right on top of the ball, and that ceiling is only 8 pixels thick, she will be able to un-morph through that ceiling and jump through it. I discovered that this was easily fixed by edititing a single line to no other effect, since that collision check was isolated to the unmorphing event.
Image

I'm not sure what the reason for not having more 8x8 fidelity structures is (no real change in size, except you might be tempted to have more structures.. and which you could have since there was a little bit of spare space left in that segment), but if the unmorphing bug was a reason, it'd be simpler to just fix it.

Then of course you have the sequence breaking exploit with the closing doors, which surely wasn't intended.

In Project Blue, we prevent the player from getting stuck in a wall if being transported into it by a transporting tile (conveyor belts or water streams). So no solid can be touching a transporter tile in the direction of transportation. It works okay in level 1-A and 1-B. In level 3-A and 3-B, you have the situation where i *want* a solid to meet the flow of water. This was fixed by making a lookalike tile of the flowing water that didn't have the transporting attribute set, so the player will stop being transported on the last running water tile that meets a solid. It's not as perfect as having code that can handle all these situations, but it works well enough.
Re: Collision: Preventing it VS. Fixing it when it happens
by on (#224731)
Something no one's mentioned. Mario can change size. You could (in theory) be under a 1 tile tall corridor as small mario, and get hit by a mushroom. The game could force you to crouch, and then you have to jump a lot (and I mean a lot) to get out.

I do think soft collisions vs preventing collisions was a choice, and I think Mario's ability to change size on a whim was a large part of the choice. (Crouch/uncrouch, getting hit while bit, getting a mushroom while small.)

Indivisible has soft nudging corners, but also prevents collisions. It was easier to get away with because her box basically never changes size.
Re: Collision: Preventing it VS. Fixing it when it happens
by on (#224732)
Similarily but differently, if you do get stuck in a block in metroid, you're locked on the x position but can jump through. This prevents the player from getting stuck in respawnable blocks, but also allows for the closing door exploit. And is half of the hidden/prevented bug i detailed above.