Robotology: Alchemy

25 Sep / by: M&R / 23 comments /

Losing the first version of this post due to webhosting problems kind of sucked.. it was looooong!

So, let’s see.. what have we been up to?

The lost post concerned all of the stuff we’ve added to the simulator; the two big-ticket items are conveyor-belts and moving platforms — both physics-driven, obviously. We actually ended up implementing both of them twice — once we had everything working the first time, we realized that the way we were modeling motors was totally screwed (it made it impossible to impose force limits on the motors), and so we ended up having to rewrite everything to use the new motor formulation. That was a time-waster.

On the plus side, we ended up also re-designing how constraint geometry (used to describe the belt and path shapes) is represented, and the second time around feels a lot better — for one thing, we can now support paths containing circular arcs! Anyway, conveyor belts and moving platforms work the way we want them to, so hooray.

We also worked out a new approach for friction using the new motors; unfortunately it isn’t working so well, so we’re probably going to revert to using the “old motor” version because it behaved nicely, even if it was “wrong” in terms of physical realism. Hopefully that will be the end of major functionality added to the simulator; stuff that we’ve overlooked will no doubt come up as we implement other parts of the game, and there’s of course about a hundred or more small items on the “to clean-up/maintenance” list, but things are looking pretty good as-is.

 

Post-website-crash, we’ve been working on the player’s “character controller”, which is all the code that describes how movement/etc works. Character control is actually one of the first things we mocked up when we started this project a couple years ago; our experiments used a simple ad-hoc physics model where only the player could move, but they were enough to convince us that what we wanted to achieve would be possible. Now that we’ve got a proper simulation working we’re ready to pick up where we left off and get the same sorts of movements happening in our more-fleshed-out simulation.

At this point it feels a lot like alchemy, in that we’re just brainstorming and trying all sorts of different ideas, hoping to stumble upon the “best” solution. It’s unclear whether or not there’s a better way to approach this — the player’s control logic is pretty much the core of any platformer, and there are an endless number of ways to program any of the various little behavioural nuances. For instance we’ve tried 3 or 4 different ways of limiting the player’s maximum velocity, each of which feels a bit different.

Considering the fact that changing one little piece tends to affect every other part of the damn thing, you quickly end up with an overwhelmingly complicated problem! Hence the sense of alchemy, not unlike blindly groping in the dark for something you think should be in the room.

Quite possibly there are some fundamental gaming principals at work here, but damned if we know what they are! We’re still waiting to read Game Feel 🙂

 

The real fear in trying to juggle all of these interacting minutia is that something important will fall through the cracks and be lost. For instance, a large part of what makes N work is the jumping model.

When you press jump in most platformers, you get something like [velocity.y = 10] — jumping results in the same upward velocity regardless of your current state. One of the first ideas we had was to try [velocity.y += 10], so rather than overriding your current velocity, jumping builds on it. This turned out to suck, because it meant that if you pressed jump while running downhill, you ended up with a very weak, or non-existent jump — your downward velocity would cancel out the jump’s upward velocity. But it suggested the obvious solution, which is what we ended up using: [velocity.y = Max(0, velocity.y) + 10]

So as it turns out, minutia matter. Occasionally, a whole lot.

 

Two things which we’re trying to do differently in Robotology, relative to other platformers, is to make the player’s shape feel “soft”, and to allow the player to move along arbitrarily-oriented surfaces (i.e player orientation is independent of gravity).

Both are things which have been done in more explicitly simulation-based games, like Elasto Mania, Gish, and Loco Roco, but we’re looking to meld that sort of movement and feeling with a more immediate, traditional-platformer type of control.

“Soft” player movement is something we’ve been experimenting with for a long time; one of our first webgame contracts years ago was for a skateboarding game that modeled the player’s internal body movement, with knees which would compress or extend based on the body’s inertia and the slope of the terrain — similar to how automobile suspensions are sometimes simulated. We’re hoping to extend this approach, so that the player can seamlessly move over varying terrain without slowing down or “bumping” into things as a rigid shape might, instead smoothly stepping up onto or over smaller obstacles. In fact, we have a nice prototype of this working, with the caveat that the player’s orientation is fixed “upright” along the world’s y-axis — which brings us to the second problem.

 

In N, as in most platformers, the various types of surface the player can move along are rigidly demarcated: floors are, well, floors; walls are perfectly vertical; and ceilings are anything that’s neither floor nor wall. The player interacts with each of the three discrete surface types in three corresponding ways: running and jumping on floors, walljumpings/wallsliding along walls, and passively colliding with ceilings.

The problem with such an approach is that it precludes allowing the player to run up vertical walls a-la parkour. While some platformers (Sonic, Silhouette Mirage) have allowed the player to run vertically or even along the ceiling, they’ve handled it in a very limited, rigidly-programmed way. We want our player to be able to run and jump along any surface — and any enemy — as if it was “the ground”, blurring the lines between walls, floors, and ceilings. Aside from enabling smoother, more acrobatic movement, this would also make features such as zero-gravity areas, or “magnetic boots” (which we’ve toyed with before in Ultramagnetic, a game which ended up lacklustre and so remains unreleased), trivial to support.

The problem becomes one of determining which direction is “down”, given information about the nearby geometry, the player’s current velocity, keyboard input, FSM state, etc.

Mario Galaxy does feature this sort of “magnetic boot” type behaviour, however the shapes Mario runs along are very “nice” — they tend to be static, convex, smooth, large/flat compared to Mario’s scale, etc — and they get by (as far as we can tell) with the rule “find the point on the world closest to Mario: down is in that direction”. This simple rule doesn’t work in the general case: closest points can jump all over the place, and there can be an arbitrary number of equidistant “closest points”, especially when you have dynamic concave shapes moving around. Most importantly, the shapes in MG are heavily authored and tested, which isn’t a viable solution for user-made or procedural content. Plus, the movement is very “Mario” rather than being based on the same underlying physics simulation as the rest of the game.

 

Anyway, our current problem is that the two behaviours we’re trying to produce — “soft” movement, and movement along arbitrary surfaces — are seemingly at odds with each other! Our prototype for soft movement only works well when the “down” direction is fixed to the world’s y-axis, and our running-up-walls prototype doesn’t like it when the player’s distance from the ground changes (as it is bound to do when the player is given “soft” bendable knees).

It’s quite a conundrum, but we’ve got a few theories; right now we’re working through them, and a few other problems that will be the topic of our next post.. which we’ll hopefully get to soon!

comments ( 23 )

  • nice informative post. 🙂

  • On a somewhat unrelated note, I found this. It’s cool. http://www.essentialmath.com/

  • Keep up the good work, guys. We will support you!

  • Fascinating post! When I was reading through it I immediately thought of the article on how MG did their physics, then I read the part where you had already thought of that. 🙂

    You have probably already considered this approach, but what if instead of considering the normal of the surface closest to the player, you use the normal of the surface that is determined as a function of the player’s position and velocity. This would help to avoid ambiguities in the cases where the player is equidistant from several surfaces. In this case the normal of the surface that the player is “most traveling towards” would be chosen as the surface whose normal to use…if that makes any sense.

    You described the problem in N+ of [velocity = Max(0, velocity) + 10] and this seems like a somewhat similar problem, at a very high level.

  • It’s nice to see you guys are moving forward with this game!

    It sounds like you reached a pretty interesting problem. I’ve actually faced it before but with different character rigs, and I can’t really say I’ve seen any magical solution to it. Each implementation has some ‘rigidity’ to it where the movement looks a bit awkward at certain situations.

    Here’s an idea I had:

    I’m assuming that the player’s character has legs and feet, and that every surface can be walked on.. including possibly a huge dynamic enemy limb (cause that would be awesome).

    So you can take all of the surfaces currently being touched by the ‘feet’ of the character and average out their normal to get the current down vector.

    Now you can physically make the feet stick to any surface they touch via constraints and use the down vector discussed above to keep the rest of the body upright.

    So if for example the character is standing on a straight surface everything would be oriented to that surface. But if one foot is on the floor, and one on the wall, the char’s body would be diagonal, etc…

  • @Owen: the main problem is that a lot of black magic is hidden in the phrase “a function of”! 😉

    @Oz: Yeah, ideally we’re going for something like [Mario Galaxy] + [Shadow of the Colossus].. + [Umihara].

    Thanks for the comments everyone! It’s great to get some outside ideas.

  • [Mario Galaxy] + [Shadow of the Colossus].. + [Umihara].

    admittedly i don’t know of Umihara, but that mix of games has me drooling..

    man, guys, i seriously CANNOT wait!!! i hope you guys don’t let yourselves get too frustrated trying to figure out a solution.

    i know you both have excellent abilities to decide what feels best in a game, so i’m not worried. (that book sounds cool by the way).

    anyways! keep on keeping on!

    P.S. elastomania was awesome.. same with Loco Roco (never heard of gish – i feel lame never knowing the more obscure titles)..

  • If you liked Loco Roco you should really try Gish! I think you can get it on Steam: http://crypticsea.com/gish/

  • Wonderful to hear such detailed, interesting news about Robotology. I mean, it’s good enough to hear that it’s progressing, but the added insight into design ideas is pretty brilliant.

    That’s about it. Keep up the good work! And the informative posts! 🙂

  • Perhaps, for local gravity, you could use a “gravity gradient”. It would hold, per pixel (or maybe undersampled, like every 4 or 9 pixels) a two-dimensional vector which represents which direction is down in that area of the map. It’s sort of like a normal map, but without the Z channel.

    You would precalculate gradient for the static stuff in the map, and then precalculate local gravity maps for moving objects (like enemies) and composite the two every frame to get an overall gravity gradient.

    Then, to find out the current “down”, you just look up the player’s current position in the gradient.

    Admittedly, precalculation is more useful when there are lots of things going to be using the information (That’s why LiquidWar does it), but it was the first idea that came to me without requiring a new data structure to hold the map (also, I don’t know what your map data structure looks like).

  • How does the player control movement along arbitrary surfaces? If up can be down, what direction do I press to go up? Mario Galaxy solves this with an amazing camera.

    I’m guessing the camera might be a hack that solves all your problems. If the camera ensured that the player was always falling down (even though down might be up), perhaps you can implement soft movement with arbitrary surfaces, since they’re not arbitrary relative to the camera.

    Note: I’ve never tried this, and I am probably completley out to lunch 🙂

  • > Perhaps, for local gravity, you could use a “gravity gradient”.

    “Distance Maps” are the same idea, applied to the inside of objects (so that, given a point inside the object, you can quickly lookup the closest point on the surface of the object). Here’s a great recent article on them: http://lab.polygonal.de/2008/07/13/collision-detection-for-particle-systems/

    They’re a really neat idea that we’ve managed to avoid so far, just because they’re unfamiliar and require precalculation which we’d like to keep to a minimum.

    More importantly I don’t know if summing the distance fields of two objects produces a valid distance field which represents the sum of the separate objects.. I suspect that it doesn’t.

    Probably what we need to do is add some logic rather than using a formula, because there are cases which will cause any formula to behave poorly (for instance, if the player is trapped/surrounded by surfaces).

    > I’m guessing the camera might be a hack that solves all your problems

    We tried this with Ultramagnetic — the world/camera rotates a-la Cameltry http://en.wikipedia.org/wiki/Cameltry — but this made us really dizzy/nauseous!

    What would be nice is if we were on a console, we could just use the left thumbstick and have the player run in whatever direction the stick is pressed (so, running up a wall would involve a 1/4 circle movement). Sadly this probably won’t work that well on keyboard.

    Just using left/right is really annoying though, since it creates situations where the player is pressing right but moving left on-screen..

  • “What would be nice is if we were on a console, we could just use the left thumbstick and have the player run in whatever direction the stick is pressed (so, running up a wall would involve a 1/4 circle movement). Sadly this probably won’t work that well on keyboard.”

    robotology on PSN confirmed!! haha… just kidding.

  • One thing we tried with jumping on HoopWorld (which you probably already gave thought to), was making the player’s gravity lower while they HELD the jump button. We only gave a little jump impulse, and let players rise due to low gravity. If they released early, they’d very quickly be brought back down to the ground under normal gravity (and thus be able to re-enact another jump, quickly and responsively… although, ofcourse, we also had an “early jump” check so that you auto jumped if you had re-pressed jump before landing again).

    Anyway, because we were affecting gravity, rather than just setting velocity.z = N while holding jump (as with mario?), it made for a smoother overall jumping arc, but possibly wasn’t as CLEAR an indicator of the behaviour as mario is!

    Sometimes the “cleverer” approach is just obfuscating for a player.

  • > making the player’s gravity lower while they HELD the jump button.

    N works like that too — expert players figured out how to abuse it in weird ways by jumping when wedged into corners, so that they just get the lower-gravity without the upward impulse!

  • All this talk of formulas and logic and programming is doing my head in… but it’s all very interesting. I’m trying to learn programming at the moment (Python), so maybe later on I can come back here and some of this will make a little more sense).
    Anyway, I came across this trailer for a game called Limbo. Very cool 2D platformer:

    http://www.gametrailers.com/player/13937.html

  • Man, this is why I’m glad I’m not a programmer.

    Wait, damnit, I am.

    It’s cool to read about the development process. It’d make it easier to understand if there were something tangible to attach to it. I know it probably looks like crap but to see something tangible would be sweet. Or even maybe waiting until the end and having a series of screencaps to show how the look has evolved from the beginning to the end would be awesome, though it’d be later.

    Also, NEW MAPPACK WHEN IS IT COMING OM NOM NOM NOM

  • We were excited about Limbo when we saw that trailer, but it’s been more than a year and nothing new has been released.. 🙁

    The new levelpack will be out in October! Once we have a firm date we’ll do a post.

  • Oh god… I’m OLD! Not only do I know what Cameltry is, but I played (and finished) it when it was newly released in the ARCADE (remember those)! The home versions, since they lacked a “rotator control / paddle”, eliminated the insane turns the later levels required – talk about confusion.

  • Hey, I have a question.
    Apparently my copy of N+ didn’t get sent to the right address and was returned or something.
    Now what do I do?

    …Also, I’m living in a different house now so it’d be better if it was sent to this address anyway… But who do I contact about that?

  • email metanet AT harveycartel.org with your name, new address, and what version of N+ and we’ll send it to Atari.

  • wow, this sounds complicated. My understanding was that movement would actually be made up of the robot’s legs moving and the forces caused on the ground would make it move (like real walking). Is this the case? because if so I don’t think there’s anything you can do to avoid it feeling like a sim (because it would fall over a lot and the movements would be super precise), and I would think that the whole blurring the walls/floors thing would come as a result of that.

    Personally I don’t think running up walls is actually necessary though. An always-down vertical works fine for N, it just uses a picture of a rotated ninja to make us think it’s actually running across diagonal surfaces or teetering off an edge (I think this is the way it works). A rope will allow the player to move in any way he wants along any surface anyway (I’m a big fan of UK and I’ve learnt to easily rocket-jump across floors, swing across ceilings and bounce up walls), and increasing the focus on the core mechanic (the rope) can only be a good thing.

  • OK, I sent an email…
    Cool post, by the way.

    I am working on a platformer of sorts as well, so it was interesting to read….

    I haven’t been reading your blog for very long; is Robotology going to be freeware or commercial or what?

Leave a reply

Archives