Quirks of Low Level Coding

As seems to be becoming a habit, I just tackled and beat a significant bug (which I’d actually noticed much earlier and had put off fixing until now) so I decided to write about it. The “moral” from this one seems to be that that low level coding will invariably have interesting little quirks and anti-features which will always be lurking in the wings to knock experienced and novice coders alike off their feet. This bug (like the last one) was in the grid cell code. As I have mentioned previously, this project involves a 3D grid map with various things moving in freeform around it but still interacting with the grid for some things.

In my mind map of future progress, the interaction between freeform objects and grid cells will mostly come about through environmental effects like airflow, gravity and toxic gasses. Without going into too much detail on gameplay (that’s for later), I’m still playing around with how best to handle it. My current implementation is a holdover of my old habit of premature optimisation, where each object that needs to check the grid will periodically (or after moving) recheck with the MapSuite to see if their latest position has resulted in a cell change – if it has, inform their old cell that they’re leaving and inform the new cell that they’re entering.

This is to replace a system where the objects simply grab and reapply the environmental settings every update regardless of cell changes or the like. The advantages of the new system is that (obviously) there’s less lookups, but also that there’s a more clear chain of communication for events such as gravity/atmospheric changes to be passed down from a cell to it’s contents. The only appreciable disadvantage that I see with it is that if I don’t account for all circumstances where something could move, it won’t update it’s cell location which will have weird effects with the aforementioned events system. I’ve got the periodical recheck as a failsafe in case the delayed cell changes miss out on something, but that’s still a symptom of the old system where there is a redundant system which may or may not be necessary. Tradeoffs, I guess.

Just quickly while I’m on the subject of the cell map, I thought I’d lay out how it works under the hood. It’s relatively simple, with all the cells being stored in an STL unordered_map and indexed by a hash of the cell’s co-ordinates (which are normalised to integers, but I’m still a little wary about possible floating point error). I’ve also got a plan in the back of my mind to have additional collections of cells where they’re sorted by relevant attributes, eg cells that temporarily need regular environmental updates.

But the bug! What was the bug? Well I mentioned it was a somewhat low level quirk of C++, to be specific in how it handles numbers. As I mentioned above, freeform objects determine their current cells by taking their exact position as a float vector and normalising it to an integer vector with an offset of (0.5, 0.5, 0.5) to account for rounding. For simplicity’s sake, the way I was doing the rounding was just casting the float to an integer. This set of warning bells even before I had written the system the first time, but I decided to try it out and see how it went.

Turns out that when casting from a float to an integer, values above 0 round down but values below 0 round up – which results in a whole extra anomalous tile on each axis when trying to find the current cell that objects are in! The way to fix it is just to add a correction value of -1 when casting from float to integer for values below 0, but I was getting some weird bugs with gravity before I found it almost indirectly while working with the player code.

Here’s to hoping that the bug where rays of artificial gravity being projected from a tile adjacent to where they were supposed to originate from will disappear! Speaking of improbable bugs, maybe my next entry will cover how I found and fixed the null pointer error while assigning bullet quaternions… better not. I might never write an entry here again 😉

Advertisements

Overly engineered redundancy

I just had a fairly textbook bug pop up, so I thought I’d write about it while it was still fresh on my mind. Unlike most “interesting” bugs, this one was both easy to locate and easy to fix – but it came about as a direct result of the way I had setup a system.

In this project, I have a 3D world divided up into cells and each cell can have a single structural frame or be empty and in order to place a frame in a cell, there has to be a frame in a cardinally adjacent cell. I have a global manager which handles creation and deletion of these frames, and I was investigating why creating or deleting frames from cells wasn’t properly triggering the creatability/deletability of frames in adjacent cells. It turned out that a reference to the cell itself wasn’t being passed around, and in fixing that issue I realised there was something I was forgetting – I hadn’t actually setup the system to ensure that there could only ever be a single frame in a cell.

So what I did was added a check to the manager’s creation function for any other frames, and if there were it would delete them. Unfortunately, I placed it after the new frame was created but before the new frame was initialized (I’d setup delayed initialization as an option to make larger or frequently resizing worlds lighter on the processor). Obviously that was completely the wrong place to put the check, as it not only attempted to delete the frame I’d just created, but it hadn’t been fully created so it was crashing every time.

Easy find, easy fix, simple mistake, but I see it as a direct symptom of a system that I engineering to not only be capable of everything I wanted it to do now, but also everything I thought I would want years down the track while still making it simple and modular enough to be expandable and adhere semi-strictly to OOP (or my garden-hedge understanding of it).

After about 12 hours over the past few days spent restructuring and cleaning up how frames and cells are handled, I’ve been reconsidering my policy of rewriting systems to be better under the hood. As a self-analysis process, this has been ongoing ever since I discovered Unity and Winforms coding over a year ago (quote “You don’t need to make the code good, because this is scrub coding land”) but I’m still on the fence with my conclusion – that a combination of the end product and the goals for making it are what justifies the approaches, procedures and technology used.

In case of this project, I wanted to make a well designed and robust system to account for complex gameplay and in doing so improve the quality and speed of designing/implementing systems that I work on… while working on it in my spare time. In other projects, if I wanted to create a game with specific gameplay and timeframe to work in, then I clear deliverables which override my desire to learn and work at my own pace in doing so. Where this has been an issue for me in the past is with university projects – it’s a learning environment where I want to maximise the convenience of being able to make frequent mistakes and effectively analyse them, but still succeed (the latter was essentially my approach for final project).

In a commercial environment it strikes me that the deliverables would be the goal, but for viability of long term usage/expansion the system under the hood needs be clean and maintainable. Anyway, I guess it’s just a line which everyone needs to work out before they start.

Ludum Dare, all over bar the shouting

It’s now a few hours post submission cutoff, and I’ve had a chance to play several of the other submissions and see the quality of people’s work. Now (as I was before we started) I was impressed by the number of people willing to try weird and outlandish combinations of technology (I’ve seen several games deployed solely to Linux, at least initially). My favourite would have to be one of the afternet#ludumdare halfops who made some kind of simple platformer in assembly, I think it was for a TRS Arm.

As of writing, there are over 1700 entries so I couldn’t possibly hope to sample more than a tiny selection, but of the ones I have I was quite impressed by Undercolor Agents (pick up weapons, shoot colour blocks to return the world to monochromey goodness, check it out here) and one I think was called Minima, where you had to flip perspective and move a cube around (can’t find a link).

My own humble submission can be found here, and although the end result is not something I’m 100% happy with, I don’t think it’s possible to do a game like that in 48 hours. Following a few desperate hours testing before submission cutoffs, I managed to get some valuable feedback – the gist of it was that my game was simply too confusing. My “interpretation” of the theme was that I would minimise player teaching, and attempt to get them to teach themselves. I definitely overestimated my ability to convey that, but of my testers who stuck with the game long enough they figured out how to get far enough to win. Of note I think, was stumbling across http://www.bfxr.net/ (before I found out about the list of tools suggestions, where it featured prominently). BFXR speedily gave me some neat retro sound effects which I could slot into my game, and coupled with additional HUD feedback and the two tooltips, I was able to overcome some of the drawbacks.

I think the main thing LD48 did for me was opening my eyes to the wider world of indie gamedev. I wasn’t expecting so many people, so many wild ideas and crazy technology. It was inspiring to hear people talk about using OpenGL/DirectX/LWJGL/SFML/Low level Graphics Library #279, so I think for the next compo I’m definitely going to attempt C++, most likely with SFML and one or two other libs (game enough to try Chipmunk again? maybe). Judging is on for the next three weeks, so I’m definitely going to be exploring more of the submissions over that time.

Ludum Dare 3/4 done!

This post is actually a few hours late, but I got sidetracked by various things. Progress hasn’t been as good as I’d like, but I’m still fairly happy with where the game is at. Gameplay has been refined further, GUI/menu/level handling have been improved and some new (less horrible) textures have been put in.

My plan from here is to grab a few hours sleep, then come back and really hammer out level generation/difficulty. At this rate I’m not going to have any audio, unless it’s something I can track down from the internet in 5-10 minutes (is that allowed? have to check the rules).

Build 3 is available from dropbox here, and there’s an embedded web player available here. My plan from here is to grab a nap, then spend the last few hours trying to work in some feedback from testers – my next post will be after I’ve submitted I guess.

Ludum Dare 50%

It’s now over halfway through, and I’m finding myself not only well rested and unstressed, but also reasonably confident about the game (it’s even kinda fun!). I uploaded the source to Github last night, and test build 2 is available from dropbox here.

Most of my progress has been ideasmanning it up as well as tweaking and polishing before I get down to the serious business of level generation and UI. I’ve come up with and discarded a bunch of minor feature ideas, and slowly the game has morphed into something much more playable than what I had last night. Main things I’ve been tweaking include the goo interaction (with other goo). The current state is that it slowly moves off other goo, and periodically merges with them to form bigger goo. They also cancel out enemy goo (like matter/antimatter). Also of note is that there is a basic menu screen, a spartan (but functional) UI and a “Win” condition (but no lose condition).

There’s been some ripper gameplay bugs, but thankfully I cleared them out without too much trouble. Unity’s convenience of allowing me to focus almost solely on gameplay coding is really coming out, but I miss working in C++.

Ludum Dare 25% mark

I’m in, and a quarter of the way through! This is both my first Ludum Dare and my first 48 hour Game Jam, so I’m taking things a mix of lightning fast and slow + steady. The theme is Minimalism, and despite a bit of grumbling I thought I could do some neat stuff with it. My first playable build is complete (nothing fancy like menus/start buttons/win messages, that’s planned for the last few frantic hours).

Build 1 screenshot

Download from dropbox here.

Shuriken wrap-up

The project has concluded now, and the final handover has been finished. At some point, I might write up a proper post mortem but I think the main thing I took away from the game is that now enough prep work was done to familiarise myself and the other coder with the technology – and thus to determine whether we made the right choice early in development (or even before it starts!).

I say this, because looking back on the project the main pitfall was that milestones were consistently delayed or missed because the underlying technology wasn’t behaving as expected, or there simply wasn’t time to familiarise ourselves with some minutiae of function to achieve the desired result. The main culprit for “not behaving as expected” was the physics engine, or rather the physics wrapped – we were using the OgreBullet wrapper around an (eventually) out of date version of Bullet, the initial idea of which was to smooth out and speed up development of the core gameplay. Just “slot in” Bullet physics to get character control fairly polished early on, then focus on pathfinding / AI / graphics for the majority of the rest of the project.

The main problem with OgreBullet (apart from it’s outdatedness quickly becoming a problem) was that some functions (raycasting) simply didn’t work, or behaved completely unintuitively (rigidbodies locked the parent scenenode to their position, and did not nicely handle any form of manual transforms to be applied). The icing on the cake was that only by digging through the OgreBullet source and constant testing of different implementations was any real progress made as documentation was non-existent. Apart from that, Bullet was nicely featured and I’ll definitely use it again in future (in fact, I am using it right now).

It should be noted that a lot of time was also spent mucking around with Recast, and getting NPC movement to mesh nicely with the character controller of the week. This one was more a fault of “not enough time familiarising with the technology” than “in hindsight this tech was not the right choice.” Dynamic navmesh generation is pretty complex, but we managed to get it working and tweaked a couple of months into the project (as evidenced from various demo pictures I’ve posted earlier).

I’ll discuss different implementations we tried, and particular methods we ended up using in a later post, but this project really rings home the mantra “You learn more from your failures than your successes.” No-one would say that this project was a complete success, but I don’t think it was a failure either. We produced a sharp, good looking game with mostly smooth gameplay, and given that we were absolved from the requirement to produce a commercial success (Shuriken was a final year university project) at the end of the day the goal was to produce a game, and target it for commercial release.