Gaming Your Way

May contain nuts.

... oh bummer.

The title says it all. Note to myself: If you sell a client a game based on your own but you're not allowed to credit for the client version, you're also "not quite" allowed to use the same visuals on your own public version. Well at least for the next 12 month.

The point being that I've been told not to "advertise" my own version of the game with the visuals I've produced for the client version. One could argue that *I* have created the visuals, so it is my IP, but hey, I earned quite a nice sum with it being "exclusive" - so I have to swallow the bitter pill and do a complete visual redesign (including menus, cars and track pieces) ... and I'm not quite sure if I could take it ...

Oh well.

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

Spoiler ahead

Ok, here's the deal, I post a few pictures now and I don't want to start a system war about what kind of system is the better one for playing games. 

...

...

...

...

I got my Xbox One the other day (and a day one edition at that), but due to the odd family commitment I haven't touched the box until a few minutes ago.


Yes, indeed a day one box.


Seems to be a Xbox One - guess why I know it?


Don't play with plastic bags ...


All mine! ALL MINE! Muhahaaaahahaaaa ....

Well it seems that I have to find room for another brick ...


The new Kinect sensor is larger than the old one and it doesn't have an USB connector anymore Also the cable is a lot thicker.


Finally. This one is also bigger as my old 360 (the black one).

Let's get this thing connected ...

... back, 30 minutes later. Update installed (500mb), Kinect set up, logged in to xbl - all seems to work. The new dashboard is a bit different so it took a minute to find my way around, but voice control is working flawless so far.

The new controller isn't as heavy as the 360 one, but then I use the chatpad which adds a few gram to the equation. Still, it feels like it was made for my hands, the sticks are a bit easier to move it seems, but that's not a bad thing. I just hope the bring the chatpad back because I very much liked it.

Oh, the the thing is silent, nearly impossible to hear from the couch - you couldn't say that about the first xbox 360 (the white one). I'm going to have a look at AC4 now ...

... 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.

"TV and the Internet are good ...

... because they keep stupid people from spending too much time out in public."
― Douglas CouplandJPod

I wonder what spambots will make out of that.

Anyway, it's Sunday again and time for the weekly post. Problem is, there's nothing even remotely game-related to write about. I spent most of the time coding a client project and let me tell you: writing an e-mail verification system is oh-so-shit boring. Plus keep in mind: never underestimate the user to do something really bone-headed when presented with a simple form.

What's not to understand with "username, 8 to 16 characters, allowed are letters A-Z, numbers, minus or underscore, do NOT use ä,ö,ü,ß"? You know it when you've got the first one on the phone telling you "I can't enter my username - it's 'Hans Müller' " ...

Ok, to make this post just a tiny bit useful: what about using a cloud based sync and Unity projects?

I for instance gave up on the idea to store a Unity project directly in the Skydrive folder (but it's the same for Dropbox, google drive, ... whatever). The problem is that unity creates a shitload of temp files whenever you change code and it recompiles it. For me it worked for some time, but then it choked and resulted in missing files.

But I wanted to sync my current Unity project between 3 computers without using an USB Drive, the obvious and quite simple idea was: use 7zip and a batch file (two actually). I use 7z as it has a nice command line version and it creates a slightly better compression than zip and I can't stand rar.

So when starting to work I hit the "unzip.bat", which deletes the local project  and then unzips the project from the cloud (and starts Unity afterwards). When done for the day it's "zip.bat", which zips the local project and moves it to the skydrive folder. It really is a no brainer, but it saves a good deal of traffic and time - 26mb (7zip) instead of 157mb (uncompressed, ~4500 files) or 38mp (zip) ...

I'm going back to code some game related stuff tonight so at least I have something for next week.

-- Oliver (nGFX)

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)