Okay, after a few nights of good sleep and days not thinking about coding, it’s time for a reflection on my efforts during this past weekend’s Ludum Dare. (For reference, my entry can be viewed here and played here).
As was evident in my earlier posts, I didn’t really have a clear idea of where I was going, design-wise. Even on the last day, I wasn’t quite sure where I would end up, though it was of course much clearer how little time I had left to add any additional mechanics. But I didn’t let that lack of direction prevent me from continuing onward anyway, so that was a success of sorts. All too often, if I don’t know where I’m going, I fail to go anywhere at all.
I think the most important single step I made in this regard happened on Friday night, after brainstorming had failed to conjure up any ideas that really grabbed me and felt strongly compelling. I decided that before going to bed, I should at least get a little code written up to implement one technical element that Jeremy had suggested: ballistic ball physics with a 2D presentation, but with a distinct shadow on the ground to help the player distinguish 3D position, a la the old school R.B.I. Baseball.
The psychological effect was that once written, I was disinclined to change my mind and drop that as a core element, since there was so little time available to work with. So instead of exploring other game mechanics which wouldn’t need to represent the ball in this fashion, I continued with this design constraint. When I added the math to make the ball bounce on the ground, that constrained my mechanics even further, and again, instead of scrapping it if I didn’t like where the mechanics were going, I just continued onward regardless.
Such an attitude didn’t exactly instill in me the greatest degree of excitement and enthusiasm, but it got me to make something, and that was my chief goal for this jam, simply make something that is vaguely complete and playable.
On the technical side, I may have shot myself in the foot by insisting on using parabolas for my ball physics. At any given time, I know the constants for a particular trajectory’s quadratic function, and can simply plug in the time parameter and get the ball’s position. It’s precise and isn’t plagued by any flaws in a numerical integrator. But what drove me initially in this direction is that I can work backwards from a desired target position in the field to the initial angle and velocity at the moment the ball is hit by the bat using conventional algebra.
But what I should have done was to take this reverse math and just translate it into a standard rate of change of x, y, and z at time zero. During each frame update loop (which I did design to work at a fixed rate), just use a trivial linear equation to update the position of the ball, and a trivial numerical integrator to update Δx, Δy, and Δz based on gravity. It would have been inaccurate, and it wouldn’t reach the exact target chosen, but it would have easily been good enough for a prototype. More importantly, all my intersection code for the ground, the back wall, and any additional obstacles I might have wanted to place in the field, would be much simpler. Intersecting a trajectory that is represented by a straight line in the x-z plane and a parabola for y is a bit messy. Not so bad for the ground, where I only needed to solve for the root of the quadratic function, but worse for the back wall represented as a cylinder, or any numerous other shapes I might choose to use. A straight line is much easier to intersect, and there are plenty of ready-made libraries and code snippets available to do such intersections against a wide variety of shapes.
Really, maybe I should practice using a mature physics library, and just use that in the future when I want to make a prototype involving physics. I guess my only worry is that it wouldn’t be flexible enough to allow me to implement exactly the mechanics I want. But reflecting on the physics engines I’ve used in the past, I know that this isn’t the case. It might be a little trickier to figure out when working with a complete game engine that has physics already integrated, because the architecture of the game engine sometimes presumes too much about the proper way for physics to operate within a game, and any deviation from this, if even possible, might need some code contortions to pull off. But from my experience, physics engines on their own don’t often suffer from such architectural limitations.