Gaming Your Way

May contain nuts.

Some boring numbers

Lost Outpost went gold the other day ( I should really have mentioned that here shouldn't I ? ) and it's currently waiting for sign off with the sponsor, so I thought let's go through some numbers just to try and show why it's taken forever to finish.

For the 10 levels ( Plus 5 Swarm levels ) we use 396 tiles, or 1,653,371 bytes worth. When compiled all the levels come in at 2,232,249 bytes.

99% of the images have been converted to png8 to save file size ( All done by hand ) which come in as 1510 images, or 17,942,059 bytes ( This includes the tiles ).

We have 272 sound effects ( Including 7 pieces of music ), when published as a swc that's 5,547,127 bytes. To give it a bit of perspective, Outpost:Haven was our most sound heavy game before this, with 158 sounds. There are 10 different shell casing sounds, an additional one just for shot gun shells, 3 different samples for a crate being shot and 12 vocals for the automated announcement system on Haven.
I went a little bit crazy with the sound I think.

 

 

In regards the source, this is more vague. Not so much the numbers themselves, I'm not just making them up, but the meaning of them. When someone says they've coded something and it's taken 2000 lines, it doesn't really mean shit as everyone codes differently. Personally I'm murder for lots of white space and for using a Class for everything ( I've been told I'd break one line out into it's own class if I could, which aside from making me laugh is very close to the truth ).
So yeah take the following with a pinch of salt, it's quite meaningless, hence me comparing the code in Lost Outpost to Outpost:Haven's as a kind of benchmark ( I can only compare my own code to my own code as my style if fairly consistent  ).

Outpost:Haven had 266 Classes, taking up 2,304,945 bytes. This includes 27 Classes that weren't mine, general utility stuff.

Lost Outpost uses an unbelievable 425 Classes, 4,317,541 bytes. That's fucking insane. Oh hang on it's not too bad, the same 27 Classes that weren't mine in Haven are included in that figure too. So less than 400, that's nothing...

30 unique physics objects ( Crates, desks etc. ), 133 "Non-Baddie" items. These are items which the baddie handler routine controls, but aren't strictly baddies, so it goes from the spinning fan shadow to music triggers to flushable toilets to the medi-packs you collect etc. 6 Classes are for the hidden game ( With it's assets coming in at a mere 255k ) and a majestic 37 Classes for all the particle effects, with 9 of those being various smoke effects. The overkill for the particles was for performance reasons rather than me over engineering for the sake of it.

The in-game terminals were a mere 3 Classes, although they came in at more than 4000 lines of code ( I guess if you deleted all the white space and comments, that would be about 40. I'm joking, but not by much ).

PDA, which is the inventory, maps and the log screen, was a mere 14 Classes but had more code than all the particle effects combined.

And I've started to bore myself, so it's time to stop. Just to recap, Lost Outpost is a huge fucking game which should equate to over an hours worth of total story play time.

Squize.

How the MTR car AI works ...

... or should, once I find the time to finish that slog. 

I must admit it was one of my worst ideas to take a stab at a racing game (and sell it to a client). The only luck so far is that it's a "when it's done" deal, so there's no deadline on this except my own wish to get it done and collect some cash for the client version.

The basic idea to do a "quick" little racing game wasn't that bad, but I really, really underestimated the amount of work I had (or rather still have) to poor into it. One of the most time eating tasks still is writing the car AI, which completely didn't appear on my radar until it was way to late.
I've written my share of AI code so far, so I thought this one wouldn't be much different. I think I was wrong with that.

The main big different with what I have written so far is that character can move freely, if something blocks the way, turn left or right and continue moving until you can resume the old path (or just run the a* again to find a new way to the player). For cars this doesn't quite work this way (now that's a surprise).

So cars need to use throttle to speed up and breaks to slow down you need to use steering angles to change direction and you must obey the limits (otherwise it'll looks like cheating). Moving the car along the track is quite easy if you have a fixed track, just draw a spline and let the car move along it. Too bad MTR has a built in track editor, so we need to construct the path for every track. (I covered this in an earlier post).


Waypoints for the AI.

Trouble enters the equation when we add other cars to the track and we cannot follow the waypoints anymore if some other car blocks the path. I calculate the throttle / steering values in steps, blending the values in the end (and then blend the desired values with the current ones).

First step is looking at the waypoints ahead and decide which lane is the shortest (using floating waypoints), then the desired throttle is calculated based on the distance between the last waypoint we've passed and the next. The shorter the distance the slower the car should go, I use 100% for the max distance and 75% for the smallest distance). 

Next step is deciding what angle we turn the wheels in order to head towards the next waypoint and if the angle is greater than the allowed one, we reduce speed further.

After this I have a basic throttle value (say 90%) and a steering value (say 20%, of the max steering angle).

 


Damn obstacles.

Now it gets a bit more complicated, we need to look for obstacles that might block the path we've just selected. The image above shows the problem, the red line shows the desired next spot we want to reach, the yellow line shows the current throttle, with the dark blue line showing the max throttle (but that's only for debugging). Important is the cyan line that is shown at the back of the green car, as it shows where we would hit the green car if we would follow the current path.

Right now, if this happens I offset the waypoint until we can pass the green car (adjusting steering to -20%), but only if there is enough room (there are also checks to see if we can pass on the left or right side of the obstacle), if we cannot pass we need to reduce speed to stay behind it.

Now just blend the values and pass them to the car and repeat this every time we hit a waypoint or another car is close enough to overtake.

If I ever get that video grabber to run I'll post a video next week.

They're nearly here

So Lost Outpost has been sold, to maxgames.com, and we're just fixing the last few bugs and adding the branding. We can't give a launch date yet, but it should be next week sometime. 

We're so nearly there, and we can't wait.

Squize.

And then they said that burning the secret documents ...

... only made things worse.

See, all the good intentions are gone by now - that is having the weekly post done before Sunday, well at least it's not 23:52h.

Although I have a good reason as I haven't worked at all for two days straight, trying to get my laptop back to work. In theory it would have been a case of just restoring the last weekly backup, but alas ...

I'm using a Dell, you know, running win 8.1 pro (64bit) with Intel Rapid Storage (magically using a SSD and a HDD mixed up for speed), Intel onboard gfx and an additional ATI Radeon card for 3d / games. I mention this because this combination is the the reason for the two wasted days (although, it's partly my fault).

The whole mess starts with me noticing that the Catalyst Control Center wasn't running (so no choice which card to use), as I had that earlier (when running still running win 8) so I knew that I just needed to install the latest ATI drivers again. That done and a reboot later the only thing I got was a black screen and a flickering cursor. What followed was a lot of cursing, because after I used a "recover to last working version" I ended up with a clean win 8 install and just a few of my settings and none of my programs left.

Ha! No problem, I have a backup that is just one day old.

To cut this short, in order to get the OS partition restored I needed the following: change boot mode to legacy (UEFI by default, to run the linux based frontend of the backup software), turn off the Rapid Storage/RAID settings in BIOS in order to access the HDD and write back the partition. With this in the recovery only took about 30 minutes, great that there's nothing to be found about this on the interwebs ... and you only come to this after 2 days of "can't this", "error that".

Oh and I had to install the ATI drivers provided by Dell in order to make things work with win 8.1 ...

... now lets's start with this week's post.


Yes, I used that image before.

I mentioned that the HUD in MTR is far from ideal or even "pretty", too much information, too small and not helpful. One of the tasks on my list therefore read "redesign HUD" and this post will go through some of the iterations that the HUD went through.

The information I wanted to show was: car, position ( the badge icon), lap time/total time and boost (the battery). Once the race is running, having 4 pairs of changing numbers is quite a bit much distraction from the track.


Iterations of the new HUD.

As you can see the icons changed quite a bit and all of the icons that were used as labels are gone now, too. 

The final HUD comes in two flavours: horizontal (for smaller screens) and vertical (for larger screens):


Default view for larger screens ...


... and for smaller ones.

The latest version adds a hint of color to the backgrounds of the badges (using the car's main color). The position is now shown by the order of the badges, the local player is marked by the orange line (color may change). It also brings back the battery icon, well sometimes, but that's for another post ...

More next week,

-- Oliver / nGFX

You can't make an omelette without breaking an egg

(from: Some Like It Hot)

Even though the title is a quote from a movie, it also is very true for development. As mentioned last post I was about to rewrite (again) parts of the game to make it easier to maintain and debug.

One of the bigger changes is that I moved states from code to a visual finite state machine (FSM). Honestly it was one of the better ideas I had since I started with a game I have virtually no "knowledge" of (because I really don't like racing games). As a result I killed about 2/3 of the code in my "RaceController", reducing it to (currently) ~300 lines of code.


Early version of the RaceController FSM.

The final version is a bit more complex, though. To be true this doesn't count in the code needed for the FSM, but *my.* code is a lot shorter now.

For the AI code however it is something different and I found it a fine line between using the FSM and handle things through code. I had to decide whether to make "Reached waypoint, what now?" a simple method call or a state. The AI is done in code now as most events coming in just alter target values that are dealt with in the main loop of the AI.

In any case this makes the AI a tad more robust when dealing with corners, speed and lanes. For example there is a value that keeps track of the lane the car is on (0 being the inner lane, 1 the outer and 0.5 the middle of the road). When the AI decides it wants to change the lane from 0 to 1 (because in corners the inner lane is faster) it sets the fTargetLane to 1 instead of fLane (the variable that holds the current lane we're on). Before easing the lane value the AI can now check if there is room to change the lane (another car blocking the way) and delay easing. Same goes for speed and steering.

Easing between current and target value also allows to add some "personality" to the AI, but that's stuff for a later post.

"All right, driver, once around the park, slowly, and keep your eyes on the road."
(again, Some Like It Hot)

-- Oliver / nGFX 

Minor changes to the UI and a serious rewrite of the AI.

Oh. I didn't mean to add a really helpful title, but I couldn't think of something stupid, so this has to do it.

It's time to pour some (erm ...) time into MTR development. First thing today is getting rid of the HUD, which is neither pretty nor particular useful at the moment.


The UI in all its present glory.

As you can see at a first glance it is way too cluttered, there are too many numbers running and the icons aren't very helpful.

I thought it might be a good idea to show infos for all four cars (as you should be able to run a four player game), but I think I should be able to condense it a bit anyway.

  1. no need for two times per car (first being lap time and second total race time)
  2. number of laps could be shown for the car on position 1
  3. showing the position of the car with an extra icon (the badge) could be reduced to just the number next to the car's icon
  4. car icons should show the actual car
  5. get rid of the black bars

I also need to reduce the number of draw calls, so I started to modify the prefabs of the tiles and separated colliders and meshes and gave them correct names. The routine that plots the track now can split these up once added to the scene, grab the meshes and bake them into a single mesh.

If time permits I'll also start on rewriting the AI (mentioned earlier it uses waypoints as rough guidelines). With four cars on the track chances are way to high to miss a waypoint, which I currently check using a simple distance check.

The new method ... but hey I need something for the next post.

And with this, catch you next time (when I hopefully have fixed the AI).

 

-- Oliver (nGFX)

Meet the gang ...

What, it's Saturday again?

I'm so glad I have something to post about.

As I mentioned last week there is work to do on that little racing game. Time between various other projects has been spent doing the last car I needed.


I'm number four.

So with the first four cars in place I can finally do some racing with different cars and although the AI needs a lot of tweaking until it runs like I want it, it feels a lot closer to a game than before. Still there's a good deal of stuff left before I call for some beta testing.
First thing on the list is the player car selection, although I'm still not sure if the cars will have different stats at all.
Second thing will be the track selection, no idea how that will look like (doing little spinning 3d tracks or simple 2d icon style ones (like the menus). 

And last but not least there is need for some more tiles, namely elevated corners and steep curves (I'm actually looking forward to see these in the game).

To end this meagre post here's a picture of all cars, right from the game running (looking at it, the first one is from the game running, too).


Not sure if you noticed, but the red car is now a blue one ...
  and it's going to become white in the end.

So catch you next week and if you haven't already done so ... just two words: Outpost and Greenlight ...

Oliver (nGFX)

Using Scout to optimise Lost Outpost

This is going to be a bit of a techy post, so if that's not your thing please feel free to move along. Oh, one sec, before you do, here's some Lost Outpost coverage we've had:

http://truepcgaming.com/2013/09/27/given-a-lot-of-love-lost-outpost-interview/

http://www.twitch.tv/coopheroes/b/467397568 ( Interview with Lux plus play through )

Right, let's talk optimisations.

I finally figured out ScoutCC, I looked at it ages ago and was just overwhelmed and not overly interested ( Unless you really need it for a live project it's hard to care ). It's awesome, just so good.

It helped me spot something major with my new sexy ultra quick particle routines. Yes they were sexy, but they weren't ultra quick, the opposite in fact. What I'd done is create look up tables for all the things like movement, alpha speed, scale speed etc. This was to avoid using Math.random() and was much quicker.
The downside being I was creating the look-up tables in the constructor which was causing a really bad performance spike. I thought it would be fine as all the particles are pooled, so it would only be a one shot hit, but where I wasn't pre-pooling enough of each particle that hit was really adding up.

I went a "Factory" route ( I believe that's the correct term, I don't really hold with proper terms. I'm the same with street names, I can tell you where a place is in relation to pubs, but not the actual street name ). I have one class which creates all the look up tables I use and trigger that right at the start of the game so it's pre-populated with random goodness, then each particle just grabs a reference to the data it needs to do it's thing.

Next up Scout was showing that the Movieclips were causing a really large hit. We all know Sprites are quicker than Movieclips, but the difference is really quite startling.
Level 4 was playing up really badly, the water level. It's turns out I'd forgot to call gotoAndStop on all the water clips I make. I have one water object, and it's as simple as simple can be. I create instances of my different sized animation clips ( 13 in total I think ), but without calling gotoAndStop on them all when you first make an instance of them, the timeline runs. So that's 13 clips running on every water object in the whole level ( I can't even estimate how many there are, got to be over 60, there's a lot of water in that level ). Simple fix and it stopped the huge performance spikes.

Right so Movieclips are very costly, and nearly everything is a Movieclip. Hmmm. I went back to my factory method, and created a couple of classes for all the animation for things like the particles ( Explosions being a good example of an animated MovieClip we used a lot ), and the baddies.
These factory classes are basically just a list of public vars pointing to bitmapData, nothing more.

Let's take a baddie as a straight forward example. Rather than having it as MC, I changed it to a Sprite and put a bitmap in it, centre aligned. I then grab a reference to all it's frames ( As bitmapData ) from the factory and to animate it change the bitmaps bitmapData reference ( Ha, what a God awful way to explain that ).

ourBitmap.bitmapData=ourAnimationFrameReferencePulledFromTheFactory;

Hopefully that's a little clearer. Now all the baddies and animated particles ( Debris as well as explosions, etc. ) use this Sprite / Bitmap combo and performance has improved a hell of a lot. We use the "Ghostbusters" sequence in the canteen in level 2 for testing, as we're throwing lots of explosions in there with baddies, it's a really full on set piece, and after these changes it always comes in on time, whereas before it would lag at times.

And that's our little story.

Squize.

PS. I know I promised not to do it too often, but we're still after some Greenlight loving, http://steamcommunity.com/sharedfiles/filedetails/?id=177695239 cheers.

#addlistoftrendinghashtagshere

It's Sunday again, although for a change it's not 23:45h while I'm writing my weekly blog post.

I guess I mentioned last week that the lazy days are over and I have to get back into the joyful pace of client work. Last week I started to setup a new client site and the racing game came back to haunt me (and it needs finishing too, if possible before the end of the year).


Website layout.

The sceengrab above is what we got as sitemap for the client website. We spent a few minutes wondering about how to turn that into a website and then settled on the idea that we just use that. To our surprise it pleased the client extraordinarily - which in turn pleased us. It even pleased me, until I started to imagine how to build this and not use an image / image map (which, let's be honest, would be a moment I should quit my job).

So I set it up as a combination of css3, canvas and javascript to make it as dynamic as possible. There's all the latest shebang hover effects (like highlighting connected circles and lines), transitions (when circles turn into popups) and some parallax effect when scrolling down to the other parts of the website).

It doesn't happen often that I can say "I'm quite pleased with the outcome".

 

After that I went back to MTR.

I'm still in 3D mode so instead of starting with code I started building the 3rd car.


The 3rd car, at least one more needed.

This one is quite easy, no fancy corners and this is the outcome of about 4 hours work. It's missing some details like the bumpers and lights, but that's for tomorrow morning. I even look forward to UVW map it (well, who wouldn't, as it's essentially a box with wheels).


I think the rendered version looks a bit shit right now.

I'm not quite sure what the 4th car will look like (although I have an idea) and with that I can finish of the dreaded AI. I then have to do a client version of it - which even might become the initial public release (so I have it out of the door for a while). The client version will feature single player mode and six fixed tracks only, maybe a few (very few) car upgrades.

We announce the next important post after the break ... or next week.

If you haven't done so already give Lost Outpost your greenlight love:
http://blog.gamingyourway.com/post/2013/09/16/Lost-Outpost-on-Greenlight.aspx

Catch you next week,
-- Oliver (nGFX) 

... and so it goes,

and so it goes
and so it goes,

but where it's going no one knows ...

(Nick Lowe, 1976)

 

That said, this "one post per week" is already going on my balls. Anyway, it's 23:31h on Sunday and I'm hammering out this week's post, well knowing that there isn't much to write about.

The week started with going back to "real life" and finishing off a client website, which is using a lot of the oh-so-new (as far as marking people know) web toys (css3 transforms, canvas) - oh boy did I have fun.
[Add a rant about the shortcomings of css, js and html here (or look me up on g+)]

... and as client projects go, some of the copy is still missing, and some last call changes delayed the whole project quite a bit - always a good thing if you want to get it live asap.

Let's get on with a more productive post about the Hellstrom Project. I haven't been coding much for the last 3 weeks, but I managed to export the last 3d model of the first block and import it into Unity. A quick "walk through" showed that the map is a bit - shall we say - crowded and things were a good deal to close together.


Sketch of the original layout.

... and so I decided to scale things up a bit. The first thing that got bigger was the waterfall, while the "old" one was about 4m high, the new one should be about twice as high (and wide), after I made that bigger the whole layout of the map had to be changed (which was the plan anyway), but I didn't want to just scale things up by 2.


Now that's what I'm talking about ...

In the end I thought: "Oh for fuck's sake" and sat down for a quick sketch of the new waterfall area of the map. Lot's of rocks to model, but funnily enough I'm looking forward to it.

Hopefully I'll have that modelled by next week (and I have something to post).

-- Oliver (nGFX)