Category Archives: Programming

Fixing the graph – planning stage

Goal number the last on my roadmap reads: “Decoupling the navigation mesh from specific window sizes”. What on earth does that mean? I’m glad you asked.

Thus far I’ve been programming and debugging my program using a fixed-size window at 800 by 600 pixels. Unfortunately, when I wrote my Graph implementation I was all about magic numbers and not so much about planning for the future. Consider the following code snippet:

At some point I got it into my head to store exact locations in the graph. Now, there’s not anything necessarily wrong with this…as long as

  • I never need to change the window size or resolution
  • The view never changes

Obviously this is unacceptable, and really should have been fixed by now. I need a plan!

Currently the Graph class is made up of:

  • The Walkable list; a set of integers acting as boolean (0/1) variables (see here for why a vector is A Bad Thing)
  • The Node list; a set of Vector2s for positioning objects
  • The State list; a set of rectangles used to map mouse positions to nodes

Looking at this I realized that I really don’t need Nodes or States to be in there. After all, my pathfinder’s solver function only takes two numbers as arguments; the grid indices for the start and end of the path. At each step of the path, the pathfinder accesses the Node list with that step’s index and returns the position. I can easily strip this out and replace it with a simple function to convert a graph index to a Vector2. I’ll need a mesh to determine where on the screen the mouse clicks to signal the start of a pathfinding call, but I can most likely construct this on the fly.

No more delays. Time to get this done.

Meander: Roadmap

Meander is getting to a point where everything I anticipated having problems with has been resolved, which is a pretty awesome place to be. A year ago all my projects were dying in infancy due to my lack of programming skills. Now I find myself often without a challenging problem to push through, and subsequently not knowing what to do next. It’s about time I put together an actual list of goals I want to meet so I can call this this project complete.

I’m not including assets in my definition of “complete”. Eventually I’ll have a full complement of images, maps, sounds, in-game items, etc. But to call the Meander engine finished I’ll need to implement the following features:

  • Parallax scrolling
  • World objects
  • Inventories
  • Saving and loading gamestate (already implemented to a degree)
  • “Doors”, “locks” and “keys”
  • Animations
  • Branching dialogue system with drag-and-drop text support
  • In-game developer’s console
  • Sound spatialization
  • Decoupling the navigation mesh from  specific window sizes.

As I complete each item I’ll update this post with a link to the post detailing it.

 

Debug streams

So far I’ve been handling console output using std::cout, as such:

This is all well and good, but I want certain things to only appear on the console in debug mode. For example, I may need to see pathfinding data while debugging a map, but the end-user won’t want to see all that. Using the Quake-style cvar system I’ve implemented I had started to add debug output like this:

This works, but it’s a lot of typing I wish I didn’t have to do. Ideally I’d be able to check for debug mode and print output on the same line. Which brings me to my results for the day:

Usage is exactly the same as std::cout:

…with the notable difference that it only runs if debug mode is on.

Anyone who wants to use this code is welcome to it under the license of your choice. I’d love to hear if you find it useful.

dllhell

Porting Meander to Windows

Alternately titled: This is why I laugh when I hear people say that it’s hard to develop for Linux.

Warning! Extremely technical post! Skip to the bottom for the video.

Now that I’ve finished my GUI system I figured it was high time I get a Windows build done. Setting up a dev environment on Windows is about as painful as it gets, but it’s got to happen eventually. My journey begins!

I’ve already installed my IDE (Codeblocks with the custom Nuwen MinGW compiler distribution. I’ve already set up the SFML libraries, so I won’t be going into detail regarding those. The libraries giving me trouble are Lua and Luabind.

I downloaded a source package from my repository and attempted to compile the project without any changes. GCC throws up a few warnings I’ve never seen on Linux:

Meander\Meander\Actors.cpp|172|warning: converting to non-pointer type ‘int’ from NULL

But hey, they’re just warnings.

Then the errors start popping up.

Meander\Meander\Factory.cpp|28|error: invalid initialization of reference of type ‘const std::string&’ from expression of type ‘boost::filesystem3::path’
Meander\Meander\Factory.cpp|9|error: in passing argument 1 of ‘MN::Actor* MN::Factory::CreateActor(const std::string&)’

The version of Ubuntu I use (10.04) comes with release 1.40 of the Boost C++ libraries. Nuwen MinWG 7.1 comes bundled with 1.46, and it looks like the newer release isn’t backwards compatible. Ironically, the reason I went with Nuwen was because of the bundled libraries. Oh well, better add Boost to my list of libraries to compile. I’ll hit that one first.

Boost uses a build system called bjam, which is similar to cmake or autotools in that it doesn’t compile anything itself; rather it configures the build settings to whatever compiler toolchain you use and builds using that.

I copy bjam.exe into the boost source folder, open a command prompt and cd in.

C:\Users\Jake\Desktop> bjam –toolset=gcc

Of course g++ and gcc aren’t in my executable path. Silly Windows.

C:\Users\Jake\Desktop> set PATH=C:\Mingw\MinGW\bin\;%PATH%

C:\Users\Jake\Desktop> bjam –toolset=gcc

compiling…

5 minutes…
7 minutes…

According to the Boost website, compiling can take up to 20 minutes. While I’m on Windows I might as well play Half life 2.

After some fooling around in Ravenholm I check back on the build. It’s done! I copy the libs and headers over to my compiler installation, and reconfigure the linker settings in Codeblocks.

Meander compiles and links to boost_filesystem…and then this.

Meander\Gooey\WidgetManager.cpp|24|undefined reference to `lua_close’|
[…]
||=== Build finished: 50 errors, 0 warnings ===|

For now I’ll just comment out all the lines with Lua. It’s all contained within one class, so it won’t take too long. Recompile.

Another undefined reference to boost.system…time to figure out which of the five nearly identically named static libraries is the right one. Recompile.

Done! Still have those two warnings, but they’re not going anywhere. Time to run the game!

sigh…dlls again. Silly Windows. I copy every single .dll file from the SFML binary folder, just to be on the safe side.

Success! A window appears with graphics in! The menu buttons still don’t work because of the Lua dependancy, but that’s next on the list. In addition, my cursors aren’t changing when over buttons and textboxes, but that’s probably an easy fix.

Lua time!

Thanks to LuaBinaries, which I’d never heard of before, I was able to uncomment all the lua code and compile/link cleanly.
Clicking on a button still causes the program to freeze and stop working due to the fact that the button’s command hasn’t been bound to a function yet. Next up: Luabind!

My initial searches for variations of “luabind mingw static lib” don’t result in anything helpful. Eventually I created a CodeBlocks static library project and followed this guide, hoping that the changes between luabind 0.7 and 0.9 haven’t broken anything. Now to copy the headers and the library I just compiled to their respective folders, compile and run.

Unexpected success! GUI buttons now execute the correct actions, and all is well. The cursor still remains its ugly arrowish self no matter what element it is over, though. Time for some *shudder* WINAPI programming.

One of my goals in this project is that it compile on any platform without changes. In the case of system-specific code I make an exception, but only if the interface code is the same. So having #ifdef SFML_SYSTEM_WINDOWS in a class is fine as long as the member functions are identical accross operating systems. Ultimately the GUI::Cursor class should only be modified through the SetCursor(CursorType) function. Time to get my hands dirty.

Every time I see a piece of WinAPI code I thank God I’m not paid to program with it. It’s ugly as hell, and the names always make me feel like the guy who came up with them had a bad speech defect. The windowhandle type was inspired by the sound you make when you get punched in the stomach. HWN…D

But I’m a perfectionist, and right now I need to make sacrifices for the greater good.

The class I’ve been using to manage my cursors was originally posted over on the SFML wiki. Before I started porting this project to Windows it was about %70 new code, since the original was hideously buggy. I assumed that the windows-specific code was more or less in good shape, but I’d never tested it. Turns out that code was equally buggy. Sigh…

Greivances along the way:

The function LoadCursor() sets the cursor style, and the function SetCursor() applies it to the display. Why? One function should be enough, no?

Also, it seems that if you don’t handle the cursor in precisely the right place the cursor will flicker back and forth between what it should be and the default arrow.

But in the end I prevailed, and with any luck I’ll never have to touch that code again. Upside is it’s now been 100% rewritten.

Thanks to the cross-platform design of SFML I didn’t have to make any other changes. The program runs exactly the same as on Linux as long as I disable the console. (protip: printing to the console on Windows is incredibly expensive in terms of CPU/memory)

Aftermath of the project:

  • I learned enough about WINAPI to hack together a solution that I had solved elegantly and simply with xlib.
  • I compiled my first static library, which made me feel awesome.
  • I can once again say that Meander is cross-platform (except for Mac, but I don’t know anyone with a Mac).
  • Now that I’ve made visible progress I’ve put up another demonstration video! The link is here.

Edit: I probably should have mentioned that all this effort was neatly sidestepped on Linux by typing the above in a terminal window:

sudo apt-get install libboost-filesystem-dev liblua5.1-dev libluabind

I like doing things the simple way. :)

Meander engine teaser update

Everybody loves screenshots, right? Well, I do at least, and this is my blog. So here’s a screenshot of the GUI for my game engine. I’ll have a more technical/in-depth post after I get a video done, but I wanted to put this up right away.

Ladies and gentlemen, allow me to introduce… “Gooey”!

More later. :)