Between Scylla and Charybdis Developer Diaries, August 2013
The turtle’s locomotion is comparatively complicated. After bloating up the turtle with 10-15 instance variables relating to the state of his movement, locomotizing, propelling, boosting, stunned, etc., the need for better control of this situation became evident. The most obvious solution was to manage his movement with a finite state machine. I always think past the most obvious solution though, in an attempt to find something better. This is complicated by Game Maker, because when everything is sub-optimal, there’s no such thing as a good solution. Even my FSM implementation in Game Maker is super fuckin lame.
Anyway, if you look closely at the First Look video you'll see that sometimes, when the turtle is making a tight turn, he kind of flickers a bit. This is because I prevent propulsion when the turtle is, at present, more than 45 degrees off his target, and he will flicker around this angular difference while switching between propelling and not. I fixed it today, by adding a “tightly turning” state into the FSM, where before it was handled with an instance variable. Of course, the FSM solution isn’t functionally equivalent, because the prior solution, using the instance variable, was broken, through inconsistent management. Moving the state and functionality of the “tightly turning” or “blocking propel” state into the FSM accomplished my original intention with little fuss. The real problem was that the frame that I was freezing the animation on during the tight turn was not always the same frame that I would change to upon entering the propel state.
The turtle’s locomotion has been one of the things that I've focused primarily on for the past several months, the other being the whirlpool and water physics. With the design being so stripped down, and with the player’s interaction with the game limited to the control of the turtle, it’s especially important for me to get this right. The way the turtle can whiz around smashing into things has always detracted from the gamefeel to me. Today I added impact damage to mitigate this, in the form of shell cracks that form when the turtle slams into hard objects. They do not actually form gradually now, but it is my intention for them to do so, when appropriate. If you slam into something really hard, your shell will just break open, and your turtle organs will ooze into the sea. Or at least, that’s how I see it in my mind. Lux may think differently.
Looking back at my marked out todo’s, I can’t remember doing most of them. I could certainly never recall them if asked “What did you do today?” I apparently fixed a bunch of bugs and worked on some misconceptions that I had about the breaking of the turtle’s shell.
I've had pausing since the beginning of development, mostly so that I can get a closer look at things as they happen. Game Maker isn’t the most transparent about how it goes about doing things, so that’s probably the extent of the global time control that I'll ever find it worthwhile to have. Using physics_pause to pause my Box2D simulation resulted in some (explosively) buggy behavior on unpausing the simulation, so I tried to deactivating each instance’s participation in the physics simulation manually, and this seems to work as expected.
In some places, I manage the alpha of particular objects using draw_set_alpha. Dealing with alphas in this way probably means that you want to restore the old global alpha after you're done drawing whatever it is that requires a special value. I was neglecting to turn this back to the right value in my drawing of the full-screen lightning effect that occurs during the storm sequence of the tsunami level, which was causing anything drawn AFTER the lightning in each frame to be drawn with the same alpha as the lightning. By chance, the only thing drawn after the lighting, as GM decides the drawing order in some undefined manner, was my debug menus. That is, my debug menus were frequently invisible.
Managing intentional movements with realistic forces, as opposed to something more instantaneous and controlled, is quite difficult to get right and generally requires one to handle and calculate steering and movement forces in rather unnatural ways. With BSAC I'm somewhat lucky, because the character being in the “water” gives me a lot of leeway with regard to the looseness or rigidity of the movement. The turtle need not stop on a dime, and in fact, if he does not, it looks much more realistic. I do not apply any breaking forces to the turtle as he rotates his body toward the player’s mouse pointer, I simply diminish the force that’s being applied as they approach the correct angle. This can create a bouncy effect though, with the turtle constantly overshooting, turning back, overshooting, and turning back. I've tried to make his control more precise in the past, for instance, nearly stopping on a dime when his alignment becomes correct, but this ultimately doesn’t feel aquatic at all, but rather bus-like. To mitigate this, I've added a range within which the turtle makes no attempt at all to align with the mouse. This range is small enough so as to be imperceptible in practice, and does prevent the bounciness without feeling unnatural, but I can see how this might make the turtle more difficult to control. I don’t think it does, but I'm open to other options if this technique becomes problematic.
Ever since I added aquatic drag to the turtle, I've had a bug that I call the “molasses bug,” that would occur at unpredictable times in the bottom left-quadrant of the whirlpool, whereby the turtle would for a short period appear to be stuck in molasses (wow!) I was able to reproduce the bug in another portion of the world, and with the help of some debug-drawing of drag forces, was able to fix it. Really though, I experimented so much during this process that I'm not sure what fixed it, or, indeed, if it is even fixed at all. Time will tell.
And lastly, I thought for a lifetime on collisions, as they relate to the shell-breaking mechanic, and especially as collisions are implemented in Game Maker. Unfortunately, my initial implementation was prone to some weirdness that I hadn’t considered. It can’t handle the shell breaking against stationary objects like walls or oceanic cairns. I've resolved this issue somewhat, but not because Game Maker was any help at all. In fact, it’s missing plenty of useful, even essential, capabilities of Box2D. For instance, one cannot determine the force of an individual collision, but rather must discern it from changes in velocity. This would be fine if we were able to discern which of the individual collisions with any particular object on each frame actually imparted the impulse. Alas, this cannot be done. My hacky workaround is to simply assume that the momentum is basically conserved in the closed system of the turtle and the things colliding with the turtle, but this isn’t strictly true, as there is a constant external force acting on both the turtle and the debris in different ways. Plus, there’s linear damping, for which I haven’t been able to find sufficient documentation for, as far as implementation goes. I suppose I can look around the source of Box2D, as I have countless times in the past, and try to figure it out, but there’s no guarantee that Game Maker implements it in a sane or documented way anyway, but I just don’t have time for this shit. The first colliding debris of this frame, with a change in momentum that matches most closely with the impulse imparted on the shell in this frame is considered the be the item that actually generated the cracked shell.
Ideally I wanted to have “resting collisions” capable of boxing the turtle in and slowly crushing him to death, but this isn’t quite possible just by measuring changes in momentum (mv=0). I would need force calculations for that, and I don’t see how that’s possible right now.
Yesterday and today I worked on adding a grabbing mechanic to the game, where the turtle can grab debris with his mouth, and then shoot it out at high speed. I added this because I felt in need of another active ability for the turtle to possess, and it seemed to serve several purposes. However, because it wasn’t added in response to any particular need of the gameplay, I'm left without really knowing how best to use it. In fact, now I have to design things in response to the addition of this mechanic, which feels strange having worked until now in a “whirlpool first” direction. I made the whirlpool, then I balanced the debris, then I made the turtle, in response to the whirlpool and then the debris. This is reminiscent to me of the order in which you often mix music, starting with the most important elements first, and balancing the track volumes in order until you get to the least important instrument and section. But now I've added another instrument to the song, and I need to rebalance the whole song in order to get the new bit to sit in the mix just right.
Witnessing emergent behavior is intense. Today I discovered two naturally occuring events resulting from my thorough use of the physics engine that I had never before seen. First, a tornado broke my shell. My back was resting on a beam, a tornado passed close by, and the pressure of it pushing me against the beam broke my shell. Then, I discovered that grabbing onto a concrete block with the turtle’s mouth greatly increased his mass, so as to act as an anchor, and slow the turtle’s descent into the eye of the whirlpool. I think this could be an advanced play strategy, but I haven’t actually found it helpful yet. The subsequent launching of the concrete blocks, however, is rather more useful. An advanced player could also catch debris in their mouths if a collision is inevitable. This supposes that a turtle’s jaw is rather strong, however, and I don’t know if I like that. Really, I don’t know if I like the whole grabbing or shooting thing at all yet.
I'm about to start working on an indirect system of lives/health. You collect barnacles, or kelp, or some tasty fish food on your back, which causes fish to start swimming on screen. If you go collect the fish on your back, they will stick with you and sometimes protect you from harm. This feature, unlike grabbing/shooting, stemmed directly from the gameplay. I wanted to encourage a player to move to places where they otherwise might not dare, in the pursuit of some reward. This keeps the player moving, and discourages camping.
I just finished getting a basic school of fish together, and now I've got to tune the fuck out of it until it looks passable. Balancing steering forces in isolation is difficult enough. I don’t fancy balancing steering forces in the presence of whirlpool forces. I'm going to work on different weighting schemes for the steering algorithms, and hopefully I can get this working today, which would keep me on schedule, because I need to work on my porn site this weekend. Lux is going to record our second BSAC video next week, and I'd like to have as many visibly substantial changes in place as possible by then.
It’s been a real slog lately with all of these new features. They're all in an incomplete state, because I'm not exactly sure with how to progress with any of them. I think I need to start making another level in order to start seeing things from a different perspective. I hope to be able to roll the things that I learn from making an entirely new level back into the first level. It will also be a good opportunity for refactoring things to work in a more reusable way.
Going back to basics was a great idea. The first new pieces of gameplay I added into the new level, icebergs and wind, were immediately good, which is much more than I can say about the last few things I've worked on. Icebergs are huge, semi-stationary objects that rise from the deeps that serve to take up large spaces of the screen, obstruct and backup incoming debris, and otherwise make it difficult to navigate without breaking your shell. Wind works with icebergs in order to push you into them and break your shell. Wind is a full-world effect that applies force to all objects in the world. Wind forces combine intuitively with the ever-present whirlpool forces.