Manta-X Code (Part 4)

Up and Running

Now that the code compiles quicker, my iteration times will be faster in this codebase. The first thing I want to do now is get the game “running” and “playable” to the point that it was. I won’t add any new features, but just try and plumb together whatever’s there.

Rendering

First thing to do is get the render loop running. The game currently uses OpenGL and used to use GLFW for windowing. The last time I touched this code, I brought in SDL, commenting out stuff to do with GLFW. The first thing to do is to start pulling all that stuff back in.

It was missing:

  • SDL_Init (heh)
  • SDL Event pumping
  • SDL Video mode setup

After uncommenting the creation and update of the render window, we finally have something displayed!

That screen is the last thing I saw before I closed my IDE on the project all those years ago. It’s like looking back in time and seeing the face of someone you once knew.

I can’t remember what I was doing at the time, but that’s it.

At this point, input is all disabled. This is fine, I’ll add it later.

I remember having at least a background in there and some enemy ship. Time to go and find how to turn all that back on.

//      MMPtr<BackgroundNode>   bkgNode = new BackgroundNode( MMPtr<Texture>(bkg) );
//      bkgNode->initSceneNode();

//      MMPtr<StarFieldNode>    stars = new StarFieldNode( 50, MMPtr<Texture>(particleTexture) );
//      stars->initSceneNode();

After prodding it for a bit, it looks like the code to turn back on no longer exists. BackgroundNode and StarFieldNode don’t exist. They did exist looking at the huge weight of evidence in the place they would have been hooked up.

And then it dawns on me that perhaps this codebase was in a transitionary state from an older one. This was meant to be the improved version. I can only imagine the trash that was there before. Back then I didn’t use version control software, so my codebases always got trashed in situ, with no backups. I often used to ‘fork’ by starting a new project and copying files over, changing them to fit the new ideas.

The older game with these features looks to be completely lost in time (unless I can find another archive).

The only way to go back and add these features is to write them again. sadface.

‘Playable’

I can at least attempt to get the input working, to at least say I have something working. This should be a straight swap of GLFW’s handling with SDL’s key events.

Or so I thought.

Looks like there’s two layers of input handling here. One via GLFW (commented out), the other using DirectInput 8. I’m going to assume that the DX version is the canonical one that needs porting to SDL.

Ripping out the DX8 code was pretty quick as it was self contained. I run the code and start pressing the keys and… nothing. Nothing happens.

Turns out there’s an error in the code that calculates the frame tick, essentially meaning that the game update doesn’t get ticked at all. I replaced this with the SDL_GetTicks function and we’re away!

The ship is moving around with the arrow keys - rolling slightly when it moves up or down the screen.

I press the spacebar to fire the weapon and… nothing. Again.

int GameShip::fireWeapon()
{
    if (m_fireTimer <= 0)
    {
    //  SmallLaserFire *p = new SmallLaserFire();

    //  p->position = this->position;
    //  p->position.x += 20.0f;
    //  p->velocity.x = 150.0f;
    //  m_level->addWeaponFire( MMPtr< IWeaponFire >( p ) );

        m_fireTimer = 0.25f;
    }

    return 0;
}

And guess which class doesn’t exist? Screw you, past me.

lol comments

Some of the stuff in the code amused me highly - mostly the use of comments to document functions. Check out this gem from the Game.cpp file:

///////////////////////////////////////////////////////////////////
// Method:      isRunning
///////////////////////////////////////////////////////////////////
// Returns the current run status of the game. If this is
// false then update should not be called
//
// Access:      public
//
// Prototype:   bool isRunning()
//
// Parameters:  None
//
// Returns:     bool
//
// History:     20/06/2004 - Created
//
//
////////////////////////////////////////////////////////////////////
bool Game::isRunning()

That’s from the cpp file, not the header where you’d expect. That just gets this:

///////////////////////////////////////////////////////////////////
// Method:      isRunning
///////////////////////////////////////////////////////////////////
// Returns the running status of the game
////////////////////////////////////////////////////////////////////
bool isRunning();

Seriously - that stuff is worse than useles…

Past-me was a Jerk

When I took this investigation on, I didn’t really know what I’d find. I’ve unearthed a lot of really bad code, with “comment out stuff” being the modus operandi for source control. There’s at least 3 or 4 layers of legacy in this code - you can tell by the technologies and style (hell, some of the comments refer to a completely different namespace).

At one point in the past, this thing was playable and now it’s not even that. This code is either the start of a new ‘improved’ fork of the game or perhaps an old one that was ripped to pieces during an ‘upgrade’.

What bugs me the most about this code isn’t that the code is bad (that was expected), but that in ‘upgrading’ the code I threw away the useful bits (eg: the game) and implemented a bunch of crap that isn’t needed or doesn’t contribute anything to the game. I literally threw away the product to sit in the wrapping paper. And it’s not even good wrapping. It’s the brown paper and string type-stuff.

Perhaps that’s the benefit of experience talking, but I do things fundamentally differently now. When I refactor, I do it iteratively and keep the old thing working. You can’t afford to just ditch the old and have code that is fundamentally broken for months (or 12 years). Unless something is no longer required, I don’t factor out old behaviours or logic during the upgrades. That’s just idiocy - something which I had in spades.

I want to go back in time and tell past-me to make better decisions around how to go about building stuff.

Next Steps

This has been a fun journey so far and I’m really not sure where to go next. It was my intention to get this game up and running and then perhaps start working on it. I’ve got it running to the extent that it ever will and now need to decide what to do next. Working on this has exposed some basic architectural flaws that would need working through (literally, everything is fucked). It may be a fun refactoring project to move this to a better architecture and keep the nugget of the ‘game’ there (‘game’ being a huge airquote). I can at least delete the commented out junk code to see what there actually is left. Or I could just close the door on this and come back to it in another 12 years.

I’ll have a think about it.