On a whim the other night I finally registered momopax.com, just short of one decade after Jules and I decided to start labeling our collective game efforts with that name. We have recently started chatting about creative projects again after a long quiet, and this is our new outputzone.
As it turns out, OpenGL loves to check for errors after every call. This makes you spend about double the time in OpenGL every frame. We were going kinda crazy trying to figure out what the problem was; I assumed it was my fairly elaborate collision detection. But running the Python profiler exposed the truth, and now we’re at a happy 30 frames per second again.
We have made lot of progress in the past few days.
Thanks to my coworker Andrew, we finally got Python and its dependencies properly set up on Julian’s MacBook so that he could run the game himself. Before that, were having to rely on making prebuilt copies on my machine whenever anything changed. Considering how simple and approachable Python is designed to be, setting up packages and installing things is a giant frustration.
Jules convinced me that we ought to increase the map size by a lot; we now have tons of tiles to work with. Levels that take several minutes to work through are now more possible.
After finding dual-stick Robotron controls unwieldy, and unable to agree on a tap/hold scheme, we decided to offer *both* of the tap/hold schemes. Tap either button to fire in the direction you’re moving; hold the Jules button to maintain your firing direction as you strafe around; hold the Fet button to halt your character in place and shoot in any direction.
Adding a hit stun effect to the enemies when you hit them was a big step in the direction of making Paraplu feel like a game. It’s a tiny thing, but seeing an enemy shake back and forth and halt for three frames is quite satisfying.
Until today, the only way to finish a level was to kill all of the enemies in it. Of course, with our new infinitely enemy-spewing doorway thingys, there would have to be another way. I set up an objectives system that allows us to define any number of different conditions for beating a level.
In the process of testing out the “get a particular item” condition, I became stuck inside a rock. This has been going on since I put together the obstacle collision, and I decided to attack the problem. It turned out to be more difficult than I’d expected. At one point I had a crazy system that checked how many character pixels were overlapping with the obstacle, and compared it to how many would be overlapping were the character allowed to continue on her current course:
In the end, I just did a simple series of four checks (which I originally deemed too tedious) to analyze the x and y components of the character’s velocity, and stopped either one if following it would result in a collision. This lets you slide along an obstacle if at least one of your axes of motion is still valid.
Hi! Tonight I implemented a bunch of stuff to add flexibility to our map objects. When an object is added to the map, it checks a dictionary of dictionaries of dictionaries to find out if it should have any special attributes. One of the possible attributes is an “initStep”, which is the name of a function to call one time when the object is created. This gives us a free pass to do anything we want with a new map object: add it to some special sprite group, give it a weird behavior, and so on.
The initial motivation for this was to be able to create crazy puzzley situations like an enemy spawner which constantly sends dudes across a space toward a hazard that kills them. This creates a sort of doorway of enemies that you have to blast through. Actually the hazard will kill any mortalGuy that comes in contact with it; that includes both enemies and the player…
Today I worked on the hit points system for the main character, and the damage and dying mechanisms that that implies. Now the character has a hit point total, can be hurt by enemies and their projectiles, and dies when reaching 0 hp. Pretty basic stuff, but it was taken out for the sake of simplicity when I copied the ship code over from Soft Landing, and it needed to be rewritten.
Thankfully, the code to do all this, including flashing Vivienne red and making her invincible for a short mercy period after taking damage, was quite easy. It only took about half an hour, and worked the first time I tried it!
This should pave the way for building our first few fun, challenging levels, now that the presence of enemies in them actually has some consequence.
Over the past couple of days, I’ve done a lot of work on the equipment system. It was harder than I expected, but now you can equip various types of items that determine how your attack works. This is the core of the “algorithmic shooter” concept we originally devised together. In Paraplu, your attack is calculated based on three types of equipment. From our internal planning site:
– Weapon determines ROF, bullet type, range, damage.
– Costume adjusts ROF, damage, range. “Firing upgrade”. No costume should be objectively better than another, and most should offer similar factors of improvement. We want costumes to be valuable and interchangeable throughout the game.
– Accessory adds special effects of all kinds: number and direction of bullets, explode on impact, swirly paths, poison, fire, et cetera. “Meta upgrade”. Practicality of these can vary widely.
I have got the mirror system working, basically. This is how you equip weapons, accessories, and costumes. It was remarkably difficult to make a system that simply opens up a menu, then opens up another menu based on the item you chose. Those old NES RPGs full of nested menus must be a lot more sophisticated than I ever imagined.
But, in the process of getting that working, I really refined the whole concept of the focused (foremost) interface box, and the management of interface modes. Now the game always knows pretty clearly what is going on, and it should be easy to add more multiple-step interfaces.
I also factored some code out into functions, for doing common things like figuring out the selected item in the foremost menu, constructing the syntax needed to show an item’s icon and name side by side, and unfocusing the focused box.
Not a whole lot of work today, but I’m trying to keep some momentum going. I added a wardrobe object (with awful programmer art, of course) to accompany the cabinet object in the atelier. Now, different types of items are stored in the different containers: materials in the cabinet, and costumes in the wardrobe. We’ll need to add a vanity for accessories, too, once we have some of those.
It occurred to me lately how strange it is that at work I’m a designer who keeps his hands off the code, and in MOMO PAX I’m a programmer who keeps his hands off the graphics.
I had a nice time coding in the little food court at Whole Foods today.
– After several hours of work, taught our most basic enemy how to avoid obstacles. This is way harder than it seems, and I had to write in a bunch of psychedelic drawing effects to visualize what what happening in the code. It turned out I was telling it to go in a direction only if any obstacle existed that it wouldn’t hit, rather than if there were no obstacles that it would hit.
– Fixed a weird string-length bug that became apparent when resetting the description box for an item.
– Started moving the main character to a specific spot on the screen when moving between areas, so that you can’t arrive stuck inside a bush.