Tuesday 7 April 2009

Almost time for holidays.

It's been almost 3 months I've been working in a Thai/French speaking office, so being the only English guy here with no other language experience has been a tough experience which has forced me to learn to communicate a LOT better. I've developed more patience, I talk more clearly, and I can explain myself much better too. The skills I've picked up are defiantly going to help me when I get back to Mere Mortals. Sadly, I've not done as much work as planned on my own projects.

Most of my programming efforts have been putting together a simple DS engine. All the time I've spent working on the DS over here has made me appreciate working on platform with less memory, less CPU, and less capabilities in general than most games programmers are used to working on. One of the things which has annoyed me very much whilst working on the DS over here is the engine I'm using doesn't do much for you. It loads everything in for you, and there you go. You've got to choose where it all goes. I don't like that one bit - which is why I decided to have a go at my own engine.

Basically, my engine, PsybrusDS of course, has a bulky tool behind it to convert graphics, including any sizes sprites into something usable by the DS. All it does is swizzles it all into the correct 8x8 block format you can go read about on any of the GBA/DS homebrew sites - nothing spectacular. Engine side, you load a sprite - and it doesn't go into graphics memory until it is needed, and when it hasn't been used in a while, it is unloaded from graphics memory, giving me plenty of room to breathe when it comes to number of sprites. Next step is to treat ROM as a level of cache too - so the sprite isn't even loaded into main memory until it's needed! The loading time is reasonably fast, and there is no seek time, so this is probably a doable approach. Background layers - I don't want to fidget with where in memory they need to go - so my engine has a simple approach - give it the backgrounds, and say "upload these for me will you?" and it works out where to place them in memory for you. A sigh of relief. Progress has been slow on it, but it is just a small project to keep me occupied when I'm bored!

Another project I've been working on (well...just started) is PyAL. It's actually just a wrapper around OpenAL to make it work better in C++, and then SIP bindings. I'm bolting a couple of extra into it such as sound layers to allow you to specify multiple sound files for different gains and pitches, file loading (via libsndfile), and eventually some utility stuff for the EAX extensions. I plan to use it to develop some sound tools for games in Python, so I can have a decent GUI to play with instead of hard coding.

As I said in the title of this update - almost time for holidays. I leave on Saturday coming up to go to Australia to see family and basically relax for my long flight back to the UK, and back to work!

Monday 19 January 2009

Adventures of a programmer in Thailand.

Well, I made it! Landed safely in Dubai, wandered round failing to find the Irish bar (was in the other terminal), then a few hours later went and jumped on a plane headed for Bangkok. I've been there a few days now, the heat has not killed me just yet, although it is dry season, so I'm lucky!

Been a hectic few days, finding that my apartment didn't have electricity (noooo), so I was put up in a hotel until that was sorted out. Following this, I went for a few beers with the MD of the company I'm working at over here, got shown some nice places, and shown some great food! Theres plenty of great food over here, although it's a little too sweet for me personally, but it's something I'm sure a couple of weeks will sort out!

I eventually got a chance to sleep, and sunday came. Woke up stupidly early - 5am, sat on the internet for a bit talking to people back home, and attempted to go back to sleep. Awoke again at half 12! Ouch! Nonetheless I wasn't going to let the day go by without doing a bit of exploring. Took a wander round the area I'm going to be spending the next 3 months to find that there are very few English speakers here. The ONLY English speaking person I ran into was an American guy at a food place - where he asked what I was doing this side of Bangkok - given that it's not a tourist area! Oh joy, I'm gonna go insane from lack of conversation! However all should be good, it'll encourage me to try and learn some Thai whilst I'm out here, at the very least enough to show courtesy when ordering food and such!

Monday finally arrived, I had my first day at work - which was quite unusual to say the least, given that no-one in the office was engaging in conversation in English. Was headphone time for me until lunch time. I did get through the day though - and finally moved into my condo! The condo is fantastic, a good amount of space, a rather large bed, 13th floor view of the swimming pool, and oh yes - a swimming pool! There is also a gym which I have access to, so maybe I can use this opportunity to get myself back into shape!

Sadly, no work has been done on FF yet, though a day or two's time I'll have began to settle into my new home, and will resume work on it! First job is to get reacquinted with the source code and tidy up the dirty bits I've left for a bit now. But anyways, for now, ลาก่อน!

Sunday 28 December 2008

The new year is almost here...

And so is the end of the project at work. It's been a while since my last post, so I figured I'd do one just before the new year sets in. After a month of working late most nights to get the project (which I can't disclose info on just yet..) at work finished, its finally there. I'm sitting on a sunday afternoon just keeping an eye on the bug database incase anything bad comes in, it goes off the first week of the new year so I'm sitting ready to go into work any time.

Even with the extra time spent at work the last month, I've still been working at home on FF. It's not had a lot of work done to it, mostly been dabbling about with the Python bindings and working out nicer approaches to get it working seamlessly with C++. A night down the pub with Callidus a while back, he was mentioning binding Python tightly with his engine's event system. The basic idea was to register a callable PyObject* with an event, and from C++, call this directly - avoiding SIP entirely, and above all else - being very fast. I've expanded a little on this idea by passing objects with events much like wxPython does. The objects passed in are autogenerated C++ classes with autogenerated SIP bindings, and autogenerated utility routines to help the event system work nicely with them, as well as being memory efficient. All thats needed is a small file which defines all the events, from that, it generates all the enums, classes, and macros required to use them. This allows C++ to send user data to Python, and Python to send user data to C++ - all with the same interface, so converting any C++ code to Python, and visa versa shouldn't be a problem if it relies on the event system. Anyways, a small example of the event descriptor used to generate the event classes:

Ev:MusicNext
Ev:MusicPrev
Ev:MusicStartedTrack
string trackArtist
string trackTitle

Two events straight out of FF. The Python music player binds to the MusicNext and MusicPrev, and when a track is started, it send MusicStartedTrack with info about the track started attached. I've got a script which parses this descriptor to generate the code. A snippet of the code it generates is as follows:

75 class EvMusicNext: public EvBaseEvent

76 {

77 public:

78 EvMusicNext(): EvBaseEvent( evET_MUSICNEXT ){}

79

80

81 private:

82 };

83

84 class EvMusicPrev: public EvBaseEvent

85 {

86 public:

87 EvMusicPrev(): EvBaseEvent( evET_MUSICPREV ){}

88

89

90 private:

91 };

92

93 class EvMusicStartedTrack: public EvBaseEvent

94 {

95 public:

96 EvMusicStartedTrack(): EvBaseEvent( evET_MUSICSTARTEDTRACK ){}

97

98 void trackArtist( const BcChar* _trackArtist ){ BcStrNCopy( trackArtist_, _trackArtist, 32 ); trackArtist_[31] = '\0'; };

99 const BcChar* trackArtist() const{ return trackArtist_; };

100 void trackTitle( const BcChar* _trackTitle ){ BcStrNCopy( trackTitle_, _trackTitle, 32 ); trackTitle_[31] = '\0'; };

101 const BcChar* trackTitle() const{ return trackTitle_; };

102

103 private:

104 BcChar trackArtist_[32];

105 BcChar trackTitle_[32];

106 };


You can see its quite heavy, but it's better that than being flaky. I'd rather have a wrapped up interface than having the events as raw structs.

In other news, Christmas has passed, and I got an EeePC 900A! Finally I have a working laptop once again to serve as a secondary machine/third monitor, and something to mess about on. First thing that was done to it was strip off Xandros (sorry..), and install a fresh copy of XP onto it. Out of the box, it runs very poorly. Thanks to a guide on the EeeUser forums, it's running up to speed now! Most of the speed improvement seemed to come from setting up a Ramdrive for temp files and the firefox cache. I have a 2GB RAM upgrade on it's way so I can bump up the Ramdrive to a larger size, and not run low with the swap file disabled. This thing is 'supposed' to be only really for browsing, but I'm treating it as my second dev machine. Python 2.5.2 and Visual Studio occupy a large chunk of the ickle 8GB SSD.

And finally, some people are already aware of this, but in about 3 weeks I'm off to Thailand! As always I can't give many details, but what I can say is Goodbye UK! I'm there for a total of 3 months, and heading to Australia for a couple of weeks afterwards to visit family. Due back in the UK mid May! When out there, this and Facebook will be my means of keeping in touch with people back home, though its primarily a development blog - so there won't be a single post without news on FF, which I will hopefully have a LOT of time free to work on whilst away.

Bbai for now!

Friday 21 November 2008

Long week and a bit...

Its official, at work we're now in crunch. Project should be out the door soon, but its gonna be hard run up till xmas! Mind this is part of why I joined the games industry, the last minute adrenaline rush to get a project finished, polished, and out the door - beats working in a shop simply crunching to get the customers out the door!

Even though I've been working late at work, I've still found the motivation to come home and grind a bit to get somewhere with Freecross Frenzy. Since I last posted, I've knocked up a quick rig and control mech using my old ODE wrapper from my dissertation. So far the control mech actually works, but is far from what I want. Biggest problem so far is realising that you can't let the player directly control the steering - it is FAR too unstable! Reading up on bike dynamics, its much better to let the player influence lean, and just moderate how much the front fork actually turns. I'm just doing this by applying a torque to try and keep the fork straight, it works, but doesn't seem a particularly nice way of doing it.

Balance is another issue I've notice problems with - bikes are stupidly unstable. 2 wheels, very small contact with the ground - It's gonna fall unless the rider corrects. Currently, I'm also applying a torque to the frame of the bike to keep it at the targetting lean angle. As with steering, this is not how I aim to keep it, but it works bloody well! The bike can stay balanced with minor leaning at 0MPH, and can lean over 45 degrees either side when moving at over 20MPH. Some how I feel I'll be writing my own friction model to deal with all this correctly, as over 45 degrees of roll on a flat surface is NOT going to happen in reality!

Tonight, I took a bit of time out of the physics side, and fixed up my material system and wrote some shader code. Previously I'd mentioned using Blender for my modelling purposes as I know it well - I found that it exports FBX pretty well - missing some bits, but kicks out enough to work with, so I've went with FBX as my primary file format. I've spent the night forcefully pulling values out of FbxSdk to fill in material properties for lighting, and realised Blender doesn't kick out quite what I need - but I need to make ends meet and just go with it for the mean time until I get a material editor as part of PsybrusEd finished up. Quickly implemented simple diffuse lighting, and specular lighting using Phong shading. the result of just over a weeks work and a few hours here and there playing Left 4 Dead:




Thursday 13 November 2008

Blender.

You mention this word to most artists, and they will cringe, and pass it off as a pile of crap. Yeah, its not as 'good' as Maya. However, its completely free, and Maya is not! Personally I prefer it, but I'm not an artist - I'm a programmer. However, I've been using Blender for there about 5 years now, and have memorised most of the tricky key combinations, can animate, rig, UV map, setup hierarchies, basically everything I *need* to be able to do to throw together simple test assets. My only gripe is the exporters - theres a few, but none of them work how I need them too. If the Collada 1.4 exporter worked well enough that'd solve my problem with the hierarchy I'm currently having. Currently putting together a test bike, properly setup as individual components to tie into physics for Freecross Frenzy. The bike is modelled whilst referencing pictures of real components used to build dirt jump mountain bikes, its *mostly* in correct scale, but I can tweak it later. Anyways, my attempt at being an artist so far:
























Sunday 9 November 2008

Freecross Frenzy, my next exciting project.

When I was in high school, I spent a large amount of time outside of programming out dirt jumping. Since then a few things have changed, and I have since stopped, not for good, but until I get myself sorted financially and can start to plough money back into buying a decent mountain bike!

A few friends used to always bug me to make a DECENT mountain bike game, and at the time I laughed it off knowing how difficult an undertaking it would be, especially since I didn't have a firm grasp on C++, and my only real projects were Half-Life mods. A few years have passed since then - in that period of time I've gotten myself a degree, a CyTech NVQ and a job in the games industry.

In my first year of university, one of our modules was games design. The project for this was essentially write a full game design document. We had over 3 months to do this but I had a small problem - I had no ideas AT ALL. Come the week before hand in, I actually started to get some ideas, and the night before it was due in, I threw together a full design document, weighing at around 50-60 pages, for a game called 'Freecross Frenzy'. 
'Freecross Frenzy', as you've probably guessed by now, is a mountain bike game. The idea was pretty much to combine dirt jumping with dual slalom and 4x. The mechanic of the game was to score points by not only completing a race in a good position, but to perform stunts whilst racing, and basically style your way to the finish line. Very simple concept, however without experience, I was unable to ever consider knocking together a tech demo. The reason I've wanted to put a tech demo together was mostly because of my idea for the control mechanism - Weight shifting. The emphasis for doing tricks in games such as Tony Hawks is focused on button combinations, which is all well and good, it gives you a pretty straight forward interface to work with, and lets you do combos with great ease. The problem? Lack of freedom. By giving the gamer control of the rider's position on the bike, it allows them to perform tricks that haven't explicitly been implemented by the programmer - encouraging emergence.

Back to the plot though, I've decided to start putting together a tech demo - nothing fancy looking, not a full game, pretty much just a track, the control system, and the physics behind it all. The physics and controls are everything for this - so theres a lot of work I need to do before I get started on the demo. This includes finishing the last couple of bits in Mapper so I can throw together a track, as well as starting AND finishing another part of PsybrusEd - Rigger. Rigger will be a simple tool I use to bolt together models with constraints, and in this case, connecting the wheels, frame and fork of a mountain bike with the correct constraints! I'm giving myself another week to get the Mapper sorted and up to spec to start lashing out levels, and then I can start properly on Rigger.

And before I go, a quick update on PsybrusEd Mapper. Height fields are in, they can't be edited yet, but they can be dropped into the world, so that's one more thing out of the way! Undo and redo are now bound back in since I've shuffled around the events a bit, and also fixed the threading problems I was having. The game is now fully updated from Python, however, the renderer sits on its own thread still so it doesn't cause the GUI to slow down - its also locked at 30FPS to keep CPU usage low. Action panels are in and working, and object selection/deselection is fully working too!





















Next hurdle to jump is to get object editing working - which would include:
- Transforming objects (Translate, rotate, scale, etc)
- CSG specifics such as clipping objects.
- Heightfield specifics such as painting the heights.


Sunday 26 October 2008

PsybrusEd Progress...

A few more days go by, a few more lines of code are written. I've mostly spent the week focusing on getting actions working correctly in the editor. As much as I wanted to put these into Python, theres still issues to resolve with the global interpreter lock so the actions may be updated from the engine's thread. This could probably be done by ticking the engine over when input events happen, rather than run it totally on a seperate thread, but that I'll wait for now.

Since the actions went in, so did undo and redo. Actually simpler than I first expected to implement! Just store an action history list, give them virtual undo/redo, and call these when an undo or redo is invoked! I'm going down the route of cloning objects when an action is performed on them, that way we can get back the exact object that we just modified, rather than transforming it back or whatever, potentially having errors creep in later on. Another advantage of doing this is the fact I can get away with writing one lump of code for undo and redo, and it work on any object:

   79 BcBool ActCsgBase::undo()

   80 {

   81     // Remove all added objects, and readd all removed ones again.

   82     ObjPtrList::iterator Iter;

   83 

   84     Iter = AddedObjects_.begin();

   85     while( Iter != AddedObjects_.end() )

   86     {

   87         ObjManagerState::pInstance()->removeObject( (*Iter) );

   88         ++Iter;

   89     }

   90 

   91     Iter = RemovedObjects_.begin();

   92     while( Iter != RemovedObjects_.end() )

   93     {

   94         ObjManagerState::pInstance()->addObject( (*Iter) );

   95         ++Iter;

   96     }

   97     return BcTrue;

   98 }


Save/load had also been 'sort of' implemented. This will be due an overhaul to use XML soon, rather than serialising the binary data of every object. Currently this is fine for me for quickly testing without rebuilding scenes to check out something! Probably going to be going down the LibXML route, rather than write my own library on this one, however one of my major concerns is file sizes will get pretty large, especially if I plan to save out undos and redos to preserve the users workspace.

Next task for me, sadly, is starting to do more of the GUI stuff, and tidying up the CSG operations so the world is stored as one object containing all the convex shapes, and operations as objects so they can be modified on the fly. Should have possibly done this from the beginning, but I wanted to get something quickly up and running to test out the CSG library to the full!

Anyways, a screenshot of it in its current state showing off 3 new lovely orthographic viewports: