Programming Is Easy; Math Is Hard

The other day, I was thinking to myself, “I’m a very experienced programmer, I’m very creative, and I like video games; I should try making some computer games.” It seemed like such a no-duh sort of thing, I don’t know why it didn’t occur to me until recently. I used to make text games out of BASIC when I was a little kid and dreamed of making more complex games, but it just hadn’t occurred to me to revisit that — perhaps because my focus had been more hardware than software until recently.

Anyway, I found out that Microsoft has this XNA library for game creation that uses C# and Visual Studios — what I use at work now so no learning curve on the programming basics. Apparently, Microsoft is making this excellent library available for free to try and get game programmers to use managed code. Now, I would have laughed at the idea not too long ago (“Managed code for a computer game? Yeah, if I want it to run at three frames per second!”), but I’ve now done quite a lot with C# (most of my experience had been with regular old C) that I would have thought would be impossible without pointers, such as dynamically creating and populating an instance of a class. So I’m a C# convert and excited to make games.

I start with the tutorials, which are nice but a little annoying since they assume you’ve never even programmed before (and I don’t see you getting very far with XNA without some basic programming experience). I find the logical flow of XNA pretty easy to understand and easy to play around with. The hard part I find out when fiddling around with the 2D tutorial is the math. I had to go back to basic geometry and try and remember how to use Sin and Cos to get the length of sides on a right angle. Nothing too bad, though.

So I move on to the 3D tutorial. Quite a bit more complicated, but I think I can still understand it all. Now I want to add mouse support to the game. My idea is to add a crosshair sprite, come up with a 3D point in the distance that corresponds with where the 2D crosshair is on the viewport, and aim the cannon at the point. I decide to start with aiming the 3D cannon by seeing if I can program it to track one of the enemy ships.

Holy crap.

First of all, when working with objects in 3D space, the simplest thing to do is use matrices so you can adjust the whole 3D object uniformly. Simplest does not mean simple, though, as I still don’t have any concept of the where and why of the matrices. I do know matrix algebra from rote, but I never got a conceptual understanding of it (didn’t think I needed one). The other problem is rotation.

I found this help on getting a 3D object to point at another. That worked on getting the cannon to rotate on just the y-axis, but I’m still trying to figure out how to get it to rotate to follow a ship on both the y and x axises without distorting the cannon. Not simple. I keep running into quaternions to represent rotation, but the consensus on those is just learn how to use them and don’t even attempt to understand them.

Now, I’ve actually worked before with complex math involving 3-dimensional points transformed with matrices when I figured out how to do elliptic curve encryption on hardware (does anyone use that? It is much faster — though much more complex — than RSA — especially on hardware since in certain configuration an XOR is used for addition (i.e., no carry bits) making for some relatively simple large multiplies). I never really understood it, though, as my engineering attitude is get the results you want and worrying about understanding what you’re doing secondarily. I never actually saw elliptic curve as representing points on a 3D plane but instead just a bunch of weird math I did to get the required output.

Anywho, that’s my new hobby I’m up to. Don’t know if any of you could be of help. Maybe I should stick to figuring out a simple 2D game to make as a starter project, but it would be nice to know some basics in making 3D games.

45 Comments

  1. Sorry, Frank. I’m no help. I similarly learned to make boring junk in BASIC, and my first computers (Commodore and Atari) were slow so I learned how to hand code some machine language subroutines to make the animation decent. But I’ve never been able to get into any of the OOP stuff. I’ve been told that learning procedural languages first is a handicap when trying to learn stuff like C++ and Visual BASIC, and I think it is true. There’s an imaginary wall I can’t seem to get past.

    Good Luck to ya, though. It’d be AWESOME to have some moon-nukin’-commie-slayin’-IMAO themed shooter to goof with.

    [That is the eventual hope. -Ed.]

  2. I don’t know about the Microsoft platform, but I had to do some 3-D animation sequences (not even as complex as a game) for a Java project I was on. I did get it to work, but it was painfully SLOW. Eventually, I ended up just rewriting it in C++ with assembly routines for doing the math.

  3. Brother Frank, I worked in that biz for a number of years leading up to the dot com burst. Although I have a degree in it, I did what 90% of folks with a degree do, something else. I stayed in the art department mostly, much easier, better pay and no math other than a t-square and ruler. If I were you I would stick to 2D, plus its a lost art and someone needs to carry that torch.

    Ciao,

    TS

  4. Good stuff!

    I doubled majored in computer science and mathematics in college. I took linear algebra and learned the basics, but it wasn’t until I took graphics in the CS track that I really “understood” it. My recollection was that understanding why you need 4×4 matrices to manipulate objects in 3D space (homogeneous coordinates are necessary to render translations [affine transformations] as multiplications rather than additions) was the turning point for me.

  5. Never mind the shooter, I’d love to see an IMAO text adventure series. Can’t get enough! Since you’re experienced with that, may i recommend the Adventure Game Creation system at BigBlueCup.com? Maybe we’d get The adventures of Frank J. out of it. That would be nice.

  6. This is what I do!!! Let me give a quick explanation of Matrices:

    3×3 matrix = rotation matrix; 4×4 = translation matrix (4×4 holds rotation, scale, and translation, 3×3 holds only rotation + scale). XNA uses 4×4 matrices by default, so you don’t have to worry about it really.

    I wont go through multiplication of 2 matrices or matrix times vector, because that’s really annoying to explain, and XNA has methods to do that for you. (They also have methods for creating matrices, but it helps to know what it is you are working with.)

    For scale, you create a matrix that looks like this:
    scaleX 0 0 0
    0 scaleY 0 0
    0 0 scaleZ 0
    0 0 0 1
    The 1 is for homogeneous coordinates. That is almost always going to be a 1 in the bottom right.

    For rotation, it’s a lot more complicated. You have Rot around X, Y, and Z. For rotation around X, you have
    1 0 0 0
    0 cos -sin 0
    0 sin cos 0
    0 0 0 1

    For y:
    cos 0 sin 0
    0 1 0 0
    -sin 0 cos 0
    0 0 0 1

    For z:
    cos -sin 0 0
    sin cos 0 0
    0 0 1 0
    0 0 0 1

    And lastly translation. By far the easiest.
    0 0 0 transX
    0 0 0 transY
    0 0 0 transZ
    0 0 0 1

    Now when you multiply them together (IN THE ORDER OF scale, rotx, roty, rotz, trans—very important!!!) you get your matrix that holds all those transforms in 1. When you multiply your origin(2D) or verts (3D) by that matrix, you get the effects you (hopefully) want.

    However, there is 1 way to ‘cheat’ the system using matrices. The reason it’s so important to multiply(combine) them in the right order, is because what would happen if instead of rotate->trans it was trans->rotate?
    rotate->trans
    |
    || <-starts there
    |_______

    |
    |_ <-rotated
    |_______

    | _rot

    |
    || <-starts
    |________

    | | <-translated
    |
    |_______

    |
    |
    |____ _ <- rotated

    The rotation is always around the 0,0(,0) of the *objects space*.

    The order is probably why your rotation is messed up–if you are using matrices. And I don’t know if you knew this or not, but the dot product is equal to the (length of first vector times the length of second vector times the cosine of the angle). That is, V (dot) W where V and W are normalized is equal to the cosine of the angle.

    I hope that helps a bit. (it’s only scratching the surface! Try getting into Ray Tracing!)

  7. Ack, the pictures got messed up; took all the whitespaces out and cut some of the text.

    rotate->trans
    |
    || <-starts there
    |_______

    |
    |_ <-rotated
    |_______

    | _ rot

    |
    || <-starts
    |________

    | | <-translated
    |
    |_______

    |
    |
    |____ _ <- rotated

  8. Ah, the reason it’s getting goofy is because the author of that code is creating the matrix with hard-coded elements:
    Matrix rot = new Matrix(Right.X, Right.Y, Right.Z, 0, Up.X, Up.Y, Up.Z, 0, Backwards.X, Backwards.Y, Backwards.Z, 0, 0, 0, 0, 1);
    As per my description earlier, this only works on 1 axis. Didn’t catch that, sorry.

    The function you are going to need is
    Matrix.CreateRotationX(radiansForUp) * Matrix.CreateRotationY(radiansForRight);
    When you create multiply those results together, it should give you the proper rotation to point towards your second object.

    Rotation on X will point you up and down, rotation on Y will swivel you right and left. To find your radians for each, think on a 2D scale for each one.

    I think this should help you out.

  9. I was a computer geek 25 years ago (high school), and went on to get a BS in engineering. Today, I couldn’t program my way out of a paper bag or solve the simplest calculus problem. Your problems with programming matrices shames me. I vaguely remember using matrices in Basic and Fortran, but couldn’t even pretend to follow the discussion between you and Rubeus.

    Alas, that is the main problem with the “plug and chug” approach I took to many of my engineering courses. Once I had not used the knowledge in a while, I forgot how because I never really understood why the solution worked.

    If I survive the coming Barackalypse, I’ll be almost useless in rebuilding our technological knowledge.

  10. I use to program…15 years ago but that was Small Talk and I did some Sybase DBA work along with simple routines in OS/2 and SPUFI. I learned pretty quickly that I wanted to manage the egg heads rather than be an egg head. I couldn’t write a line of code today if my life depended on it… Interesting discussion, however! My brain melted half way through the read…

  11. Funny to see you talking about elliptic curve crypto; back in the early days of mobile devices, I had an internship to implement ECC on the ARM processor (that which is now in most smart phones and iPods), particularly with assembly language. It was pretty cool to see my code run in a fraction of a second when the common wisdom was that it took half a minute to do a key exchange on such a device. (I used the non-XOR configuration, since processors aren’t made to do XOR-style multiplications; it’d be faster on specialized hardware than addition, but not on a general-purpose processor.) I’m pretty sure, though, that even though they explain ECC geometrically, there’s actually no 2D or 3D involved. The geometry is for the continuous analogue, but ECC is discrete, so it’s really not 2D or 3D. I think. Like you, I implemented it instead of (or at least before) understanding it.

    I once took a robotics class at a university which usually had large class sizes (so Rubeus’ stuff looks familiar to me). Though this one started out with well over a dozen people, by the time we were done with 3D matrix algebra, it was down to three of us (excluding the teacher and his assistant). So this stuff scares lots of people!

    I never did take computer graphics, though….

    By the way, if you’re worried about how to make your code run faster, I’d recommend reading http://www.agner.org/optimize/

  12. Sounds like fun stuff, Frank. Kinda makes me want to go learn C# and start messing around with that stuff. I’m totally looking forward to any sort of game where you get to kill liberals and/or monkeys.

  13. You guys would work well on my project teams. I always tell my programmers “you start coding and I’ll get back to you when we figure out what we are suppose to be doing here”… It always get’s a few nervous chuckles out of the older guys and a few quizzical expressions from the newbies…

  14. The only help I can give you is suggestions for kick ass game Ideas. First idea is a game about a left leaning superhero who by day works for a group called Today Our Future United (TOFU) helping peole too lazy to help them selves. but by night uses his mutant powers as the “Flaming Liberal. Dressed in his Tiedye Greatfull Dead shirt and berkenstocks, he strives to make the world into something of Berry Goldwaters nightmare. Saddly his only power is to spontainiously catch on fire, and scream in aginizing pain. It’ll be funny and liberals will never know you are ripping into them.

    The next would be a rewrite of a old Nintendo classic, “The Adventures of Bayu Jindal”. Just take the old game of Bayu Billy and super impose Bobby Jindal’s head. Then change the story line to have him save Lousiana from overspending and massive coruption. I’m guessing it will be really popular in 3 years.

    Yeah I suck at math and am too lazy to actualy learn programing. This is why I work for the government.

  15. calbear:

    The XNA framework runs on C# and DirectX 9. Making C# fast is a whole different beast from making C++ fast. C# is slower than C++, but not as slow as Java. It’s like that because it has a sort of virtual machine setup like Java does, but it’s more abstract and more virtual than Java’s so you get the portability (to other systems with the framework) and more speed.

    Now XNA is not the fastest running game ‘engine’, but it is one of the easiest and most intuitive systems I have used making development time much quicker than C++.

  16. I have no idea what this thread says.

    If I survive the coming Barackalypse, I’ll be almost useless in rebuilding our technological knowledge

    Don’t worry HCG (and seanmahair): they’ll need the 3 of us when there are latrines to be dug and jobs that programmers won’t do. 😉

  17. I still consider myself a CG artist even though I flunked out of college whilst pursing a BS in animation and am not all that highly skilled at present.

    I know my way around GIMP and Blender, so if there is any serious consideration to be made in making a game, perhaps I’d like to participate to some extent.

  18. Good luck – I’ve been toying with writing a game myself and you’d better just go get your Calculus (and Physics) book off the shelf, dust ’em off, and do all the learning you were supposed to do in school. 🙂

    On another note, there are other GDK’s available. One I’ve been toying with is irrLicht. It’s free and platform agnostic. Another is DarkGDK from Game Creators, which is MS only but I think you can get it free right now through MS as a promotion for Visual Studio 2008. They both simplify some of the stuff you are trying to do.

    One idea is to create a ray that goes from the center of your cannon to the center of the target and align the matrices of your cannon with the ray. I have no idea if it would work, but it sounds good.

  19. Bwahahahaha!! type geeks! type! Everyone knows its marketing where all the fun and money are! So slave minions! slave! There is golf to be played, hands to be shaken, and pokets to be picked, er I mean, sales to be made! Bwahahaha.

  20. Pffft.. Childsplay.. Think that’s tough, wait til you start working in 4D… Oops.. wait.. I’m not supposed to mention that.. You guys havent discovered it yet and by mentioning it I might totally change the time period I came from… Just pretend I never said anything..

  21. Frank, if you do decide to try making a 2D game, consider taking a look at BYOND (add .com for the website). I have been using it for years and it’s very programmer-friendly, plus it’s free. It does everything except reconstitute blended puppies.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.