Collision ignoring corners

147 views
Skip to first unread message

Alexandre Freitas Caetano

unread,
Feb 6, 2015, 7:22:18 AM2/6/15
to mel...@googlegroups.com
Hi, guys, me again.

I noticed a difference in how melonJS handles the collision for objects and the old tile-based one.

On my last topic I was wondering some way to use the tile-based collision on my server, and the object collision on my client.
(It took so long until I had time to do this upgrade, that's why I'm only posting this now :/)

I did manage to use both the tile and object layers as collision for server and client, respectively, by doing this on TileD:

* Blue is for object collision layer, and the meta-tile for tile-based.


But then, there's one little difference between them. Using the object layer collision, it kinda "ignores" the edges if you keep on accelerating the player towards that edge. So my server and client positions get insanely different and then the server sends the player back to where it belongs server-sided, which causes this:

* It is caused by server correcting client's position after the prediction was done. Anyway, no need to go further than that on networking theories.




Below I'll show two examples, on how the SERVER behaves and how the CLIENT behaves at the same time.

EXAMPLE 01 - TILE-BASED COLLISION BEHAVIOR (SERVER BEHAVIOR)  

Player's shape hit the very edge of the solid tile, it does NOT pass.


EXAMPLE 02 - OBJECT-BASED COLLISION BEHAVIOR (CLIENT BEHAVIOR)

Player's shape hits the edge of the solid object and then passes it.


So, my question is: 

How can I force Object Collision on client (EXAMPLE 02) to behave just like Tile Collision on server (EXAMPLE 01), and why does object collision ignore those corners?

Aaron McLeod

unread,
Feb 6, 2015, 9:36:52 AM2/6/15
to mel...@googlegroups.com
Ah sorry just saw this one. Ignore part of my reply to the other post :).

I am still curious to see how your player is handling the collision response. Are you using the same code on the client & on the server for the collision?

--
You received this message because you are subscribed to the Google Groups "melonJS - A lightweight HTML5 game engine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to melonjs+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Alexandre Freitas Caetano

unread,
Feb 6, 2015, 11:16:52 AM2/6/15
to mel...@googlegroups.com
Hi, Aaron!

I'm using a tile-based collision on my server, and for the client I'm using the Object-based collision. My server uses the same collision check for world collision as melonJS 1.1 did!
The reason why I don't change my server's collision handler to something like melonJS 2.0.x is mostly because the tile-based collision checker is way lighter for the server. And the lighter the better, since nodeJS is limited to use only one thread.

Using the solution you guys gave me on my last post, I managed to emulate a tile-based collision on my client. The only exception are those damn corners >_<

I came up with this solution so far, for my problem:
onCollision: function(response, other) {
var cachedPos = this.cached_pos[this.actions-1] || this.spawn;
if(other.body.collisionType == me.collision.types.WORLD_SHAPE) {
if( (Math.abs(this.body.vel.x)==0 && Math.abs(response.overlapV.x)>0) ||
(Math.abs(this.body.vel.y)==0 && Math.abs(response.overlapV.y)>0)) {
this.pos.x = cachedPos.x;
this.pos.y = cachedPos.y;
this.updateBounds();
return false;
}
}
   return true;
}

This does work, but the real problem comes when the collision objects must have the EXACT SAME width and height as the meta-tiles for collision.
Still doesn't solve the best way for me. 

I'm guessing I might need to add SAT collisions on my server OR perhaps make a plugin for melonJS 2.0 to force the usage of the old tile collision.

I'll start off trying the plugin, which is easier.

Aaron McLeod

unread,
Feb 6, 2015, 11:22:55 AM2/6/15
to mel...@googlegroups.com
With the shape collision, if you replace every solid tile with a square, you will run into issue as you cross over tile edges. It's just an inherit problem with SAT. It's why you want to use a single block to represent a set of collision tiles.  Basically use as few objects as possible of convex shapes.

SAT should be faster than single tiles if you have a lot of them though. Really comes down to how big your maps are :)

Alexandre Freitas Caetano

unread,
Feb 6, 2015, 11:32:34 AM2/6/15
to mel...@googlegroups.com
Unfortunately, using SAT on client isn't my best option ATM.

See, since I make a collision map Matrix on my server, I can pinpoint the exact location of the player in that map, and then check only the array values that are elligible for a collision.
If I used QuadTree (which I use for npc-player collisions on server-side) I'd have more checks than I really have using my matrix :/

The best solution for me is going legacy-style for world shape collision, I think!
Even if there's the slightest chance to unsync the character position from client to server (cause of those edges problem on SAT), players will be able to see the character jumping from one point to the other so server corrects client. 
It looks like bad programming for a common user, and they might consider it a bug.

So, for MY implementation, legacy collision handler would be the best.

I'm developing a plugin to patch entity's onCollision function. 
I can share, but I don't think people will be needing to downgrade their collision handlers except for very rare cases like mine.

Anyway, thanks for doing such a great work on melonJS and helping so much here in this forum! :)

Alexandre Freitas Caetano

unread,
Feb 6, 2015, 1:23:39 PM2/6/15
to mel...@googlegroups.com
Hey!

I just finished the plugin I talked about :)

It works just the way I intended and now there are no more problems with server-client sync!

I made it so anyone can use. It works like this:

  • Plugin is loaded:
    • Plugin checks if there's a tile layer with "collision" as its name
    • If there is, it sets its layer opacity to 0, so it doesn't show on screen
    • Then it uses legacy-style SOLID ONLY collision only for Map collisions
    • Entity collisions stay the same, using melonJS 2.0 SAT algorithm

I'd like to know if you guys want me to share the code, or if it's not necessary at all! Just in case there are people around here that need the legacy collision style!

Thanks for the tips and fast answers guys! You guys rock! :)

Jay Oster

unread,
Feb 6, 2015, 2:50:29 PM2/6/15
to mel...@googlegroups.com
Hi Alexandre! I'm coming late to the thread, but thanks for the contribution.

A few things I would like to point out: The original AABB-collision handling works very well for large grid cells, but provides very rough (large square) collision shapes. It can be described as "inaccurate" for representing organic shapes. On the other hand, SAT allows for pixel-perfect collision detection, and when combined with a QuadTree or SpacialHash (the latter is more easily customized for maps of different sizes) the collision detection runs at roughly the same speed. The breakdown is something like this:
  • AABB collision detection: fast and inaccurate
  • SAT collision detection: fast and very accurate

The good news is that it was actually pretty easy to rip out the AABB collision detection in melonJS and replace it with SAT. As I recall it took at most three days for two of us working together to get the baseline Platformer example working reasonably well. There was a few weeks of additional tuning involved. But then again, all of the code is available for use in your server today.

You might not think that accurate collision detection is important, but once you try it out, you will probably not want to go back to ol' blocky mode! For example, the grey column  on the left side of your screenshots should have a circle at its base instead of a square! The player entity should also be a circle; that way player entities will move smoothly around obstacles like the column. Getting caught on a "corner" of a cylinder is weird and unnatural. :) This is what I mean by using the term "inaccurate" to describe AABB collision detection. I used a circle for my player entity in my first melonJS game. Give it a try and see if accurate collision detection might make your game "feel" better: http://parasyte.github.io/nm-prototype

By the way, I provided a detailed description of the collision response mechanics in another thread: https://groups.google.com/d/msg/melonjs/fSvQ728YYW8/BfABpcwJZsAJ The "shorted depth" that I describe explains why bumping corners pushes the entity away from it in a direction perpendicular to its momentum.

Kas

unread,
Feb 13, 2015, 1:48:01 AM2/13/15
to mel...@googlegroups.com
I'm having some related issues that I'm trying to work out.

I believe this first one was an issue with the old collision code as well, or at least it behaved simularly; When an entity is jumping and clips an upper corner of a collision box, it's catapulted upwards.  It even seems to ignore the code that I have that tells it to set Y movement to 0 when you let go of the jump key.  It still does the push to the side on hitting a corner though.

Secondly, the push to the side for hitting a corner.  This is more jarring on a platformer than it is on the overhead, and I'm not sure what to do about it.  "Simply" reimplementing the tile based collisions isn't much of an option, since I'm using moving platforms.  Yeah, I know.  This IS the exact same issue that Alexandre was having, but I'm having trouble figuring out how to deal with it in my case.

Thirdly, when you are falling against a block and your entities upper corner collides with the lower corner of the block, it resets your y movement back to 0 (as if you bumped your head on the bottom)

And finally, on a slightly different topic, when you jump and hit the bottom of an object, you have a moment where you are neither jumping or falling.  That one isn't as much trouble, but it adds some extra annoyance to logic when the apex of your jump registers the same as if you were on the ground.


Jay Oster

unread,
Feb 13, 2015, 3:34:54 AM2/13/15
to mel...@googlegroups.com
The catapulting effect is the oldest open ticket: https://github.com/melonjs/melonJS/issues/16 There are ways to fix it, for example computing collisions against the range of motion for an entity, instead of just its new position after velocity is applied. This is described in detail in https://github.com/melonjs/melonJS/issues/103

Kas, if you read the other thread, it describes how the collision responses can be altered to do things like prevent "corner bumping" ... you just need an additional layer of logic around detecting the direction of motion compared to how much contact is being made in the collision, and correct for SAT's  inaccurate "shortest depth" heuristic.

The third one is the well-documented issue of resolving collisions against internal edges. Here's some additional information on this: https://groups.google.com/d/msg/melonjs/_bvI0Ksc04U/DsrKHWpl_MMJ

The fourth is perhaps easy to fix; you can set the falling flag in your collision handler if the collision response vector is going to correct the position downward. (response.overlapV.y < 0) The jumping/falling flags are only set when velocity is applied to a body, which happens independently of collision response handling. There is a good argument for making this behavior default, however! Try it out, and let us know how it works for you.

Kas

unread,
Mar 13, 2015, 12:22:55 AM3/13/15
to mel...@googlegroups.com
Whew.  Busy couple weeks.  Haven't had much time to work on most of this.  What I did poke at was the fourth bit, and it seems that it's not as easy of a fix as it seemed.  Something is overriding it.  I've tricked it into working properly with a little variable shellgame, but it should probably at least be default to let you override it via collision.

Kas

unread,
Mar 13, 2015, 5:22:04 AM3/13/15
to mel...@googlegroups.com
...that last part ended up sounding judgemental.  Oops.  Was meant to be joking XP

Jay Oster

unread,
Mar 13, 2015, 7:41:16 PM3/13/15
to mel...@googlegroups.com
:D

The funny thing is that I agree, it should probably be handled better by the framework. If you can get a working patch and submit a pull-request, one of us will look it over and try to get it accepted for the next major release.
Reply all
Reply to author
Forward
0 new messages