Most
programming-time on this project, disappears into improving graphics, making
the editor a better man, or fixing bugs. Although engines, programming
techniques and strategies get better and more robust every time you try, stuff
still feels like a Jenga brick tower sometimes. Shove a new shader in here, and
crap falls out at the other side - without you noticing until a week later,
then wondering what the hell happened.
But I
shouldn't forget, that we're making a game here. Or trying to at least. Making
something you and me can *play*. So, once in a while, I step away from graphics
and dive into game mechanics. A whole different area, I must say. Whatever game
you're planning, the fun part is probably making your foes even smarter, designing
puzzles, tweaking guns, testing what happens if you drive that race-car into
garbage cans, et cetera. But... you're too far ahead maybe. Because a game
begins with decent controls & basic physics.
Sure
thing doc. But you know what? Making them Right, is pretty damn hard! Even if
you have a proper physics library. Certainly because game-control-mechanics
often have to cheat, overruling standard physics, collision and gravity rules,
rather than using them. Getting a box tumbling down the stairs isn’t too hard.
But getting a 200 pound guy moving upstairs is. It will bump, get stuck,
rocket-jump into the sky, or more likely; stick on the ground like an Easter
Island head.
Shoe
laces thight
I take
good controls for granted, 99% of the games have them right more or less,
nowadays. Though the foul memoires of broken games haven’t faded completely. How
many platform games fucked up, 30 years ago? Games didn't have too many
problems stealing the ideas and visuals of Mario Bros. But copying the controls
and mechanics was a whole different league. The player character being too
fast, as if feeding an ADHD kid 200 red M&M's, six cola, and a line of
speed before going to mcDonalds. Controls too slippery, as if ice-skating on
olive oil the whole time. Too stiff, as if moving a 1 ton statue with the
friction of a Thwomp. Too artificial, as if moving a rectangular sprite in
horizontal or vertical patterns over the screen. Too sluggish, as in having a
jump-button, but Arnold Schwarzenegger being too old to jump over a 30 cm
obstacle, making it useless. Too unrealistic, as in total absence of any
physical rules. Too realistic, as in having no control at all once you're airborne,
realising you miscalculated the jump and heading into the abyss imminent.
Many old
platform games failed miserably, because of unbalanced controls, or a
level-design with impossible jumps. Or both. And not to mention the weird bugs.
One thing I hated, was sprite-physics-anorexia. What I mean is that, even though
the player sprite is 1 meter wide, its collision hull (an invisible shape used
to test if it hits another shape) seems to be much thinner. Your feet would
land on the edge of a platform, yet you would still fall down because the
hitbox of your player missed the jump. It sucked, it seemed relative easy to
fix, yet dozens of games screwed up. Also the opposite happened. A bumblebee
would fly one feet over your head, yet still kill the player instantly because
its oversized hitbox caught it.
Why L ?!! Well, I can tell you why.
Again, because making physics is hard-core stuff, even for a platform game. I
can tell, because I had the same weird shit in my 2D-hobby-games, where players
would end up in the middle of the wall, raising upwards, straight out of the
television. Detecting a "hit" isn't too bad (in 2D), but deciding
what to do next, and making a 100% waterproof system is. Velocities, bouncing
off, material frictions, taking the angles into account properly, and a big
dose of magic numbers.
Having a built-in jump-tester in the level editors would have saved dozens of broken joysticks and frustrated crying kids. But probably a lot of those shitty games didn't even have visual editors back then.
3D
Crapdoll physics
The big transfer to 3D didn't really help either.
Although a game like -of course- Mario 64 did remarkably well for one of the first
serious 3D platform games with advanced moves, I couldn't count the number of awkward
stunts on a hundred hands. Soldiers would drop through the deck of a moving
boat, sink like a brick to the ocean bottom, then warp high into the sky to
fall down to their deaths eventually (yes, I'm talking about Hidden &
Dangerous here). Ragdolls would start spinning up to hyper speed, tearing their limbs apart, because they
got hit by a closing door. Dead guys float in the air until I touch them with a
fingertip, as they finally drop peacefully straight down (Fallout 4 + plenty of
other modern games). Wrecked
cars being launched to the moon after hitting that wall at the G-spot (GTA). Getting
your head stuck through a wall, horrible clunky vehicle steering, flying in
Limbo, …
Should I go on? Yeah, why not. Giant dinosaurs worming through a 2 meter
radius cave portal. Player not being able to proceed because required object
used as a step-up fell through
the floor. Tough action hero’s that would drown instantly
once being in 40 centimetres deep water. Cannot reach key of dead guard as his
ass lays half inside a concrete wall. Being able to disable gravity and
collisions by taking a wrong step somewhere in the corner of a map. Not able to
get off the sofa after jumping on it because the ceiling is too low (Tower22).
The list is endless, and if you look on Youtube, you quickly waste another few
hours on watching this kind of stuff. Sometimes it works out well, like the
Quake1 Rocket-jump ability, or having fun with flying cars in GTA. But most of
the time it’s just, well... stupid.
That looks... painful. I think.
And at
this point, T22 is still tormented with the same kind of bugs as well. But not
the funny type of glitches. More the types where you want to smack the keyboard
through a door, and decide to become a garbage man instead of a game-programmer
for the rest of your life. As you may
know, Engine22/Tower22 uses "Newton" (not the guy, the code library) physics
as a base layer. I'm not too sure about recent trends -to me it seems physics
engines are a bit out of development last years-, but it’s free, and Newton was
said to be quite accurate. Accurate my ass, when that stupid ball falls right
through the floor again. Probably my fault somehow, though I often really can't
explain the quirks. It works, works, works, then it suddenly goes wrong.
Role of a physics engine
Tower22
won't be a Prince of Persia game where you can climb walls upside down, take
long jumps, or have to balance on ropes while riding the back of a tiger. But
for starters, it would be nice if you can just walk in a straight line, rather than
a drunk hobo who gets stuck behind doorsill.
Problem
with game-physics, is that it's sort of a hack. Like with graphics, we'd like
to found our physics on, well, real physics laws instead of (much simpler)
programming abracadabra. Which is a good thing, but also complicates the
situation at the same time. Rotating and moving an object forward with pure
vector math is easy peasy. But the physics engine won't agree to do so, as your
(player)object has friction with the floor, wants to spin like a vertical
rolling-pin while
sliding along a wall, get stuck in narrow passages, bounces you back when
hitting an object, et cetera. Which is terribly annoying, because you're the
MAN with the Controls. IF I say LEFT, go LEFT dammit.
But, if
physics engines are so realistic... what exactly is the problem then? I mean,
unless being on ice or having an epileptic seizure, you're in control. You stop
when you want to stop, you can manoeuvre through a crowd without bouncing in
the air, you can climb stairs and do a handstand while taking a piss, drunk. So
again, the realistic physics engine can manage that for you
as well, right?
No, it
doesn't. Physics engines typically do 4 or 5 things:
- Collision detection between primitives (spheres, cubes, cylinders,..), convex-hulls, and triangles (the world). Highly optimized, because doing this requires horsepower.
- Collision response (friction between 2 surfaces, bouncing off, E=MC^2, ...)
- Joint physics (ball & chain, hinge door, but also a ragdoll is basically a string puppet made of lots of primitives and joints)
- Apply forces on bodies (gravity, spin, torque, movement, custom forces)
- Special types like Fluids, Buoyancy or Cloth physics
Which
covers a big important deal, but not everything. Player-physics for example are
a black-art. Humans aren't boxes or capsules flying into all directions when
you hit them. Or well, if a cement truck hits... Yet physics engines treat us
just like that. Because *REAL* physics would be way too complex.
Obviously
walking in real life isn't a matter of pushing us human-shapes forward. It's
more a controlled form of tumbling forward, step by step. Push up, tilt
forward, fall on the other foot. And repeat. No miracle it takes a baby some
time to practice on his two legs (though I sometimes whish our youngest son
never had legs, now that he learned how to climb onto practical everything).
It's so difficult that God or Evolution gave most animals 4 or more legs, for
Pete's sake. It's so difficult that hordes of scientists spend billions of
dollars and hours into making robots that can do nothing but climbing stairs.
So
having true human movement kinematics into games... better not. Even if it was
available, it would probably beat the hell out the CPU. And then we have an
alien character with 3 legs, or a crippled guy that walks on his hands... Got
to start all over again. Just no. What we do have, is
either
old fashioned homebrew fake-physics that are guaranteed to generate amazing
stunts, or use the tools we get from a physics engine. Usually we do a hybrid;
special rules for players, yet using an existing physics engine so it
integrates with the other stuff in the game. Meaning it will bounce away a box
if it was in your way, and meaning you can benefit from the same optimized collision
detection systems.
Even the ED-209 hates stairs.
Jalapeno
on a stick
Until recently,
the Tower22 player was really just a capsule. On a stick. The tiny stick (cube)
did some special stair stuff, and the somewhat wider capsule does the collision
detection with other objects and of course the environment. Fortunately you
can't see it (physic collision hulls are always invisible, the 3D mesh does not
represent the actual physics shape), but man, it's a ridiculous model. Imagine
everyone on street would look like Jalapeno on a stick, sliding forward by some
invisible force. Because that is what happens, we push that thing forward, and
use an up-constraint to prevent it from tumbling over. Like an invisible rope
in the air that keeps us up.
Biggest
problem is the sliding / pushing forward thing. What happens if you push a 80
kilogram washing-machine-box forward? Probably nothing, because it's fucking
heavy. If you smear green soap on the floor, it may work though. So let's say
we have green soap all over the place. Yeah, we're sliding now! Smooth as air-hockey!
But crap, there is a little stump on the floor. Even though its 1 cm tall, it’s
enough to block. Push harder, and the box tumbles, you landing on top. This is
why a capsule-shape may work better, thanks to the rounding at the bottom, it
has minimal contact with the ground, and it can lift up itself gradually. Over
small obstacles at least. A 35 cm stair-step is either impossible, or requires
an incredible amount of force. Increasing force is easy enough in a computer
simulation, but hold your horses! Don't forget we also need to stop almost immediately
when we release the forward button.
Oh dear, stairs. In the past that would mean you had to take 10 steps back, then charge like a raging bull, hoping your momentum would be enough to bring you upstairs.
Controlling
the player like this, feels like manoeuvring the Bismarck. There is no direct
control over it, you're at the mercy of physics. Which is exactly NOT what you
want. I don't know how people do it in other physics engines, but Newton offers
a bunch of "overrides", sort of. Rather than rocket-fueling force
into the rear of my player, I can set its velocity. Sort of a PID-control will
monitor the velocity and
eventually correct it every cycle, in case it drifts off. Same stuff for
controlling the spin force. If I say the player should be rotated 270 degrees, he'd
better listen. The rotation is measured and guarded every cycle, meaning a
correction spin will be applied as soon as the physics engine thinks otherwise
(for example, when the player hits or gets hit by something). It works, but be
careful that in some situation, you actually want the environment to have
effect on our player. Well. Magical rules, overrides, different states... code
quickly gets dirty for sure.
Scanning,
Scanning, Error.
I didn't
mention the stairs yet. The horror. As I tried to explain, we basically just
push stuff forwards. But that's not how a human being climbs stairs! Lift a leg, place
it one step higher, pull up. Well, we can't really simulate that with a stupid
capsule on a stick. But we have some more David Copperfield magic up on our
sleeves. If we can set forward-velocity, we can also set upward velocity.
Obstacle in front of us? Add some "lift". Problem solved? Of course
not.
How do
hell do you know if there is an obstacle in front of you? And then I mean an
obstacle you can pass, not a wall. Otherwise you would slowly lift yourself
over the Chinese Wall, that's not how it should work. The player should scan
its surroundings. For example, fire a ray forward from your toes, to see if
there is something in front. If so, this *might* indicate a stair. But before
rocketing up, do a second
scan at balls-height. Still an obstacle? Then you can't simply step over it.
You may need to leap over, if that's allowed in your game. But just sending some
rays forward (like I did earlier) is prone to fail. Take a look at this
picture:
That's a
classy stair right? "Thanks" to its open gaps, my toe-sensors don't sense shit.
So, no obstacle, no lifting. In other words, we're stuck. But wait a minute,
there a are a billion other scenario's that can fool you. What if we were to
climb to stairs while strafing or walking reverse? Toe-sensors have to measure
into another direction, or it still fails. And what if we see the stairstep, but
miss a metal pipe in front of our head? Head-bang. The most annoying are tiny
obstacles (less than a CM tall), like rubble. Your sensor-rays may fly over
them, but they are enough to stop or at least slow you down.
Scanning
is one way to make decisions, but do not rely on a few rays only. Fortunately
Newton provides convex-raycasting (like sending out a thicker volume, rather
than a thin ray) which already does a better job, as it less likely slips
through narrow holes or gaps. But a very different approach, is to simply
flatten the stairs. And I'm quite sure older games did that a lot, and maybe even
modern games still do so. In fact, due polygon limitations, old games actually
had diagonal ramps rather than real block-shaped stairs. Yet, it feels a bit
fake, as the player doesn't "hop up". Also the animation should
change; you climb a stair, not run it. Idiot.
Looks like stairseps right? But look again, carefully at the edges. It's just a flat ramped polygon with a stairstep texture on it.
A third
thing you can do, is making hints, or a context. And this sounds pretty
logical. You could mark every "shape" as "floor",
"wall", "ramp" or "stair". You decide what can be
climbed, and what not. This at least avoids an automated scan to make mistakes,
trying to climb stuff that shouldn't be. It also allows to make the player
aware of more advanced manoeuvres on its path. Like "ladder",
"rope" or "passable for AI only". Giving hints for players
and NPC's. You would still have to scan forward, and as said, the level
designer shouldn't forget to mark everything properly.
Yet at
the same time, it feels as if this shouldn't be necessary. Can't remember
having to do this for every possible obstacle in the Duke Nukem or Half life
level editors. Also games with dynamic environments that can be altered by
building or destructing stuff, probably don't have to mark everything.
Obviously it would be nicer if the player-physics can figure out what to
without hints.
So. How DID we do it?
As usual,
I’m very good at showing a hundred and one failure situations. But more interesting,
where is the cure? Well, I wasn’t exactly Newton’s best student back at school.
Then again, as said, player physics is more about hacks anyway. In fact, the
code is so… if there were Burqa’s for programming-code, this piece should definitely
wear one. It’s the type of stuff you’re ashamed of. It’s not founded on
rock-solid, robust, proven methods. But on numbers, case specific approaches,
and cheap tricks. It feels as if it can collapse any moment. But reading
Google, it seems this “Black Magic Code” just happens to be the norm. Okay… If
you say so.
- Skinny Capsule
So, first of all, I replaced “Jalapeno on a stick” with Jalapeno only; a Capsule. A relative thin capsule I must add, otherwise you’ll find your ass getting stuck in door portals. No Kim Kardashian collision hulls. This capsule has low friction and bounce settings. Basically we want as little contact with the environment as possible.
- PID Controlled Velocity
As explained earlier, rather than just adding force into our desired direction, we measure the actual velocity (and spin), and add more or less if needed. This gives a more stabile speed, at surfaces with different friction settings.
- Hover Shoes
Even
though our capsule makes relative little contact, I still found myself getting
stuck behind 5 millimetre floor height differences. A doorsill would be enough
to keep me outside the room. Like Garlic hanging in front of Dracula’s nose, it
just stopped moving. The solution? Sci-Fi hover shoes. I constantly apply
upward force (or vice-versa, you could disable gravity while standing on the
ground). Just a bit, to lift me off a few millimetres. Be careful not to add
too much, or you will “wobble” like a flying space scooter.
- Convex Cast ahead
No toe
sensors, but we do a downward convex cast slightly ahead into our desired
direction. I'm using a flat disc for this. Now we
can compare our feet level with the obstacle height at the next step. If the
difference is less than a defined “MAX_STEPHEIGHT”, we can engage our shoe
thrusters further, giving upward velocity. Notice we can also do an upward scan. This
is useful to signal NPC’s to start crouching, in case of an obstacle at head-height.
- Downforce
We
talked a lot about climbing stairs. But how about getting down, without flying
through the air? By default, only gravity will pull you down. So you don’t
really step down, you just fall. If you run fast enough, you won’t be touching
the stair-steps at all, losing control while being airborne. What I did, is
reversing my shoe thrusters to “press” you down rapidly. But only if the height
difference isn’t too big. As shown in #4, the down-cast will get below the
player feet. If less than “MAX_STEPHEIGHT”, downforce will be applied. In
essence, it quickens the fall. Be careful not to apply downforce BEFORE you’re
over the ledge, otherwise you get pinned to the ground just before taking a
step down.
- Baywatch
Just keep in mind you may walk through a wall, or fall through the floor for whatever reason. So you'd better have a lifeguard. Make a respawn point, or use some hard boundaries to prevent falling through. If the lowest point in a room is -2,5. then just disable gravity or even push up whenever the player threatens to get below that point. Yes, it's stupid and it shouldn't be necessary. But better safe than sorry.
Does this provide waterproof, fine controls? No, but at least it''s a step into the right direction. And moreover, I just wanted to give you an idea of things *can* be done. I still find myself in odd situations, like getting stuck in corners that are complex geometry-wise. Or flying up onto a steep ramped wall that shouldn't be climbed really. And for some reason I keep falling through that damn floor for no apparent reason. But at least its a lot better already.
No comments:
Post a Comment