The Player…

Spent a few hours this evening beavering away on my Amiga Cracktro. Tonight’s mission: working out how to add music!

The defacto standard for Protracker mod playing seems the be The Player, which will pack and convert mod files, and is reputedly the fastest thing around.

Wasn’t the fastest thing to compile, though, so I’ve now had a whistle stop tour around the innards of AsmPro and a beginners lesson on how to get someone else’s assembly to compile.

Lesson of the day: don’t initialise The Player with your audio channels switched off (if you’re an idiot, like me). You’ll have no errors, no sound and no fucking clue what’s going wrong.

Had to re-jig my startup code just a smidge get the initialisation in the right order, but it’s all working now, and I have a scroller with music!

Happy :D

CoreText & Rendering to an OpenGL Texture

One nice thing that I used & abused in iOS was it’s ability to render an NSString to a bitmap. This was great for getting lovely anti-aliased text, correctly spaced at whatever res you needed, and – bar the variable setup – was hardly any code:

// *snip*
CGColorSpaceRef colourSpace   = CGColorSpaceCreateDeviceRGB();
CGContextRef    context       = CGBitmapContextCreate(pixeldata, width, height, 8, width * 4, colourSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);  
CGColorSpaceRelease(colourSpace);
 
CGContextSetRGBFillColor( context, 1.0f, 1.0f, 1.0f,1.0f );
CGContextTranslateCTM( context, 0.0f, height );
CGContextScaleCTM( context, 1.0f, -1.0f );
 
UIGraphicsPushContext( context );
[cocoaString drawInRect:CGRectMake(0, 0, width, height) withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:align];
UIGraphicsPopContext();
 
// glGenTexture, etc...

Even after getting my 1205th bitmap font writer together, I still wasn’t convinced that the results looked as good as a properly kerned font. So I had a poke about to see what was involved in getting CoreText to write to a CGBitmapContext, and if it was possible to bundle your own, custom .TTF file, into the application resources so you’re not reliant on the system installed fonts. And surprisingly, there’s very little on the web about how to do this.

Now, it turns out that CoreText is probably the hairiest framework that I’ve tried to use on OS X. Not surprisingly, I guess, but be prepared. It’s assuming a more intimate knowledge of OS X types than I actually had.

Anyway, the font bundling turned out to be easy. Add the .ttf file to your application’s resource copy step, as usual. Then use CTFontManagerCreateFontDescriptorsFromURL to get the file path for the font. You’ll have a Font Descriptor that you can then use to create your very own NSFont object, which is good to go.

The tricky bit (for me) was working out how to actually get a string into CoreText, in a format that it’ll then render out. Turns out that you want a fancy Attributed String from which a CoreText line is created. That’ll actually do all the drawing for you. And it’ll draw to any context, so CGBitmap ahoy!

Anyway, the code.

BTW, I’ve removed all the error checking for brevity:

// Get the font
NSURL            *url         = [NSURL fileURLWithPath:[NSString stringWithUTF8String:_Game_Interface->GetPathForResource("SolomonP.ttf").c_str()]];
NSArray          *descriptors = (NSArray *)CTFontManagerCreateFontDescriptorsFromURL((CFURLRef)url);
NSFontDescriptor *fontDesc    = [descriptors objectAtIndex:0];
NSFont           *font        = [NSFont fontWithDescriptor:fontDesc size:font_size];
 
// String & Attributes
CFStringRef textRef = (CFStringRef) [NSString stringWithUTF8String:string];
CGColorRef colour   = CGColorCreateGenericRGB(1.0f, 1.0f,1.0f, 1.0f);
CFStringRef keys[]  = { kCTFontAttributeName, kCTForegroundColorAttributeName };
CFTypeRef values[]  = { font, colour };	
 
 
CFDictionaryRef	attributes   = CFDictionaryCreate( kCFAllocatorDefault, (const void**)&keys, (const void**)&values, 2, NULL, NULL );
CFAttributedStringRef attStr = CFAttributedStringCreate( kCFAllocatorDefault, textRef, attributes );
CTLineRef line = CTLineCreateWithAttributedString( attStr );
 
// Find out how big the string is expected to be...
CGFloat ascent, descent, leading;
float expected_length = (float)CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
CGFloat line_height   = ascent + descent + leading;
const size_t width    = ( expected_length + 1.0f );
const size_t height   = ( line_height + 1.0f );
 
// Bear in mind, this will be a NON power of two texture. Which has been fine on all the macs I've tested so far :D
void *pixeldata	      = calloc(width * height * 4, 1);
 
// Context to render into...
CGColorSpaceRef colourspace = CGColorSpaceCreateDeviceRGB();
CGContextRef    context	    = CGBitmapContextCreate( pixeldata, width, height, 8, width * 4, colourspace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
CGColorSpaceRelease(colourspace);
 
// Output the string to the context
CTLineDraw(line, context);
CGContextFlush(context);
CGColorRelease(colour);
 
// Now generate the GL texture...
GLuint name;
glGenTextures(1, &name);
// etc...

And there you go. A Non Power of Two, Premultiplied Alpha texture, with whatever abuse you want to throw at the player. The NPOT thing hasn’t been a problem on any of the Intel macs that I’ve tested it on, so far. Can’t vouch for any older hardware though…

Probably worth mentioning at this point that my use of a purposefully pixelated font means this looks worse than the bitmap font. Gngngngngng. :D

We have a game…

Small milestone reached today: I’ve finally got around to putting all the game states in, including all the tear-down code. I’m now entering the game, loading and parsing everything, running about with 3 lives, then destroying everything and circling back through.

Up to now I’ve just been entering the game, testing, then quitting, so hadn’t actually written most of the code to destroy and free everything, which is lazy, I know. So I’ve had it soaking for a while, sniffed about for leaks and I think I’m pretty much there. Feels good, tbh, although I should probably have done all this ages ago while I was writing it :D

Quick WIP shot, to celebrate…

New Year…

Ok, long time since the last post. Sorry. I’d been holding off as I planned to do some more work on the graphics, thinking that I’d have something shiny to post, but that didn’t happen.

Instead, I’ve been under the hood the last couple of weeks and:

  • Added keyboard control, so I can play as I code without the need for a joypad :D
  • Replaced all the dynamic allocation for the main game objects and sprites, with a cache system that Guy used for PigOut (Thanks Guy!)
  • Replaced all the file loading that was dotted about, and integrated PHYSFS, so now all resources are loaded from a single, packed file
  • Started to replace the old Debug HUD with a new one, that uses the proper render path and text writing code (don’t ask)

Nothing to see, but quite a lot of code changes to get this far. The packaged resource file and dynamic allocation being two things I’d never done, but always wanted to have a pop at, so I’m quite happy with those.

OpenGL Tilemaps

What an absolute ball-ache this ended up being.

I’d actually written a tile map using OpenGL, a long, long time ago, but I’d forgotten about the problems I’d had with teeny tiny little seams appearing between the tiles. So my first quick pass of this for Beat Arena was to bash out an array of sprites and check that my XML parsing was working. And there they were, bastard little seams between each tile, and it all came flooding back…

On TP2k I ended up cheating and setting the glClear colour to what was roughly the average colour for the backgrounds and thanks to the fast scrolling, this pretty much masked it. Except for the clouds, which I never fixed…

A little older and a little wiser, I thought I knew exactly how to solve this: make sure that the neighbouring verts between two tiles were sharing the exact same X/Y coordinates, which admittedly, required a bit of pen-and-paper-doodling-action to work out the offsets, but in the end, didn’t actually take too long to get working. Instead of what looked like actual ickle gaps between the tiles, I now had something that looked more like blending errors. Gah.

So, next step, check that I was actually setting GL_CLAMP in the texture manager (I wasn’t, fuck knows why) and recompile.

Yay! No gaps!

But only in fullscreen… Dropping down to windowed mode meant those fuzzy little seams appeared again, but not between every tile, now I had tartan seaming. *facepalm*

Since moving to pixel art for the Sprites I’ve been using GL_NEAREST for the blending mode, but oddly, GL_NEAREST_MIPMAP_NEAREST actually made the problem considerably worse. So I left the blending at GL_NEAREST and decided to mess about with the actual texel positions of the UV mapping. My first guess was to move in by half a texel on each corner, and bingo. It worked! Fullscreen and windowed, no seams…

Well, pretty much.

If you shrink the window small enough then eventually the seams will reappear again, but tbh I’m pretty much set on having the game ship as fullscreen only, so I’m not sure if this will be an issue. Not to mention, the game is unplayable at the size of the window you need for this to happen, so I’m safe.

However, this solution doesn’t work with GL_LINEAR blending. At lower resolutions the seams will appear and I’ve not found a fix for it, despite an hour of fannying about.

But I think I’ve done enough. And this is the last time I’m ever doing a 2D tile map. Or more likely, a 2D game :D

Fullscreen…

As a good little boy, I’m quite often referring to the Apple docs to find out how to do things, and for the most part this is an illuminating process. I very rarely have difficulty with their docs and I normally get enough information to do what I want, with the minimum of fuss. So, as a good little boy, I’d been using the DisplayLink process they outlined in the GLFullscreen example. And it’s been a royal pain in the ass.

I made some changes to the way I handle XML parsing, so I had a general class rather than bespoke pieces for each of the XML files I’m using for the game data – as part of the tile map for the level backgrounds – and this uncovered the mother of all threading issues, that ended up in the bowels of the display link callbacks. I spent a couple of nights looking into this, before bailing completely. Gaz suggested just using the fullscreen option that’s arrived with Lion, which means going back to an animation callback (similar to how I drove Ballzup). The benefit of this is a much simpler way of setting up the Mac application, and no nasty threads to think about for the DisplayLink stuff. And it works like a charm :)

The downside, Beat Arena is now Lion only, but by the time I finish the next version of the OS will be out, so I don’t think that’s a problem. ;)

And while I was in there, I spent a few hours doing some more optimisation.

Because I do all the transforms for vertex data on the CPU, the update function in my Sprite class was as issue. It’s called a lot, and the first memory accesses for the arrays was super expensive, so I did a little reading and started aligning data, prefetching what I can to take advantage of the cache and optimising the matrix multiplications to remove all the zero cases. The results seem to be pretty good. I nearly halved the cost of that function, which in real terms, gives me a bunch more sprites on the old Air.

I’ve also removed one of the FBOs, and now do the feedback effect by attaching the textures to one FBO in turn. I didn’t realise that swapping FBOs was expensive until I read about it this afternoon, so that was a quick fix. There’s more to get out of this, as there’s one copy stage at the end that I can probably remove, just by ping-ponging the order of the textures each frame.

Unfortunately for Beat Arena, it’s game season, which means all the games I’ve been waiting all year to play are starting to come out. My evenings are going to be spent shooting and adventuring for the next couple of months… :D

Still drawing…

So it’s taken a couple of weeks to actually draw my main player character and get some animation frames to test with. He looked quite good in photoshop, but as soon as I managed to get him running about in-game I was able to see all the problems between the different facings. I’ve got a few more days in photoshop ahead…

On the plus side, when that’s figured out I can base some of the other characters on his dimensions, which will definitely save some time.

Code wise, there’s a pretty skinny class in there to flick between the frames, but it’s all driven by an xml file, so once I’m happy with where I’m going I can extend it into something more generic. And even add other types of events if I need them :)

I’ve also made a start on a tile renderer – which is a good case for digging out the old VBO code I tried a couple of months ago – so my little man should be running on some ground fairly soon.

Assuming I don’t spend the next month playing F1 2011 :D

Pixels and Spawning…

Made some good progress on Beat Arena this week. Code-wise, the temporary spawn manager has been replaced and hooked up to the playlist, so I can now spawn any number of baddies at given points in the track. Simple change, but it’s instantly made it feel more like a game; I now have waves of enemies spawning in and attacking, rather than the constant dribble from before.

I’ve also had a quick try out of my idea for the art and setting for the game, and I think it might work. I’m going to stick to something I know about (and can take the piss out of), so you’re going to take up the role of an intrepid bedroom DJ. I’ve got a couple of very bad jokes in mind for the intro and some ideas for bad guys & behaviours that made me smirk. Enough to get on with, at least until I change my mind in 12 months time.

So the last few nights have been spent pixeling up the player character. I’ve ended up going for a 16bit look as it’s the only thing I can draw. Cliched, given it’s the only thing me and every other bastard on the planet can draw, but there you go. It might not stay that way. Depends how bad my graphics look.

Next week’s mission: Getting my new sprites animated…

Bit Rot…

I found a big box of Amiga floppy discs during a bored clean out of my office last night. All told, a couple of thousand of them; magazine cover discs, wares, my demo collection and all my old graphics & mods. So I pulled out my A500 and went through to see what I could salvage.

Despite looking in fairly good nick, pretty much every disc had a read error somewhere. I did manage to recover a few nice demo packs, some my old graphics and a few of my mods, but well over 75% of the discs were either completely fucked, or had some nasty read error somewhere.

That’ll teach me for buying the cheapest floppies I could find, back in the day.

On the plus side, there’s really no need to keep them anymore. Most games have been archived via WHDLoad and a lot of the demos in my collection are somewhere on the Internet in ADF format. I did have quite a few bits that I’d not seen on Pouet or Exotica, so it would have been nice if I could have salvaged them and upload them. T’was not to be…

So that’s basically the end of the 3.5″ floppy for me. Here’s hoping USB keys and Hard drives last longer than 20 years…

Die, Die, Die…

Small update this week. I’ve finally locked the player into the arena and processed collisions with the enemies, meaning you can die :D

More exciting, for me at least; I’ve finally thought of something that hooks the game to the music. Or at least, gives me a location and an art style that I can follow.

I’ve been unsure what to base the graphics around since I started the game, given the self imposed limitation of using 2D sprites, so I’m happy that I’ve finally got a direction to try out. If it works, I’ll have ticked the two main boxes for the look of the game: Don’t look like Geometry Wars and avoid a black background.

Code’s still the priority atm, though.

Full Speed Ahead…

Whoops, I’ve been a bit slack and not updated the blog. Sorry :(

There’s been a bit of change and a bit of progress on Beat Arena since I last posted. Mr Wayne Keenan has bundled aboard and is helping out with the code, which is ace, and helps keep me motivated :D

He’s re-written the control handling, so the game is no longer reliant on SDL, but most cool of all, it can now be controlled via the iPhone for those people without a twin stick joystick! For people in a pinch I can see that being a very handy addition!

So, the last couple of weeks has still been focused on stuff under the hood. There’s basic playlist support, so I can sync spawning and other game events to the music. The beat matchers are more flexible, and we’ll soon have better audio support so spot-FX can be used in the build.

It’s not moved on much, visually, (in fact the GFX are still very placeholder) but it’s getting there a lot quicker with Wayne’s help… :D

Here’s a little video. Apologies for the shit quality, was in a rush and compressed it to fuck to get it uploaded :(

Threading…

Rightly or wrongly I’ve decided that my Macbook air will be the minimum spec for my game. I reckon this is safe for a couple of reasons:

  1. My Air doesn’t have a particularly fast CPU, although the GPU isn’t too shabby considering.
  2. It’ll take me two years to actually finish anything, so Moore’s law will totally save me, not to mention Apple keep on cranking out the nice hardware, so people will upgrade.

Which is a pretty solid plan if you ask me, except for the fact that I’ve been able to drop frames on my Air without really trying.

So I had a little chat with one of the Super Brains at work – he’s also working on a bit of homebrew so we’ve been encouraging each other with the odd sneaky demo of our progress at work – the upshot of which was a couple of ideas to help speed things up: Timeslicing and Threading.

My thread-fu is a bit weak, my only experience being an attempt at debugging some shit old CGI code, long before I got into games, so I thought I’d have a pop at time slicing the particles. That sounded like a nice, easy change.

My first attempt was just to balance the particles into a couple of batches, process one half each frame, and render them. And as expected, this looked shit… Dirty fucking 30hz, man. So I binned that and tried capping the amount of time that I spent processing particles – doing as many as I could in the time, then carrying on where I left off during the previous frame, until I looped around or I could process everything in a one-er. This was a bit better, but not as nice as 60hz, possibly because I didn’t spend very much time on it (couple of hours all in, for both attempts).

But my particles were nicely segregated into their own process lists and everything already had separate Sprite adds because of the FBO use. Time to roll out the threads, then.

On my Mac Pro this one change gave me nearly 6 times as many particles per frame. On my Macbook Air, just shy of 3 times as many. Happy happy :D

So tonight it was time for the Physics. I kinda roughly had it in my head that I’d need to thread this when I started out, so I was careful to keep a total distinction between the actual physical objects and the game objects that had them. The only slight muddying of this were two lines of code where the physics object also set the game object’s sprite position and rotation during it’s update as it was a waste of a function call. Easy enough to split out into a synchronise function, which was basically all that I needed to do.

The main game loop is now, roughly, this:

  1. Kick off the particle update thread
  2. Kick off the synchronise thread
  3. Poll input and do general house work for the frame
  4. Block for synchronise then kick off the physics world update thread
  5. Wait for the particle update to return then render all these to the feedback FBO
  6. Add the FBO, HUD and Synchronised sprites to the render buffer for the screen
  7. Wait for the physics to return then kick off the game object update thread, as this’ll be applying all the forces to the physics objects for the next frame
  8. Add the player and render the finished screen
  9. Do all my debug hud stuff
  10. Wait for the update thread to finish

I don’t think that’s necessarily as groovy as it could be, but for now it’ll do. The Air is only dual core and performance is LOADS better. I can still drop frames on it if I’m pushing it, but it’s well past the point where I think the number of objects will be an issue. The point being, these fuckers will kill you, so you don’t want 400 of them on screen.

I still might override new and delete for all the game objects for an extra little squirt, and I know I will have to cap the number of particles and bullets to something reasonable, just in case. But the Air’s pushing 1000s of them now, which looks suitably mental.

And I can always time slice the baddie updates… :D

68k Major Mode

One thing I love about Lion is the fullscreen terminal. Simple thing but I use the terminal a lot, so having it old-school, fullscreen and sans distractions gives me a warm glow inside.

(D-Term was a worthwhile replacement for certain things, but now I have a monster terminal a ctrl-arrow_key away from me, I’m too happy to fire it up…)

It’s also meant that I’ve returned to Emacs for pretty much all my text editing. I’ve flirted with Sublime Text and TextMate for a long while, but neither really do it for me. I’m not sure why, as they’re both lovely, but there’s no use fighting it: I’m Stallman’s bitch.

So I had a look around to see if there was a 68k major-mode for Emacs… Emacs used to be built for the Amiga so I was sure there’d be one kicking about, but either my Google-Fu completely failed me, or it’s on some archaic FTP server somewhere. So fuck it, I rolled my own.

21 – very long – lines of elisp later and I’ve got something quite presentable:

It’s deriving from fundamental-mode, so there’s no fancy auto tabbing or tab completion malarky in there just yet, but other than that, the only thing that’s really missing is different colouring for my equates of the hardware addresses (which you can see in the copper list), but I’ll add those at some point.

Strangely happy with that, for my first go. Should help cover up some of the Alopecia in my beard, as well. :D

Indivision AGA

I’ve been after a flicker fixer for my Amiga for years, but they’re a bit rare and often stupidly expensive, particularly for the A1200. A4000 users have a few more options but my tower’s been alternating between an old 14″ Microvitec, kindly donated to me about 10 years ago, and a 17″ TV I found that’ll – just about – sync to the machine’s Scart output. Neither have been great, tbh, especially for reading text.

Indivision released new hardware a couple of years ago, including an AGA version, that’ll up-res all modes and produce a rock solid, clean, VGA output. Unfortunately I just missed the production run, so I’ve been keeping an eye out for a second hand one ever since. These have been getting stupid prices on eBay the last year or so – the last one I tried to bid on ended up going for 2x RRP, roughly 300 nicker – but last week another one popped up, so I threw in a bid as usual and waited to see what happened. And I won :D All in, less than 100quid for a boxed, as new, Indivision AGA.

Here she is, very tightly nestled in the tower:

And it does exactly what it says on the tin. I’ve temporarily nicked a monitor from work to test it out and my Amiga’s now running at 1280×720, 128 colours, with no noticeable slow down. The picture quality is miles better, although this monitor’s a native 1440×900 widescreen, so there’s a little bit of pixel smudge. But in comparison, it’s like night and day…

Not that you can tell from this photo… :D

So that’s all good.

What wasn’t so brilliant was Lion completely fucking up the network sharing setup I had. The Mac Pro has WiFI and two Gigabit Ethernet cards. I have my Wifi on 192.168.0.* and one of the ethernets on 10.0.0.*, acting as a default gateway for the Amiga by sharing the WiFi.

The first breakage was easy enough to work out, Apple have dropped the name Airport, so the sharing was locked to a device that no longer existed. Changing this to the new “WiFi” named device didn’t improve matters. I could see from the router that the Amiga was sending traffic but the Mac wasn’t responding. TCP Dump showed the incoming requests but nothing was getting NAT’d and neither machine could ping each other, which was really odd considering I could see the packets… So I moved the ethernet over to a fixed IP in the 192.168.0.* range, along with the Amiga, and finally they were talking. But, annoyingly, sharing still wasn’t happening…

On Snow Leopard (and, IIRC all the old versions of OS X) you could drag an interface up and down in the Network Preference panels which, effectively, made it the primary device. You can no longer do this in Lion (well, I couldn’t find out how in the 30 seconds I was bothered to try) so by putting the Ethernet into the same range as the WiFi, it was primary and all outgoing traffic was sent through that, meaning nothing getting to my base station and no internet. At which point I couldn’t be bothered to fart about any more…

Instead, I’ve got my Umbongo’d Mac Mini plugged directly into the Amiga and the WiFi is shared through that. 2 minutes to setup (ber-limey). Naughty Lion.

And as I ended up cocking about with my LAN when I wasn’t expecting to, I thought I’d give FTPmount on the Amiga a whizz, and fuck me if it’s not excellent. A really simple app that mounts an FTP location as a fixed drive on your Amiga. All you need to do is give it your FTP password when you first open the folder and bingo, you’re working on the remote machine. Dead handy, having mounted my Git repository…

So yeah, unexpected nerd-camp outing there…

Cry for gDebugger

My favourite tool for OpenGL, the awesome gDebugger, is no more. I fired it up this evening to find out that it isn’t compatible with Lion and a quick bit of Googling turned up this news piece, which if true, is absolutely gutting.

I’ve been using gDebugger loads over the last few months and it’s been invaluable in helping me find problems in my code. I doubt my FBO stuff would have been working so quickly without it.

So long gDebugger. I’ll think of you fondly…

Quick Beat Arena Update…

I did a bit of tinkering during my flight to the ‘States last week so thought I’d take a quick screenie. (Click to for the full size jobbie)

I decided that the cream background colour was too bright. I still don’t want to go to a really dark screen as it feels a little ‘me too’, considering nearly every twin stick shooter seems to opt for this, so I’ve tried to keep a semblance of the pastels in there. This also has the added bonus that I can do a smidge more additive blending without things going on a whitey straight away.

The tank for the player sprite was a quick bodge that I’ve just thrown in. I was bored of the circular thing… But tbh, I’m tempted to leave little tank tracks as you move about, Swiv style-e, which would probably cement it.

Not much more to report atm as I’m mainly playing with Pig Out levels, but I’ll try and do a bit of a tidy up over the weekend and post a vid…

Of Interleaved Vertex Arrays and VBOs…

I briefly discussed Ballzup’s, er, naive approach to sprite rendering in a previous post. But to be clear, it was about the worst thing you could do in OpenGL, particularly on a tiny device like an iPhone. Each sprite had its own texture bind, there was no checking of state, so blend modes were often called multiple times per frame and vertex data was pretty bloated. My current “engine” was written as a direct reaction to that.

I spent a fair bit of time reading around in order to get to something that was much more optimal for OpenGL ES 1.1, and having knocked off some of the rough edges from that initial implementation over the last year – not to mention moving to shaders and something that would be compatible with ES 2.0 – I’ve ended up with a fairly nice sprite renderer using interleaved vertex arrays. There’s one texture bind per texture, per frame and all sprites are rendered out in blend order from one glDrawArrays call.

But I’ve had this niggly feeling that I wasn’t doing the best that I could, what with them Internets (and a few coder type chums) telling me that VBOs are what the cool kids use. So I had a bit of read-up yesterday (and looked through Guy’s Pig Out code) and realised that it’d be pretty simple to remove a copy stage and have my sprites hold all their own corner information in one array and pass that straight into a VBO. And as an added bonus, I could have an interleaved VBO without breaking my texture and blend ordering.

So I had a quick go at putting it in today, which turned out to be really interesting. I’m not really sure what I was expecting, maybe for it to be a smidge faster, but I definitely wasn’t expecting it to be slower. And it turned out to be just over 2ms slower, straight out of the box. I’ve since tested this on all my Macs and it’s been the same on each.

Now, thinking about it, maybe that makes sense. With the vertex array it’s possible that I’m getting a benefit from the driver copying everything over to the card in a one-er, whereas with hundreds of BufferSubData calls, it’s possible that it’s having to do some jiggery pokery in the background to manage the uploads, leading to little stalls.

There’re some extra things that I’ve yet to try, which may make a difference:

  1. I could double buffer the VBOs, as Gaz suggested. Not hard to do, and an obvious first step.
  2. I could split out the packed data into individual VBOs and possibly use an index array. I’m not convinced that this would give me as much improvement as double buffering.
  3. I could have a look at some instancing.

But my (unproven) suspicion is that I’d just end up with something about as fast as I have now. I’ve probably got a pretty bad case for VBO use, as there’re basically no static sprites and very few that persist for long periods of time, meaning I’m constantly feeding new data to the card.

All in all though, this little change has been a great result. I’ve been able to easily change my back end with just a small modification to my sprite class and a different render path in the texture manager giving me a lot of confidence in my own code. I’ve now got a compile-time switch so I can use either, which should be handy when this code is used for something on the iPhone/iPad, and I’ve still got some options for speeding up VBOs should I find a bit more time and inclination.

I’m really happy with that. :D

Alpha!

Ok, first of at least 3 alphas, but we’re there!

The first build went out to play-testers just before I headed out to E3 and the results have been really encouraging, which is always great. And now we’ve got a smidge of pressure to get fixes in and builds out on a more frequent basis, just to keep the momentum going. I love it when people finally get to play stuff for the first time. :D

So tonight I’ve knocked some of the edges off the levels – some of the bastard hard ones are much less cuntish – and changed all the fruit to take advantage of the new gravity well that’s generated by the Pig. It’s going to be a bit of a slog to get a perfect progression in the levels, I think, as it’s lots of little tweaks here-and-there, so play-throughs can take a while, but we’re getting good steers from the play-testers.

And yes, this weekend I will finish the boss. Promise. Might even stick a vid up, as well :D

Like A Boss…

Yay! The Pig Out Boss is now physical, moving and susceptible to player’s farts!

I’m not entirely happy with the movement, but I have a couple of ideas that I’m going to try out to see if they improves things… Bar the shooting, though, he’s all there. :D

Quite pleased about that, as it’s been a really enjoyable process; It’s not often that I get to swan about with other people’s code anymore, so having a bit of a workout tracing through through and learning how Guy’s structured things was a nice change of pace.

I also found out that the build’s going out to testers fairly soon, so I’m going to have a load of feedback about the levels not being balanced. I’ve got a little tingle of excitement about that, tbh. It’s fun, gentle design work, and something I can get my teeth into when I’m back from the States.

Pig Out!

So I’ve not managed to do a lot of productive programming over the last few weeks, what with the sun, trips down south and the imminent 5th Birthday of the podcast looming – for some reason I thought it’d be a good idea to do 5, 2hour long retrospective mixes, covering each year of the podcast… – but I did find some time on on Tuesday to make a start on the Pig Out! boss. So here’s a quick screenie to prove that I’m doing something:

Pig Out! is Mucky Guy’s baby, and despite there being quite a lot in the game that’s working nicely, I’ve managed to take an uninspiring screenshot of a fat dude shitting out some fruit. That’s not actually the purpose of the game! See here.

The up-coming art is looking great (I know you can’t tell from that screenie ;) , the music is catchy as hell, and there’s already 20 odd levels waiting for tweaks and balancing.

For the next few days I’ll be trying to make the fat dude shit out things that kill you, move about in nice patterns and wave his hungry little arms in excitement. :D

It’s interesting stuff, working in someone else’s code, so I’m trying not to break anything while I’m in there and help get it finished. More vids and pics soon!