Platformer style games progress
by Matt Bates · in Torque Game Builder · 01/11/2007 (1:27 pm) · 20 replies
First I'd like to start off saying that TGB is a really great engine with really awesome tools, I love it.
As with all engines to make it "perfect" for your game you will need to modify it at least a little bit. I'm sure like a lot of people I've been struggling getting even something that works like a platformer going. There are some great posts and tutorials about this topic and the release of 1.1.3 was big help too, but even after all this I'm still stuck with some major issues (getting stuck in the ground, floating, bouncy collisions against walls).
Does anyone have ideas / info on this topic at all?
Any word with the platformer framework that was mentioned a while back either?
As with all engines to make it "perfect" for your game you will need to modify it at least a little bit. I'm sure like a lot of people I've been struggling getting even something that works like a platformer going. There are some great posts and tutorials about this topic and the release of 1.1.3 was big help too, but even after all this I'm still stuck with some major issues (getting stuck in the ground, floating, bouncy collisions against walls).
Does anyone have ideas / info on this topic at all?
Any word with the platformer framework that was mentioned a while back either?
About the author
#2
01/11/2007 (6:34 pm)
The mini platformer tutorial works pretty well but I get stuck in cellings some times and stutter between gaps and the such. I've read through this thread a lot and there doesn't seem to be any definitive solution. All of the above does work but it's a bit hacky and not that expandable.
#3
01/24/2007 (11:48 am)
Weird, the sticking to ceilings still happens? Haven't seen that bug in a while at my workspace.
#4
Hrmfh.
01/24/2007 (12:02 pm)
Yeah, I just re-did it and I'm getting a sticking-to-the-ceiling bug in my own game again. I was very dissapointed to see that. I've tweaked with it some and helped to remove some of it, but it's still showing up, even in the latest code from the example and with TGB 1.1.3.Hrmfh.
#5
If you have Pro and don't want to wait for the next release, Melv piosted a fix to the sticky collision issue in this thread.
01/28/2007 (1:58 am)
The sticking-to-surfaces bug has been fixed, as far as I know, and should be in the next TGB release. As for the Platformer Framework, that was a bit of a pet project of mine that had to be put on hiatus to work on a similar project for TorqueX. I plan to resume work on the TGB Platformer Framework once this current project is out the door.If you have Pro and don't want to wait for the next release, Melv piosted a fix to the sticky collision issue in this thread.
#6
Final question: How come a "fix" Melv posted over a year ago isn't in TGB yet? I assume there were more important / desirable things.
01/28/2007 (6:44 am)
I'll have a go with fix Melv put up later on tonight, any idea when the next version of TGB is due-ish? (We all know everyone hates giving out release info). Also what can we expect in the next version fix wise?Final question: How come a "fix" Melv posted over a year ago isn't in TGB yet? I assume there were more important / desirable things.
#8
I'm pretty sure that the only edits of consequence are the if-statements. I changed if (mNotZero(dotVelocityNormal) ) to if ( dotVelocityNormal < 0.0f ), recompiled and everything worked fine. I wasn't experiencing the sticking bug in my test level before either, though.
These two lines seems to be the fix. Makes sense, too. It makes the engine only clamp negative velocities (normalized, I believe this means 'things falling into the collidee'). Thus when we have things attempting to [even slowly] move away from the collision area they won't get 'stuck'.
That about right? Devs?
01/28/2007 (9:55 pm)
I just looked at Melv's code and compared it to the version I have in my code. Here's Melv's Fix reprinted:void t2dPhysics::resolveClampCollision( bool solveSrc, bool solveDst, cCollisionStatus* pCollisionStatus, const U32 contactIndex )
{
// Solve Source?
if ( solveSrc )
{
[b]const t2dVector preVel = pCollisionStatus->mpSrcPhysics->getGrossLinearVelocity();[/b]
// Fetch Linear Velocity / Collision Normal.
t2dVector linearVelocity = pCollisionStatus->mpSrcPhysics->getGrossLinearVelocity();
t2dVector collisionNormal = pCollisionStatus->mCollisionNormal;
// Normalise Collision Normal.
collisionNormal.normalise();
// Calculate Dot Velocity Normal.
const F32 dotVelocityNormal = collisionNormal * linearVelocity;
// Any velocity to clamp?
[b]if ( dotVelocityNormal < 0.0f )[/b]
{
// Set new Linear Velocity.
// NOTE:- vO = vI - ((NvI)N)
pCollisionStatus->mpSrcPhysics->setGrossLinearVelocity( linearVelocity-(collisionNormal*dotVelocityNormal) );
}
}
// Solve Destination?
if ( solveDst )
{
// Fetch Linear Velocity / Collision Normal.
t2dVector linearVelocity = pCollisionStatus->mpDstPhysics->getGrossLinearVelocity();
t2dVector collisionNormal = pCollisionStatus->mCollisionNormal;
// Normalise Collision Normal.
collisionNormal.normalise();
// Calculate Dot Velocity Normal.
const F32 dotVelocityNormal = collisionNormal * linearVelocity;
// Any velocity to clamp?
[b]if ( dotVelocityNormal < 0.0f )[/b]
{
// Set new Linear Velocity.
// NOTE:- vO = vI - ((NvI)N)
pCollisionStatus->mpDstPhysics->setGrossLinearVelocity( linearVelocity-(collisionNormal*dotVelocityNormal) );
}
}
}I bolded the sections that differ from the code in my version (OSX TGB 1.1.2). Also missing is the following two lines at the top of the function:// Flag as handled.
pCollisionStatus->mHandled = true; This seems like a bit of housekeeping code that was added in sometime since the Alpha that Melv's fix applies to.I'm pretty sure that the only edits of consequence are the if-statements. I changed if (mNotZero(dotVelocityNormal) ) to if ( dotVelocityNormal < 0.0f ), recompiled and everything worked fine. I wasn't experiencing the sticking bug in my test level before either, though.
These two lines seems to be the fix. Makes sense, too. It makes the engine only clamp negative velocities (normalized, I believe this means 'things falling into the collidee'). Thus when we have things attempting to [even slowly] move away from the collision area they won't get 'stuck'.
That about right? Devs?
#9
*Edit*
I rebuilt TGB with Melv's fix and it seems like 90% of the problems have gone, I can still ride along a celling now and again but I don't get stuck in it and thats really a trivial problem to fix. Hopefully upon further investigation other problems won't occur.
01/29/2007 (12:36 am)
I haven't got round to adding the fix yet, how much difference does it make scripting wise? i.e. is it just a matter of setting CLAMP and add some gravity or do you have to add in all the script hacks like in previous versions.*Edit*
I rebuilt TGB with Melv's fix and it seems like 90% of the problems have gone, I can still ride along a celling now and again but I don't get stuck in it and thats really a trivial problem to fix. Hopefully upon further investigation other problems won't occur.
#10
01/29/2007 (9:58 am)
This looks great, but is there a solution for the Indie version of TGB? the one that doesnt have the source code?
#11
@Azrael: There's no solution that doesn't involve recompiling the source. That being said, some other people were distributing binaries that they had compiled in another thread (adding, say, 1.1.3 features for the Mac which is still at 1.1.2). Perhaps we could do this for you? Of course you'd have to trust whoever did the compiling...
GG Devs? Is that a violation of the contract?
01/29/2007 (4:06 pm)
@Matt: Sounds like things are starting to look up! I'm not sure how you're "riding on the ceilings" as that's a symptom I've never come across. I did find through some experimentation that if you made sure you had parallel collision polygons on both colliding objects then the sticky bug didn't seem to ever occur. Perhaps you could try that as a mini little hack for a bit. My character's polygon still looks like it has a point until you get really close to it. If you have angled ceilings you could limit them to a specific angle perhaps (at least the collision polygons) and match that to your character... See if that helps.@Azrael: There's no solution that doesn't involve recompiling the source. That being said, some other people were distributing binaries that they had compiled in another thread (adding, say, 1.1.3 features for the Mac which is still at 1.1.2). Perhaps we could do this for you? Of course you'd have to trust whoever did the compiling...
GG Devs? Is that a violation of the contract?
#12
01/30/2007 (4:49 am)
@Eric: I made a design choice a while ago not to have "slopes" in my game, way less problems that way and I might actually finish it too! I haven't encountered the "riding the celling" thing all day I guess it's extremely rare and nothing to worry about. Right now my characters collision poly has all kind of points in it and I haven't found any real problems, and I'm just using a constant force (gravity) with CLAMP for collisions no script hacks at all Yay!!
#13
01/30/2007 (7:53 am)
That's really odd. I have no slopes in my game, my collision poly is all "nice" numbers with perfectly flat edges, and yet I still climb almost any wall I hit and can stick to ceilings with relative ease.
#14
@Clint: The pointy edged polygons are what used to cause people to get stuck in ceilings and such. Wall climbing is from a different issue altogether.
There's code in the MiniPlatformerTutorial that negates that issue. It was added and mostly debugged back in November of '06. As I recall, CLAMP physics mode will stop all velocity in the direction of the collision normal. Thus, if you have a vertical collision while against a vertical wall, the horizontal velocity causing the collision will disappear: it gets CLAMP'ed to zero. The vertical (upward) velocity, however, remains. The climbing occurs because somewhere along the line, the gravity doesn't get calculated in.
My assumption is that there's a point in the physics 'algorithms' where if you're colliding, gravity doesn't get factored in. Something to look into, at least.
The MiniPlatformerTutorial uses cast-collisions to check for collision in the horizontal (X velocity). If there's an imminent collision, the velocity X is CLAMP'ed to zero on the script side. This allows the gravity to work as expected as it bypasses the issue above. Are you using the latest platformer code? If not, I'd recommend that you take a look at the updated code and see if that doesn't help your climbing!
01/30/2007 (3:37 pm)
@Matt: Great to hear about the bug-fix success! Slopes and gaps are a pain because of the 'hopping' issue. I kind of wish there was a "MAGNET" physics mode that would keep the player always connected to the collider. That'd be really useful for a lot of platforming, I feel.@Clint: The pointy edged polygons are what used to cause people to get stuck in ceilings and such. Wall climbing is from a different issue altogether.
There's code in the MiniPlatformerTutorial that negates that issue. It was added and mostly debugged back in November of '06. As I recall, CLAMP physics mode will stop all velocity in the direction of the collision normal. Thus, if you have a vertical collision while against a vertical wall, the horizontal velocity causing the collision will disappear: it gets CLAMP'ed to zero. The vertical (upward) velocity, however, remains. The climbing occurs because somewhere along the line, the gravity doesn't get calculated in.
My assumption is that there's a point in the physics 'algorithms' where if you're colliding, gravity doesn't get factored in. Something to look into, at least.
The MiniPlatformerTutorial uses cast-collisions to check for collision in the horizontal (X velocity). If there's an imminent collision, the velocity X is CLAMP'ed to zero on the script side. This allows the gravity to work as expected as it bypasses the issue above. Are you using the latest platformer code? If not, I'd recommend that you take a look at the updated code and see if that doesn't help your climbing!
#15
Either way, this block in the miniPlatformerTutorial should take care of it (at least as long as all of your walls are perfectly vertical):
01/30/2007 (9:39 pm)
The clamp code seems to work fine. Toss your character into a wall with a constant velocity (without influencing the simulation via keyboard) and you'll see the character react as you expect (specifically not climbing walls or getting stuck). The wall climbing appears to occur because of the scripting code. The source code does things in this order:updateScene()
subUpdateScene()
preIntegrate()
[Here we resolve the constantForce variables]
integrateObject()
[Here we resolve collisions -> constantForce was taken care of in preIntegrate()]
onUpdateScene()
[This is the [i]script function[/i]. Anything we want to insert into the main-loop gets added here.
Nothing is resolved until the next call to updateScene()]Somehow things get all screwy with setting all of the velocities script-side. setLinearVelocityX() not doing what it's supposed to? Or maybe inserting a sudden, artificial velocity into the simulation throws things out of whack...Either way, this block in the miniPlatformerTutorial should take care of it (at least as long as all of your walls are perfectly vertical):
if(%this.airborne)
{
%this.setLinearVelocityY(0);
%collision = %this.castCollision(0.005);
if(%collision !$= "")
%this.setLinearVelocityX(0);
}
#16
The MiniPlatformerTutorial is really just a quick and dirty example and is far from ideal platformer physics. As a bit of a point of reference, in a platformer project I'm currently working on, the Actor class is maybe 4000 lines long and about 1000 of that is just physics. The code isn't particularly long-winded either, there's just a lot to do. Granted, that handles slopes, rotation, inherited velocity, one-way platforms, physics state switching, etc., blah, but a lot of it is just simple movement.
That said, it's perfectly fine for a TGB licensee to use a binary that's been modified and compiled by a Pro licensee.
On this specific problem, the CLAMP bug is a pain, especially for this breed of game, so I know you guys are itching for the fix. My internship had ended just before they put it in, and when I got hired they had just released that version. The first time I ran one of my projects I saw it and I've been whining about it to Justin incessantly since then. Anyway, it's fixed now internally and the next TGB release will have the fix. If you just can't wait, it sounds like someone might be willing to build a version with the bug fixed.
02/01/2007 (7:10 am)
Correct, wall climbing is caused by wrongly detecting that the character is on the ground when they hit a wall and then failing to apply constant force. The MiniPlatformerTutorial is really just a quick and dirty example and is far from ideal platformer physics. As a bit of a point of reference, in a platformer project I'm currently working on, the Actor class is maybe 4000 lines long and about 1000 of that is just physics. The code isn't particularly long-winded either, there's just a lot to do. Granted, that handles slopes, rotation, inherited velocity, one-way platforms, physics state switching, etc., blah, but a lot of it is just simple movement.
That said, it's perfectly fine for a TGB licensee to use a binary that's been modified and compiled by a Pro licensee.
On this specific problem, the CLAMP bug is a pain, especially for this breed of game, so I know you guys are itching for the fix. My internship had ended just before they put it in, and when I got hired they had just released that version. The first time I ran one of my projects I saw it and I've been whining about it to Justin incessantly since then. Anyway, it's fixed now internally and the next TGB release will have the fix. If you just can't wait, it sounds like someone might be willing to build a version with the bug fixed.
#17
1) Is all of that 1000 lines of physics torquescript code?
2) What exactly do you mean by "inherited velocity"?
3) Looking at the new 1.1.3 code, it appears that only one of the two if-statements had the bounds changed to incorporate Melv's fix. The "solveDest" portion still features the old code. Is that correct? Why does it differ for the destination? Doesn't that change the way things work if both source and destination are moving in the same direction? Say the destination object is moving to the right of the screen. The source object is as well but it's moving faster. CLAMP should stick the source object to the destination object (by killing the 'extra' velocity that makes it faster than the destination object). But it appears that the destination object might get it's velocity in the direction of the collision normal completely CLAMP'd, causing it to stop dead. Is that correct? Should the solveDest's if statement be changed to "if ( dotVelocityNormal < 0.0f )" as well?
Of course, for things like walls, the change means nothing as there's no velocity to CLAMP anyway...
02/01/2007 (4:08 pm)
@Thom: A few questions for you:1) Is all of that 1000 lines of physics torquescript code?
2) What exactly do you mean by "inherited velocity"?
3) Looking at the new 1.1.3 code, it appears that only one of the two if-statements had the bounds changed to incorporate Melv's fix. The "solveDest" portion still features the old code. Is that correct? Why does it differ for the destination? Doesn't that change the way things work if both source and destination are moving in the same direction? Say the destination object is moving to the right of the screen. The source object is as well but it's moving faster. CLAMP should stick the source object to the destination object (by killing the 'extra' velocity that makes it faster than the destination object). But it appears that the destination object might get it's velocity in the direction of the collision normal completely CLAMP'd, causing it to stop dead. Is that correct? Should the solveDest's if statement be changed to "if ( dotVelocityNormal < 0.0f )" as well?
Of course, for things like walls, the change means nothing as there's no velocity to CLAMP anyway...
Quote:Correct, wall climbing is caused by wrongly detecting that the character is on the ground when they hit a wall and then failing to apply constant force.4) Is the fix that you mention above a fix for this? Is it separate from Melv's fix outlined above?
#18
1) No, it's C# (shh...)
2) Moving platforms, falling platforms, trampolines, external forces from enemies, etc.
3) Yes, both should have the if (dot < 0) check, and I'm almost positive they do in our version.
4) The fix is exactly #3 (the dot check)
There is another change that could be considered a fix that might also go in, which is actually resolving all overlaps each tick. That may or may not go in, but regardless, the castcollision calls check for walls seperately, so that shouldn't affect the TDN version of the tutorial code.
02/01/2007 (4:24 pm)
@Eric1) No, it's C# (shh...)
2) Moving platforms, falling platforms, trampolines, external forces from enemies, etc.
3) Yes, both should have the if (dot < 0) check, and I'm almost positive they do in our version.
4) The fix is exactly #3 (the dot check)
There is another change that could be considered a fix that might also go in, which is actually resolving all overlaps each tick. That may or may not go in, but regardless, the castcollision calls check for walls seperately, so that shouldn't affect the TDN version of the tutorial code.
#19
1) Ooooohhh... TorqueX... shiny.
2) Ahh, gotcha.
3) That's... weird. I wonder what happened between 1.1.2 and 1.1.3 there. Heh.
4) Okay, cool. Yay CLAMP physics!
Okay, so for now the CastCollision method is the right way to go. I assume that the wall-sticking/slow movement that remains (when holding down a button into a wall, say) is related to the overlaps not getting resolved each tick[?]. That would potentially make sense because you'd get an overlap and then a collision in a vector in which there shouldn't be one...
02/01/2007 (4:54 pm)
@Thom:1) Ooooohhh... TorqueX... shiny.
2) Ahh, gotcha.
3) That's... weird. I wonder what happened between 1.1.2 and 1.1.3 there. Heh.
4) Okay, cool. Yay CLAMP physics!
Okay, so for now the CastCollision method is the right way to go. I assume that the wall-sticking/slow movement that remains (when holding down a button into a wall, say) is related to the overlaps not getting resolved each tick[?]. That would potentially make sense because you'd get an overlap and then a collision in a vector in which there shouldn't be one...
#20
02/02/2007 (8:43 am)
Specifically, the problem caused by not resolving multiple overlaps in a single tick is the jitter when walking continuously into a wall while on the ground. The jitter happens because it alternates between resolving the overlap with the floor and then the overlap with the wall back and forth. If it were to resolve both, there would be no visible jitter when pushing into corners. This is not a bug, it's just a weakness of the current collision implementation which could potentially be upgraded in future releases to make games that require smooth interior corner collisions easier to make (like platformers or top-down dungeon adventures). I'm of the mind that there are enough types of games that would benefit from the upgrade that it would be worth it.
Torque Owner Clint Herron