Project Good Robot 2: Welcome to 2D

By Shamus Posted Monday Aug 19, 2013

Filed under: Good Robot 129 comments

So now we’re working in 2 dimensions. The advantage is that 2D development is a lot easier than 3D. The disadvantage is that I don’t have the right tools for the job.

If you’re making a game or some other kind of 3D-rendering type stuff, then you need some basic variables and tools. The first thing you’ll want is some sort of geometric vector. Like, if you’re going to be using x, y, and z values then you probably want some way to bundle them together. With a proper vector toolset we can have this bit of code:

//Get the distance between two points in 3D space
float GetDistance (SomeVector start, SomeVector end)
{
  SomeVector difference;
 
  difference = end - start;
  return difference.Length ();
}

Without a nice suite of vector tools, the same code might look like this:

//Get the distance between two points in 3D space
float GetDistance (float start_x, float start_y, float start_z, 
                   float end_x, float end_y, float end_z)
{
  float   diff_x, diff_y, diff_z;
  float   distance;
 
  diff_x = end_x - start_x;
  diff_y = end_y - start_y;
  diff_z = end_z - start_z;
  return sqrt (diff_x * diff_x + diff_y * diff_y + diff_z * diff_z);
}

This is a simple example, but hopefully even a non-coder can see that the second example is just a bit more verbose and cluttered. This problem is exacerbated once you really get into the tricky stuff. A good set of vector tools will turn half a page of dense math into a couple of lines of descriptive code. Now, C and C++ don’t come with their own vector variables, so you have to make them yourself. (Well, okay, it does have vectors, but they’re nothing to do with geometry.) If you use a third-party game or graphics engine, they always come with their own vector variables.

The thing is, my 3D dimensional vectors are really well developed. You can add ’em, multiply ’em, put ’em in a stew. Get the dot product between two of them, find the length of another, and reflect them off each other. By contrast, my 2D tools barely exist.

For the first hour or so I keep running into situations where I try to add a couple of vectors and have the compiler chide me because I didn’t write any code for adding 2D vectors. So I stop what I’m doing and put that in. Then five minutes later I run into the same thing for multiplying 2D vectors. Then again for multiplying a 2D vector by a single value. And so on. There are a lot of permutations in the number of ways you can combine vectors, so I get a lot of these little interruptions until I suck it up and just write all of them.

Okay, done. Now I guess we can start making something.

Usually in the programming projects I’m reluctant to talk about gameplay or influences. I don’t want to answer a bunch of questions about things I haven’t even designed yet. Is there a limit to how many dots this Pac guy can eat? Can he shoot the ghosts? Does the player have to be yellow, or can we configure our color? Can I play as a girl? Will there be DLC hats? Will there be a power pellet that lets you bash through walls? Shouldn’t the ghosts stop chasing the player and try to steal the fruit? Will we get a sprint button for getting out of tight situations? Eventually you end up with other people trying to design your game through the art of passive-aggressive suggestions.

But I’m doing this project to work on gameplay, so we might as well talk about gameplay. With that in mind, here are the influences I’m drawing from, from the minor to the major:

Insanely Twisted Shadow Planet.

Insanely Twisted Shadow Planet. (Which I think was a gift from Jarenth, in my case. Thanks Jarenth!) We could also say Limbo and maybe some level of World of Goo. The silhouette style rendering is something a talented artist can use to set a mood and create striking visuals. It’s also a tool that crap artists can use to mask their crappyness. I know I’m a crap artist. As with Pixel City, I’m hoping that covering the world in darkness will hide my artistic sins.

If that doesn’t work, then I suppose I’m doomed, because I don’t have much of a plan B. But we’ll try the silhouette thing and see how it goes.

Ultratron.

Second influence is Ultratron from Puppygames. I played a lot of this game a couple of weeks ago and I found it deeply satisfying. The player is very strong, but enemies threaten to overwhelm you with sheer numbers by attacking from every side. My only gripe with the game was that it was a little boring being stuck on the same screen the whole time. Which brings me to my major influence:

Descent.

Descent. Yes. All these years later and I still appreciate this game on a really fundamental level. You fly through tunnels, blasting many different types of robots while an electronic soundtrack thumps along in the background.

So that’s our core concept: 2D Descent, blasting robots in a weightless craft while flying through tunnels that are done mostly in silhouette. Whatever isn’t black should be glowing, bright, and colorful.

The other major component to the game is the leveling, which I’ll talk about later because that needs a post of its own.

But I’m getting ahead of myself. Before we can do any of that, we need something to look at.

For scenery, I combine some simple value noise and use it to generate patterns of solid / open space. To fill it in, I use marching squares.

gr2_map1.jpg

None of this is part of my game design. I’m not going to have random lumpy rooms made out of blue glowstick. But I want to work on gameplay and so I need some kind of environment to fly around in.

I want the game to encourage fast & flowing gameplay. I want it to be fun to zip through tunnels and bank around corners. Having perfect control can feel kind of mechanical and boring. A big part of feeling connected to your character is feeling the “weight” of controlling them. It might be that little half-step Mario spends coasting to a stop, or the way the Decent craft drifts slightly when you let off the controls. It’s not much, but it’s there. Too little, and the craft will feel like a mouse pointer or a cursor. To much and it will feel like you’re piloting a barge.

gr2_map2.jpg

And now I realize the problem with writing this series: You can’t see motion in these screenshots. And since this is a fast-moving 2D game, a lot of my work is going to be based on moving stuff around the screen. Maybe I’ll have to post videos at some point.

But not yet. I’m not going to upload YouTube videos of the project in this state. It’s like posting pictures of the costume you’re making and including images from the 15 minutes you spent looking for the scissors.

And now I come to the first question: What do we do with the camera? I know how to place chase cameras, over-the-shoulder cameras, overhead cameras, and first-person cameras. But I’ve never placed a camera in a scene like this. It’s one of those little problems that I didn’t even consider, but which turns out to be central to the experience.

The obvious thing to do is to just lock the camera to the player’s avatar. And that works. But there’s something about this that muffles the feeling of motion. I don’t know. Space Pirates and Zombies used a locked camera like this, where your ship was always perfectly centered on-screen. It’s not horrible, but it lacks weight.

I much prefer a game where the camera chases after you. When you accelerate, you move away from the center of the screen and when you slow down the camera overtakes you. It lets you “feel” the weight of movement in a way you don’t get when you’re fixed in the middle of the screen and the walls scroll by.

But how far away can the camera get? I know I’ve played games where moving really fast will put you near the edge of the screen. That gives you the feeling of “Wow! I’m going so fast I don’t have time to react to things as they appear!” It also gives you the feeling that the game designer is punishing you for going fast. I don’t want that.

gr2_camera.jpg

I fire up Bleed and fiddle around for a bit. The camera in this game feels about right for my purposes. When I run I feel like I’m going fast, but I don’t feel like the camera is trying to kill me. It seems like the middle 50% of the screen is the critical zone. The game can let the player appear anywhere inside this area of the screen, but as soon as they get more than halfway to the edge of the display, it begins to feel like the game is saying, “Slow down, or you’ll be sorry!”

So I set the camera to chase you around, moving faster the further you get from it and locked so that you can’t ever get more than half the screen away. This feels just about right. I add the ability to bounce off the walls at reflection angles, and it really starts feeling like a game. You don’t bounce fast. You’re not a tennis ball or anything. But just a little bump-back when you accidentally clip the wall feels really good.

Well, it’s not much so far and you can’t tell what I’ve done from the screenshots, but at least we’re started and we have a goal.

 


From The Archives:
 

129 thoughts on “Project Good Robot 2: Welcome to 2D

  1. Phil says:

    I’ve never really gotten into that type of math, but what is the difference between all those vector calcs using 2D vectors and using 3D vectors with the Z always set to 0?

    1. Alex says:

      Nothing. What you describe is just the Pythagorean Theorem in its more well known form. If distance^2=x^2+y^2+z^2, and z=0, it cancels out to distance^2=x^2+y^2.

    2. Blake says:

      Something like a cross product will produce a different result, otherwise probably not heaps.

      1. David F says:

        Actually, cross product will technically work the same too, since cross product only works on vectors in 3-space, and always produces a vector orthogonal to the original two vectors. If I’m correctly remembering my vector math which I haven’t used since school.

        1. Blake says:

          People do 2D versions of cross products, which may not be cross products in the most strictly defined sense, but they do what you need them to.

          http://www.gamedev.net/topic/289972-cross-product-of-2d-vectors/

          If you did that on 2d vectors in 3d space you’d end up with a vector along the axis you weren’t using.

        2. silver Harloe says:

          I’ll have to dig out my linear algebra book, but I’m 80% sure cross-product is defined for matrices of any size (even 1×1)

          1. Nawyria says:

            The cross product isn’t strictly speaking defined for other dimensions, but there are generalizations to spaces of different dimension, the most well-know of which is the exterior product (wedge product). However, you’ll have to venture into Lie Algebras / Topology / (Differential) Geometry to encounter one; so your linear algebra book most rock :P.

            1. silver Harloe says:

              more likely is that I’m simply mis-remembering things from a class I took in 1986 ;)

    3. Shamus says:

      For the most part it’s the same thing. It’s just that ALWAYS adding this useless zero to the end of every single little bit of math is tedious and messy. I mean, it’s not big deal when you’re just getting the distance from A to B, but when you’re taking that distance, comparing to another distance, normalizing the larger of the two and scaling it back up to some other value, and inverting the direction, it turns into something that eats more screen space for no reason.

      1. The Schwarz says:

        Actually the correct way to do this is to make all the calculations depend on the number of dimensions, i.e., don’t have X, Y and Z, just have x1, x2, x3,…
        That way you can have the exact same methods for just about anything and they’ll work in 2D, 3D and even 11 dimensions if you want to do crazy String Theory stuff. The only difference is that for 2D you have a 2-coordinate array, and for 3D it’s a 3-coordinate.

        1. Jay says:

          A standard graphics card is built on the assumption of three spatial dimensions, so I doubt the string theory stuff would work with it. For 2D, no prob.

          1. Zukhramm says:

            But we generally don’t run most of our program on the graphics card.

            1. Rick C says:

              Except for the obvious and relevant counterexample of 3D games. :)

              Unrelated: Shamus, it’d be really nice if you made the “Confirm you are not a spammer” text clickable. All you would need is <label for=”p_gasp”> and that text would work like a (properly-written) Windows[1] program does.

              Do Macs & X programs do that?

              1. Zukhramm says:

                The rendering runs on GPU but there’s a lot more to a game than drawing the picture.

              2. Corran says:

                Edit: I guessed the comment processor would eat my html and it did. Hopefully I fixed it now.

                From what I see the actual id of the checkbox is cl_check_cd7.

                So to make it work you would replace ‘Confirm you are NOT a spammer’ with ‘<label for=”cl_check_cd7″>Confirm you are NOT a spammer</label>’.

                Once you do that people can click anywhere on ‘Confirm you are NOT a spammer’ to check the checkbox.

        2. Adam says:

          Except that I’m not aware of any string theories with all euclidean dimensions if any. Most of the higher dimensions tend to be tightly rolled up.

      2. Blake says:

        class Vector2: public Vector3
        {
        Vector2(float x, float y) : Vector3(x,y,0.0f){}
        };

        Problem solved!

        1. Phil says:

          Yeah, this would’ve been my suggestion, too. Definitely save you from that extra 0 problem.

          1. Paul Spooner says:

            With the added bonus that it should be much easier to convert to 3d later. It seems like this should have been obvious though, so there must be some reason he didn’t do it this way. I feel like I’m missing part of the picture.

        2. Deoxy says:

          Yeah, I was going to suggest exactly this as well. Mildly inefficient, but saves the programmer SO MUCH TIME.

      3. sheer_falacy says:

        Could you create a subclass of your vector class which doesn’t take any z coordinate and just calls the superclass functions with a z of 0? Or is your vector stuff not object oriented?

      4. I don’t understand where your extra zeroes are coming from. Wouldn’t the code you describe just look like this?


        double dist1 = (avec - bvec).length();
        double dist2 = (avec - cvec).length();

        Vector* nvec = (dist1 > dist2 ? &avec : &bvec);
        nvec->normalise();
        nvec *= -1 * newLength;

        Not a zero in sight. ???

        1. Shamus says:

          Sure, the distance example would be fine. But sometimes I need to use literals. Sometimes I need to take map coords or screen coords and turn them into vectors. This happens a lot. And then we end up with:

          nvec = vec(new_x, new_y, 0.0f);

          instead of:

          nvec = vec(new_x, new_y);

          And yes, I could just make a constructor to handle that, but if I’m going to have to write code either way then I might as well code it to use the vectors I’m actually interested in. :) It probably doesn’t matter in the long run, but it feels more correct.

          1. Felblood says:

            “but it feels more correct.”

            –and that matters more than any of that other stuff. Seriously, I am not even being sarcastic.

            Shamus knows coding practice well enough to know that when he’s reading this code in 6 months, he’ll want to be able to trust his gut on what any of it actually means.

          2. I always give my vector constructors default zero arguments so I can specify just the x or just x and y, but fair enough, it’s not as though a quick vector library is all that much work. Add, scale, get length, normalise, dot product, angle, project onto, and you’re largely done, right? Interpret as complex number and add a division operator if you feel fancy.

          3. noahpocalypse says:

            Random tidbit: the diagonal of a cube is always equal to the side length times the square root of 3.

            Not that that’s any use unless your game is based on cubes. And even Minecraft wouldn’t have any use for it. But it’s still neat, if you like math. A… proof, I think is the proper term, can be found here:http://noahcaldwell.com/blog/2013/05/16/diagonal-of-a-square/

            (I confess, that is my blog. But it’s still an interesting and kinda maybe relevant read. Relevant to my comment anyway, which isn’t very relevant to Shamus’ post.)

    4. Daemian Lucifer says:

      Well keep in mind that for a looooong time now Shamoose has been using memory efficient code.You cant just expect him to constantly watch at this useless dongle that is eating up KILObytes of space and not do something about it.

      1. Deoxy says:

        You think Shamus waits until it’s KILObytes before he worries about it? That’s insulting.

        1. Shamus says:

          You guys joke, but the thought of wasted z-floats hanging on the end of every vector does bug me.

          I’m not going to run the math, but…

          No, I’ll totally run the numbers. Let’s see. Assuming a single thing on-screen is a collection of 4 vecs for the corners of its polygon, then that’s 4 extra floats per thing. (Bullet, bad guy, particle, etc.) Each float is 4 bytes. So we’re wasting 16 bytes per thing. Oh, but each thing probably has a direction of movement or momentum or some other dang thing that’s making it move about the screen. So let’s say 20 bytes per thing.

          At that rate, I would need 51 things onscreen at once to even add up to a single kilobyte of waste. Which means if we’re being super-conservative with memory usage, then I’d need about 51,000 things before it began to matter.

          And yet, it still bugs me. Comes with cutting my teeth back when kilobytes mattered, I suppose.

          1. Felblood says:

            Hey, it only takes a few thousand such inefficiencies, multiplied across a few hundred objects to reach a point where this actually does hurt.

            Is a project with one coder going to reach 1000 of these? No.

            Is a project with 20? Almost always.

          2. Daemian Lucifer says:

            I sympathize actually.Having a wasteful code is just an eyesore,even if the waste is measured in bytes,and even if it would take hours to rectify the mistake.

          3. McGurker says:

            I mean, it’s also messy, isn’t it? Forget about wasted time or wasted memory, this is code that doesn’t look good and isn’t the best at what it’s supposed to do they’re talking about. Sounds like beginner programmer talk (my talk!) to me. “Well I have all this code which BASICALLY does what I want this code to do…I can make the modifications!” and then you write constructors that make assumptions about how they’ll be fed data and this and that until you forget about one of those assumptions and make a mistake and get a bug that makes no damn sense. Better to write pretty code than screw yourself ten years from now cause you took the quick way out, to take a page out of your own handbook.

            Note: When I failed to add my info because I posted this as a reply, I thought it would delete all this text, and it didn’t. You sir are a true one of a kind class act, I’ll tell you what.

          4. Alexander The 1st says:

            This is probably the next biggest divide between programmers these days.

            No seriously, I’m of the “Make it developer friendly first (re-usable, easy to edit, etc.), *then* optimise it if you *really* don’t have anything else that you could be working on to make this easier for other developers to use” school of coding.

            I only started coding around 2007, so…:

            – That was the tail-end of consoles using memory sticks to store save data;

            – Since then, we went from one console generation where 512 MB of RAM was all you had, one console even split that 256 x 256 between graphic memory and engine memory. The console generation after that? 8GB of RAM, such that you could essentially throw out *all* byte-specific optimisations and probably do just as well as Skyrim did on the PS3 at worst. (For perspective, you could have 128 different instances of Doom running on a previous generation console before you ran out of RAM – the current generation could run 2048 different instances of Doom before it ran out of RAM – though it probably couldn’t keep up with the CPU cycles by that point, if it could survive 128 last generation. [Source: http://www.gamers.org/docs/FAQ/doomfaq/sect4.html%5D);

            – Engines like Unity and Unreal Development Kit 3 are built with being able to take game idea and make it easy to put it onto the consoles in a very generic way without needing to worry about optimisations at all;

            The above steps are something that, for an aspiring developer like myself, make me happy, because I no longer need to worry about whether or not what I make is byte-efficient, and more about “Will this be understandable when we probably need to change how this works without adding more bugs to the system later?”

            1. TSi says:

              You don’t need to justify the way you code and the tools you use. I even don’t think you need call this a “divide”. Shamus is obviously not using someones else engine and that’s cool if you like to use one should it be Unity, UE3, CryEngine or some other in-house engine. It’s up to you and to the people you work with. He doesn’t need his old code ( http://www.joelonsoftware.com/articles/fog0000000069.html ).
              Here we’re talking about coding stuff from nearly zero and as such, optimizations are always good should they begin early on during development or later.
              I like to think of it as a zen garden. You need to feel in peace with your code, how it looks on your editor and how you organize it in your folders.

            2. Simon Buchan says:

              Inefficient memory is, unfortunately, still a problem when:
              a) You fall off the CPU cache cliff (probably the biggest cause of slow performance in most desktop apps: either you have to have very nice data access patterns or you can make latency is a low priority, perhaps by clever asynchronous code)
              b) You actually *are* slicing up the memory into as many instances as you can, say, because you’re running servers where you are memory-bound (from what I understand, fairly common), and paying $/hr/server, so a higher user/MB ratio means a lower $/MB ratio, meaning you are directly saving your company money by cutting bytes.
              c) You are running on a garbage collected language on a mobile device. You can have as little as 35MB before a garbage collector starts getting scared and thrashing to avoid having the OS kill you!

              There’s probably more, but those three are actually somewhat common. Memory is still not free, though you can generally look at it last for performance problems.

          5. Deoxy says:

            You guys joke, but the thought of wasted z-floats hanging on the end of every vector does bug me.

            I said it as a joke, but I knew it really wasn’t. I have the same tendency, though I think I have less compulsion to follow it than you.

            Elegant, efficient code is its own reward, mentally speaking. But sometimes that reward pales in comparison to the “got it done on time” reward…

          6. Anachronist says:

            I’d be more concerned about the useless math being performed on the zero Z component than about wasted memory. Excess floating point math has a greater potential to slow things down when there’s too much stuff moving around.

            More memory can always be added, but your processors are what they are.

          7. Ninjariffic says:

            My guffaw just made everyone at Second Cup look at me.

            I really applaud your sense of craftsmanship when it comes to things like this.

  2. The Schwarz says:

    Suggestion for the screenshot issue: animated GIFs? I know they’re sort of the clown-noses of the internet, but sounds like it really is what you need here…

    1. Kamica says:

      I had the same idea, so yea, I support this idea =D.
      (Also, my avatar always seems to be the same, is this done through username, e-mail or IP? Or some other way?)

      1. MichaelGC says:

        I believe they are generated from email addresses – if you use the search box above to search for ‘wavatars’ you’ll get the posts talking about them. I like mine! – it looks appropriately perplexed.

        1. Cuthalion says:

          And I have never had a more appropriate avatar.

        2. Syal says:

          Likewise, mine looks appropriately smug.

      2. Hitchmeister says:

        Yes. Gravatar randomly assigns an avatar to your email address and that same avatar appears every time you post with the same email. Alternatively you can go to gravatar.com and register for free and upload anything you want as an avatar so you too can be something cool like a perplexed emu.

        1. Josh says:

          Or an American President!

          1. Daemian Lucifer says:

            Or a succubus.

            1. somebodys_kid says:

              Or a Crazy Duck!

              1. krellen says:

                Or a whatever the heck my avatar actually is.

                1. anaphysik says:

                  Or a manta ray! IT’S NOT A SAILBOAT, GRAVDAMMIT!

                  @krellen: I think it’s a sentient pair of sunglasses, wearing a person.

                  1. Piflik says:

                    Or some random doodle that ended up being my icon across all of teh webz…

                    1. newdarkcloud says:

                      Or that one BoS guy I killed and stole Power Armor from.

                      Wait, what!?

                    2. PeteTimesSix says:

                      Or a different thing every other week. Ive got this pixel dragon here, glowing ant over on steam, a pony for my windows login screen, a different pony for an unused account on skype and a pixel imp on a forum I frequent. Comes with never being satisfied.

                    3. Simon Buchan says:

                      Or a toddler assembling a gun in class! (So am I in the cool kid’s club now?)

                    4. Groo The Wanderer says:

                      Or ME!

                      Anyone know where I can find the cheese dip?

                    5. Cap'n Hector says:

                      Or me in an expensive car.

                    6. Trix2000 says:

                      Or a stylized Pokemon.

        2. Retsam says:

          I’m pretty sure that the default avatars don’t come from gravitar, as it’s default behavior is to return
          this image for unregistered emails, but instead that the default images were somehow assigned by the blog itself. (Plus, the “geometric shapes with faces” fits the blog’s theme pretty well)

          Mine was kind of odd. A circle with an X over the mouth, I think. Probably indicating that I’m too verbose. Way of Kings cover art is much better (if maybe questionably legal).

          (If anyone’s curious how the blog might detect whether or not you have a gravatar, adding “?d=404” to the end of a url will return a 404 if they don’t have an avatar, rather than returning the default)

          1. anaphysik says:

            They’re called “wavatars,” and Shamus made them. Gravatar subsequently implemented wavatars (along with a couple other people’s methods (monsters and patterns, iirc) as one of the default options.

            http://www.shamusyoung.com/twentysidedtale/?p=1462
            http://blog.gravatar.com/2008/04/22/identicons-monsterids-and-wavatars-oh-my/

            (And yes, the first comment on that really is someone saying that wavatars are “ugly and bad drawed” *just* because they don’t have perfect anti-aliasing applied to them <_<

            (Hm, honestly it’d be cool to see these alternate wavatars be adopted too: http://blog.dmcleish.id.au/2007/12/19/wavatars-now-with-new-and-funky-art/ (Shamus even said that he liked that art style better than his own))

            1. Hitchmeister says:

              I started reading the site sometime after 2007 so I never knew that Shamus created the Wavatars. Cool.

        3. Chuk says:

          You could just be a random hunk of some cool game’s UI, too.

    2. TheUnHidden says:

      Or better yet: Animated PNGs. Gifs have a very limited colorspace and the compression isn’t the best. With animated PNGs you have a better compression and better image quality. Most modern browsers play them (except for google chrome, which needs an extension for that …).

      How to get these? Well you would need to videocapture your program of course. Afterwards you could use something like VirtualDub to cut it to size and convert it into an APNG with this virtualdub apng plugin.

      1. Felblood says:

        Surely, you are joking.

        Yes, this is the way normal people produce animated gif. (Vdub FTW)

        However, Shamus already has a pipleine for embedding Youtube Videos in his blog, like in the Pixel City series. Why would he need to convert the video into another format?

    3. Galad says:

      If you end up using animated GIFs to illustrate your points, please make it possible to turn them on/off with a video-like button.

      If you don’t understand what I mean, you can check the gifs on 9gag.com.

      Thank you :)

      1. Eskel says:

        In most browsers you can stop animated GIFs by pressing ESC

        1. Rick C says:

          Unless you’re using a recent Firefox version, because they thought it would be a good idea to make a key that did one thing for 15 years do a different thing!

          1. Parkhorse says:

            Ah, the ol’ Windows 8 school of interface design!

  3. Knut says:

    Regarding camera speed, I’ve played games (but I don’t remember the names) where the camera lags behind due to acceleration (in all directions, so also turning and braking), but not due to speed. So when you start to move, the camera lags behind, but then catches up. I remember this gave a good sense of speed, but still allowed me to see where I was going. Maybe this is something you can try out, I don’t think it would be too difficult to implement.

    1. Mephane says:

      This actually sounds especially appropriate as Shamus described the gameplay as zero gravity (I inferred that from the phrase “weightless craft”), where all you ever feel is acceleration.

    2. The RIght Trousers says:

      I’ve seen games where, when you’re going fast, the camera zooms out a bit so you can see more in the direction you’re heading.

      1. Sabredabce (MatthewH) says:

        Alternately, when you go fast, zoom in to reflect the difficulty of changing direction at high speed. That always seemed better to me -though either would work. Depends, I guess, on the nature of the game you want.

        I’m unclear on something: is the ship supposed to bounce off the walls in the “you hit the wall and bounce off -stop doing that!” way, or in the “bing-bing-bing-bing-bing I’m a ricocheting ball of death!” sort of way?

        1. Syal says:

          Since he specifies accidentally hitting the wall, I assume it’s just a small bounce-back to make you look/feel dumb.

    3. Decius says:

      I like this, but I would prefer if the camera lagged behind due to acceleration, then caught up, then led somewhat in the direction of travel.

      I may be moving fast, but I’m looking forward, dammit!

      Or zoom out at higher speeds, on the same principle. (I believe GTA1 does that)

      1. Tizzy says:

        Yes, GTA 1 did zoom out as you went faster. This jumped immediately to mind before I was done reading the article, and I am glad I’m not the only one who thought about it.

        It was a great reward mechanism: having the camera zoomed out to the max felt great, allowed you to have a much better sense of your surroundings and opportunities, but was also risky: it was very easy to get swept up in the feeling and miss a turn, especially since the environments were very grid-like and comparatively small.

        As I recall, crashing could easily blow up your car and kill you back then. So risk and reward rolled into one. Great fun.

  4. Cuthalion says:

    This sounds awesome! Descent is one of my favorites. I also like the black vs bright colors style, the apparent robot theme, and some of Puppy Games’ other work (Revenge of the Titans), though I haven’t played Ultratron.

  5. Jarenth says:

    You’re welcome, if it was really me. I don’t quite remember?…

    I kinda dig the glowstick rave tunnels, actually. Maybe the scary eye monster from last post could be smashing those up?

  6. ACman says:

    Wouldn’t it be great if Shamus made a cool little corridor shmup and that actually put him in the black?

    Get Rutskarn to write the dialogue and Chris to design the menus and power ups store. Josh does the netcode???

    1. GM says:

      nah have Josh do the game testing.,he´l find all the bugs don´t you worry.

    2. Muspel says:

      Have Rutskarn do all of the voice acting in his Atlantic accent.

    3. Jarenth says:

      Chris should be in charge of making sure the gameplay and the story match well thematically. I’m not going to say that one phrase, but you know what I’m talking about.

      I envision Josh more in a boogeyman role.

    4. Jarenth says:

      Chris should be in charge of making sure the gameplay and the story match well thematically. I’m not going to say that one phrase, but you know what I’m talking about.

      I envision Josh more in a boogeyman role.

  7. PeteTimesSix says:

    [passive-aggressive suggestions mode]
    Now this is just from the top of my head, so it might be very dumb, but how about a reverse-chase cam? Instead of trailing behind, the camera actually moves a bit in the direction youre accelerating? I dont remember where I saw it, but it was in some game out there and it was reasonably effective…
    [/passive-aggressive suggestions mode]

    1. Shamus says:

      That’s an interesting idea. I’ll have to put that in and see how it looks / feels.

      1. Shivoa says:

        I think there is a post-mortem on Insanely Twisted Shadow Planet that explains exactly this, with a video stream of their debug view (with acceleration and thumb stick vectors, things they flagged in the environment as important to bias to try to show, etc) to make it all more concrete.

        I remember it being technical enough to be useful to actually code up a similar system while still being accessible enough that you should totally link it if you do find it useful in a future post.

        And as I was typing that I found it (thanks Google) here (contains YouTube embed). 10 minutes of your time.

      2. Deoxy says:

        I’ve seen it done – it’s the opposite of punishing you for going fast. Basically, you are going this way, so we should LOOK this way and have MORE reaction time instead of less.

        It can work nicely. Like almost everything else, it can also be horrendously awful.

      3. Shamus says:

        And for the record: I’m on week three of this project, but this blog entry didn’t even cover all of day 1. So… it’ll be a while before the results of this experiment show up.

        1. MichaelG says:

          No, you should blog as you code things. Then you can promise new features that never happen, and let people see you go off course and get depressed. Reality Programming!

      4. Hey, if we’re going to go armchair designer, I got one!

        If I understand correct, this is basically you v. bunchaRobots. Well, consider an Asteroids-like mechanic where when ya blast one, it turns into chunky bits that must also be blasted OR can be grabbed to upgrade your ship with better blasty bits/armor/etc.

        1. Syal says:

          As a counterpoint, nothing bugs me more than killing a big enemy only to have it turn into a smaller enemy.

          1. swenson says:

            Especially when you just barely managed to kill it before you collide with it, and just when you’re congratulating yourself, you run into all of the little bits and pieces that exploded out of it.

    2. Zukhramm says:

      Hey! I wanted to suggest that!

    3. Cuthalion says:

      If I’m not mistaken, this is actually the recommended way to follow action with a camera when shooting video. The object could start moving, but then the camera catches up, passes it, and stays a little ahead. It’s been awhile since I had that class, and now I can never remember if you want to lead with the camera or follow… pretty sure it’s lead though.

    4. Paul Spooner says:

      When I saw the “what do I do with the camera” thing, this is what I thought of. Glad someone else was thinking along the same lines!

      1. Atle says:

        Another trick is having the camera zoom out while moving fast, GTA style.

    5. Unbeliever says:

      I’m remembering a camera like this on Repton, the Defender-clone for the Commodore 64 ages ago… (which probably implies that the Defender camera worked the same way — but I played way more Repton than Defender).

      The advantage, of course, is that the faster you go, the more screen real estate you get for things coming at you…

  8. DoctorSatan says:

    Hmm, 2D limits a lot of gameplay types. Why not a top down game?

    1. Bropocalypse says:

      That would more-or-less end up as the same thing, unless you throw in some jumping or something. But that sort of mechanic can be frustrating or just plain odd-looking from a static viewpoint(sidescrolling notwithstanding) if not managed very carefully.

  9. Kdansky says:

    I saw this a while ago on the topic of 2d platformer cameras:

    http://www.youtube.com/watch?v=TCIMPYM0AQg

    As for the rendering, I much prefer to go with an existing solution, like Slick2D (or any other), because writing vector multiplication code gets old fast.

    1. Volfram says:

      That was a really interesting video. I learned two things from it.

      1: I HATE the camera logic in the Mario games!
      2: WHY I hate the camera logic in Mario games!

    2. Anachronist says:

      That’s interesting. The camera has different modes of tracking (locked to bottom, locked to level, or unlocked) depending on the environment Mario is in, and gives Mario a 16 pixel region to move around in and change direction before the camera starts moving again.

      I can see something like this for Shamus’s idea. Make the center 1/3 of the screen a free movement zone in which the camera doesn’t track. When the ship crosses the zone boundary, smoothly accelerate the camera to catch up, aiming for the ship to be in the zone center, until the ship is back within the zone, then smoothly decelerate the camera.

      The camera’s velocity should be limited to something slightly higher than the ship can travel.

      There could also be another zone, say 20% from the edge of the display, where the camera rapidly accelerates to max velocity until the ship is back inside the normal acceleration zone.

  10. Weimer says:

    Now I’m thinking of Liero. Damn that was a fun game.

    On that note, it would be nice if there were powerups inside the walls randomly strewn about, but you’d have to dig your way to them, revealing hidden obstacles and enemies.

    But then I realize that if I wanted to see that implemented, I could always learn to program it myself. So I’ll just shut up now.

  11. swenson says:

    My older sister and dad used to play hours upon hours of Descent when I was young (well, Descent II), but I never had much luck with it. Part of it was that I was too young to really understand what I was doing, I suppose, but it always kind of scared me. Too claustrophobic for me, I think.

    Fury3, on the other hand… I played that one pretty much endlessly.

    Regarding the actual post: I like what you’re doing with the camera. I, too, like when the camera does the little catch-up thing, it really helps sell the speed.

  12. Daemian Lucifer says:

    “2D Descent”

    So,r-type?

    1. Zukhramm says:

      How are those anything like each other?

  13. Syal says:

    “To much and it will feel like you're piloting a barge.”

    …I kind of want to play a game about a barge going on a rampage now, trying to run people over even though they’re faster and more maneuverable than you. You have to, like, sneak up on them. Stay in the travel lanes until you get close, then pounce upon your unsuspecting prey in a slow, awkward manner.

    Or maybe there could be spots where you chase small ships into coves and then drive them up into the rocks.

    And then you could throw containers and stuff off the sides to clog up the water and block the boats from getting away.

    1. MichaelG says:

      You could ram bridge supports, collapsing the bridge and throwing cars into the river. Bonus if you hit a bridge with a train on it. :-)

    2. McGurker says:

      There has to be a genre of “games people proposed completely tongue in cheek and then someone actually made it.”

      Like Penn and Teller’s game where you just drive the van for eight hours. Or the game that simulates “train watching” in a safe and responsible manner.

    3. Asimech says:

      That reminds me of a mental image I once had that can be summed up as “Stealthy Hulk in Space”.

      Bonus: “In Space No-one Can Hear You Smash”

  14. LazerBlade says:

    Why do all of the one-man game devs I follow start making the game I gave up on finishing?

    1. Jarenth says:

      Evidence seems to suggest you have cool game ideas.

  15. Hal says:

    Wait, I didn’t get this from the first post. Is this “Shamus playing around with programming because that’s what Shamus does?” Or is this “Shamus is trying to make an actual game/product to sell to people?”

    Post 1 looked like the former. Post 2 looks like the latter.

    1. Ilseroth says:

      This is “Shamus is experimenting with gameplay development and design as opposed to his normal graphically focused coding.”

      He may decide to release it if he things people might actually like it, or he may just file it in his “that was an interesting experience” folder and it may not see the light of day again till he references it in something somewhere.

    2. PeteTimesSix says:

      Why cant it be both?

  16. aldowyn says:

    I know this is largely incidental to the post, but WHY is the vector list class called vector? I use geometric vectors all the time so when we started using the Vector class in my java courses I was pretty confused for a while.

    1. Ed Lu says:

      Linky

      You probably want to read both the accepted answer and the one just below it; the accepted answer doesn’t give you the whole picture.

      1. aldowyn says:

        hmm, okay. Thanks!

      2. Cuthalion says:

        Ohhhh…

  17. McGurker says:

    Shamus I just want to say that is this BY FAR my favorite thing you blog about and I’m so glad you’re bringing it back after the on-hold project octal which, frankly, got a little harried for me to follow (but I still followed it!)

    My second favorite, which is so close a second as to basically be tied, is when you use your enormous braindatabase of programming knowledge to analyze games from the perspective of how they were coded/how the art direction happened/what’s going on in this scene here/why is this madness happening?

    Honestly they are tied, all the programming is so awesome and I love it, your writing is accessible, informative and brilliant, if you wrote a book of THAT STUFF I tell you I’d donate to the kickstarter, buy a second copy (obviously I’d donate enough to get a free copy) for a friend/future child/extra in case of damage and…well…I don’t know what else.

    It would be neat if you made a poll to see who likes what on the site, I’d be interested to find out if I’m the minority, I know there’s people who love the game reviews which I’d put third, and the videos which are also third (I could sub divide this but for the most part I like every video) and then the podcasts and stuff which I don’t listen to because audio is never enough for me. OH except I guess the podcast style videos I don’t like either because, funny as it seems, I want to hear the game! This is why I don’t like director commentaries either.

    Enough blabbering, I’ve got to make pasta, keep up the good work!

  18. Nersh says:

    What tools/libraries/etc are you using?

  19. Viktor says:

    Is there any reason you can’t use animated gifs instead of screenshots? For a lot of this you won’t need more than a few seconds of gameplay footage, so using a Youtube video seems like overkill.

    1. Paul Spooner says:

      Or a Vine or something? Composited sequence made to look like motion blur? Color indexed time-stamps? The possibilities are endless!

  20. Adam P says:

    Shamus, if you want to show off the motion in a screenshot, but without using a video, there’s a neat little program that will capture GIFs of your desktop: LICEcap. I’ve seen 3D modelers use this to do turnarounds of their models instead of doing a painstakingly long offline render for them.

  21. Amarsir says:

    I remember the concept from Linear Algebra, but never having worked with graphics I never made a real-world connection. Why would multiplying vectors be useful? It seems about as relevant as writing a social network app and having functions to multiply users’ ages.

    1. Ed Lu says:

      I don’t claim to understand these things on a theoretical level, but here goes a few examples of what you use vector multiplication for:

      1. Camera movement: There’s a reason that fancy strafing you have in FPSs now didn’t exist back whenever, and that’s because it was easier to just change the angle of the camera. If you want to move to the side, you’ve got to calculate a vector normal to the plane defined by the player and the direction you’re looking. To do this, you take a cross product.

      2. Calculating surface normals: This is used for lighting; basically, you’re calculating a vector perpendicular to a surface, like the ground or a wall, so you know how light would bounce off of it coming from different angles. It’s calculated exactly as #1 is, since everything is made of flat surfaces (triangles) and all you do is take the cross product of two vectors making up that triangle.

      2. Projections: The big one; used for many, many, many things, from collision detection to rendering the entire scene onto your screen. Think of it as collapsing an axis; you’re taking a shape in 3D, putting it against a piece of paper, and tracing its shape. Taking a projection is, in fact, equivalent to vector multiplication, as noted on the wikipedia page.

    2. Zukhramm says:

      That’s such a generic question it’s kind of hard to answer it. Why is multiplying anything useful? It’s used in plenty of places in geometry, physics and other areas, finding normals, projections, I can list examples, but that’s not really answering the question.

  22. Asimech says:

    If you feel the need for more “speed space” you could have the centre of the camera to be slightly in front of the ship. But this tends to feel a bit awkward in my experience.

    Reading the comments I’m now wondering how disorienting/nauseating it would be to have both the chase-restore cam and the reverse-chase cam. At first the camera wouldn’t follow and then would end up overtaking the ship.

  23. Steve C says:

    Speaking of Decent, did you know there is an update project being worked on for Decent? Now you do.

  24. Kronopath says:

    You disparage your “blue glowstick” walls, but I’m a bit curious as to how that effect was achieved. Is it just a texture or was the effect done procedurally?

  25. WJS says:

    Wow, there’s a bug in your marching squares for the glowsticks. Never noticed that before.

Thanks for joining the discussion. Be nice, don't post angry, and enjoy yourself. This is supposed to be fun. Your email address will not be published. Required fields are marked*

You can enclose spoilers in <strike> tags like so:
<strike>Darth Vader is Luke's father!</strike>

You can make things italics like this:
Can you imagine having Darth Vader as your <i>father</i>?

You can make things bold like this:
I'm <b>very</b> glad Darth Vader isn't my father.

You can make links like this:
I'm reading about <a href="http://en.wikipedia.org/wiki/Darth_Vader">Darth Vader</a> on Wikipedia!

You can quote someone like this:
Darth Vader said <blockquote>Luke, I am your father.</blockquote>

Leave a Reply to Cuthalion Cancel reply

Your email address will not be published.