Gaming Your Way

May contain nuts.

I do not fear computers. I fear the lack of them.

... Isaac Asimov.

I'm not sure if I mentioned it, but MTR ("The Client Edition") went live the other day. Well not exactly. It will be delivered on CD-Rom as client give-away. I'd like to post some screenies of that, but we're not allowed to take credits for the game (but then it also uses slightly different graphics). The AI in the client version is - to say the best - quite basic, basically because the game has to get done (and because no one noticed that the enemies driving like being on rails).

This out of the door I can finally overhaul the AI of the public version, adding some new patterns (like flocking, follow the leader and so on) and moving the AI processing away from each car into a central FSM. This may sound like a step backwards, but in reality it makes things a lot easier when adding flocking). Not to mention that this will also remove one component from the cars (the AI controller).

Anyway, there's some reading involved and a lot of client work to do before I can dive into it. One thing I added this morning, though, is the car selection screen. It's not quite done yet (I need to model the "podest" the car will be placed onto) but here's a screenshot. Oh now that I look at it I also should add the track selection sooner or later ...


Oh, I just see next / prev buttons are missing in this shot ...

... Next week then.

-- Oliver / nGFX

Lessons learned the hard way, part 100

Right now I have next to no time for working on MTR, as it's December - which means that about a million client projects should be finished by the end of the month.

Getting my ass up and continue coding after doing it for 12 hours is, let's be candid here, not easy and most of the time I just want to drop myself onto the couch and play for an hour. Right now I'm playing Assasin's Creed 4 (Black Flag) on the XBox One, which is reasonable fun, if you overlook the fact that the novelty has worn off a bit after 30 games with the "same" theme. But the open world and the the lush caribbean environments make up a lot. I event spent some time just sailing between the small island and hunt down the "hidden" items scattered around the map.

Back to the title of the post, which isn't as unrelated to the post as usually.

In the post about the new HUD I mentioned that I want the thing to be dynamic and showing the order of the cars while they progress through the race. With this idea I coded a little sort function that creates orders the cars according to their position on the track. The idea is simple enough: every time a car hits a waypoint, I store it away and use it to sort, higher waypoint id means better position. As the ids start with 0 after a round I just add 1000 for each lap and that problem is solved, too.

There might be the chance that two cars share the same waypoint and this is taken care of by comparing the time when the cars hit the waypoint making the one with the lowest time first.

The first version of this updated the position of the HUD each time a waypoint was his and espeacially in the early stages of the race this could change quite frequently, causing an ever moving HUD (which was quite distracting, tbh). The second thing that didn't work out like planned (quite logical now, but I didn't see this when I thought of it) is the way the time is displayed. I only wanted to show the current time on the first car and show only the difference to the first on the other cars. Yet again, during the start of the race there is nearly no difference, resulting in changing 1/100 secs, which didn't help at all. I'm going to test if I may stop the time for 2nd, 3rd and 4th car, showing a fixed difference (instead of a running time) to the first car and update it only every odd waypoint. Either that or I drop that and just show the race time ...

No image this time (it would just show the track, 4 cars and the HUD anyway), maybe next week ...

-- Oliver/nGFX

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.

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)

#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) 

New rules ...

It seems that I'm now a proud member of the Iron Blogger Community, in my personal case it's http://www.ironbloggerruhr.de/. The idea is to write at least one post per week or you have to pay a fee (which is used to buy beer when we meet once a while).

Announcing that I'm now a member of an Iron Blogger "chapter" counts as a post for that week, but that would be a bit lame.

I'd like to post some progress on the MTR racing game and as a surprise ... I even have to report some progress - sort of.

I'm not sure if I mentioned how the AI in MTR works, but I guess I might repeat myself to get to the point.
When I posted the last time the AI was using waypoints to move along the track and not, say, a fixed spline (which would be oh-so-much easier). I use waypoints, because there is a track editor build in and players can build their own tracks, if fact I do some blending between waypoints so it's nearly a spline.

Anyway, the trick is to actually hit the waypoints when moving along the track, because sometimes you're coming a bit to fast down a ramp and the "hit waypoint" radius is just the few digits to small and so you missed your target waypoint. Detecting that is quite easy - if the allowed angle between driving direction and car/waypoint is too big, we simple jump on to the next waypoint in list and continue driving. The problem is: what do we do if for some odd reason the car turns a bit too much before it hit the waypoint (crashed into some other car maybe) - in this case it all can go berzerk faster as you can mumble "fuck". 
And then there are the other cars, having 4 cars chasing the same waypoint always ends up in a crash and then in missed waypoints ... the obvious solution is to prevent crashes, but that doesn't always work out like planed, too.

The first change I made, was to add 2 more waypoints and so having "lanes" on which the cars drive - this worked better. I created waypoints on the left, right and center of the road and give the cars a "lane" (ie: 0,1,2) on which the want to stay. As far as you want that all is good, but once you want to change lanes things get complicated again.

The current version uses a "floating" waypoint, it goes from the left side of the road to the right side and the AI cars use a float (0-1.0f) to see where they want to hit the wayoint (this also allows to use a "desiredLane" value and blend the current lane with the desired one over time). Now the AI cars cannot miss the waypoint any more, they just can miss their desired lane).

Phew, a lot of words, time for an image.

This is what I've been working on for the last couple of weeks (and prevented me to do any real work on MTR): animating and rendering a lot of small animations showing smoke and fire (sorry no further explanation just yet).

And with this, see you all next week.

nGFX

The world in words and pictures

My calendar icon tells me it's Monday  - and July already. This means I've not only missed the start of the summer, but also don't know what happened during the last six month.

All I know is that I started to work on a small scale semi top-down racing game that should be finished in "not more than 3 weeks solid work".

Ha!.

Anyway, the blog needs writing and images.

I've added a new car (see image), coded parts of the backend (for storing tracks "in the cloud" - just to use a buzzword) and a lot less bugs than on my last post. All tiles have been redone, as I needed to split the floor (road) and side (rails) colliders and even a few deco tiles have been added to the editor.

"Right away Michael."

"Look, it's a tree"

What I don't have is solid physics and a working AI. The first is a matter of bending the rules to my favour - which slightly collide with the rules the physics engine believes in. The latter results in parts on the first problem and my stupid idea to control the AI cars using the same principles as the player car, read instead of telling the car to "drive at speed Y" or "turn left X°" I simulate the controller as if a human would be playing. Of course I have a stupid (but perfectly valid) reason for that - playing back things.
Right now I'm brewing a nice mix of waypoint driving, raycasts and player data and it nearly works the way it should, well it works the way it should, but at times it fucks up due to "unforseen" events. 

I'd love to write some more, but just as the weather became fine, there are deadlines to meet ...

 

nGFX