Zombie simulator: the road to hell... PDF Print E-mail
Friday, 26 February 2010 19:03

...is paved with 32x32 pixel concrete tiles.

My recent efforts to resize the road tiles has given me some extra space to play with around intersections, which allowed room for "end of lane" markers at stop signs and traffic lights. The process of implementing this took quite some time, leading to me completely re-draw the road texture since I wanted to also include a darker stripe down the middle of each lane that's caused by the occasional oil drip from cars as they travel along.

Now that the roads are more than wide enough to handle the cars properly, I also decided to expand the width of the pavement since it was starting to look a bit narrow. This, of course, made things even more complex since the road texture now had to contain a strip of pavement along the edges. A bit of trial-and-error lead me to settle on constructing the pavement from an 32x32 pixel tiles, so I readjusted the road once again to allow for for this. I also  threw in a few extra pixels for a kerb, which for now is a flat grey, but will eventually be shaded to give it a 3D look.

With these textures pretty close to final, it was back to the code to create polygons alongside the edge of the road. I decided to use much the same process as I for creating the roads, doing it this way because I found that having an array of polygons defining the road made it a lot easier to generate the paths that the cars would follow, and since humans will also be following paths, it stands to reason I'll need to know where the pavements are.

If luck is on my side, it won't be much longer before humans and cars are sharing the city streets!

 
Zombie simulator: it's alive! PDF Print E-mail
Wednesday, 24 February 2010 21:00

Finally, it's time to work on the city's denizens... starting with the un-undead, otherwise known as "Humans".

More b3d exporting troubles

My first stop was Blender to add some animation frames to the guy in the jumpsuit that started this whole project. I added some key frames with five different poses, one for standing still, and the other four for various configurations of one foot on the ground, which, when put together, make it look like the little guy is walking. This is called a "walk cycle" and I found this tutorial made it simple to setup, literally taking an hour, beginning to end. Well, to be honest, I don't need a very accurate walk cycle because my guys are going to be quite small, so I can get away with cutting some corners.

Creating a walk cycle in Blender

Back to the Zombie Simulator, it was time to run the sprite generator module to see what It'd give me... Many moons ago, when I wrote the sprite generator, I planned ahead for handling multiple animation frames, though I hadn't had a chance to test it. After feeding the jumpsuit guy into it, the output was less than stellar. Sure, it was obviously animating, but the end result looked rather like half the vertices were being left behind as the arms and legs moved... it was looking like something out of an early 80's music video...

Thinking that maybe I'd screwed up the sprite generator, I loaded jumpsuit guy's b3d file into Irrlicht's example 09, which is a 3D model viewer and the same problem showed up, so it wasn't my fault, but I still had to fix it.

There were two possibilities that came to mind, one, that the guy's texture was spread across two different images (I ran out of room on the first one), and two, that the sprite model itself was split between two objects (the hair and collar are separate from the body). After playing around with the model for a while, it turned out that the problem was that the guy's model was made up of two separate objects. As soon as I merged both and re-exported, the sprite began to render correctly.

Back to the code, I added a new class to handle animations, created an XML file to store the animation info (no hardcoding for me!) and then created a single animated sprite for testing purposes at the top left corner of the map. Astonishingly, it worked, the little guy was actually moving, however I noticed after a while that he appeared to be doing the moonwalk... there were several animation frames missing.

Using the correct options when exporting a Blender animationWhat was at fault this time? The b3d exporter or Irrlicht's importer code? I put some debugging code into the b3d exporter and re-ran the export. The output showed that the b3d file had the correct number of animation frames, so Irrlicht was at fault here. Through trial and error, I've since discovered that that the only way to get animations to export properly from Blender is to use the b3d exporter's timeline option and extend the timeline so it includes one extra frame either side of the animation. Then, when Irrlicht reads the file it drops the first and last frame and the correct number of frames will be loaded.

To paraphrase, the latest b3d exporter lessons that I've learned are:

  • A bone animation must include only one object
  • Export using the timeline option with an extra frame padding the start and end of the animation

Moving forwards

The next step in this project is to finalise the road textures so I know how much room I have to play with for the pavement, then I can move onto setting up the path following for pedestrians, which should be a lot simpler than the vehicle path following. Pedestrians are a rude lot and will simply push past one another, dodging and weaving around obstacles. They don't don't need queue in neat orderly rows, they don't need to give way to the right and they move slow enough that collisions with each other are not an issue. It's so much easier dealing with legs.

After the guys are walking I'll be looking at creating some new skins for the human model to add some variety, and then it'll be be time to create a modified human model that will server as the lowest level zombie... mmm... zombies!

 
zombie simulator: traffic rage PDF Print E-mail
Wednesday, 17 February 2010 18:22

"This should be easy"!

That's what I said to myself when I started coding the car control, to get them driving around the city.

The first issue, as previously mentioned, was OpenSteer. Having overcome that, it was time to get the traffic to obey some rules.

Getting these cars to avoid accidentally hitting each other was a nightmare!

I can only assume I designed this the hard way, because I ended up in a situation where I had large blocks of if..then..else statements telling cars what to do at the different kinds of intersection, how to handle traffic lights, etc. and every time I made a change to add or tweak a rule, it caused unintentional havoc elsewhere breaking the previous rules I'd implemented, leading to mass pile ups.

It got so bad, once I had all the basic driving rules in, all the cars were being incapacitated from damage within 60 seconds of starting the engine!

You'd think it'd be easy, the roads are all at right angles, there's only two intersection types. I suspect my mistake was using OpenSteer for both road following and random path following. OpenSteer is rather loose in it's interpretation of what "path following" is, and cars will tend to drive a line that is the average of the path in the vicinity, so they'll both cut corners and take a slightly different line into corners every time. That is what made it hard to pin down the rules.

For me to reach my goal, I need the cars to cruise around without unintentional accidents for at least 10 minutes... after many, many painful hours I've finally got that happening.

Almost.

I've just been able to run the engine for 10 minutes with only a single collision - nothing major, just a sideswipe, more like "paint trading" really.  I can live with that.

Hopefully I can move on to something more interesting now.

Here's a video of a working intersection. I've drawn coloured lines (which are blurry in Youtube) between the traffic lights to show what colour the lights are since they'd be too hard to see. The cornering still needs a little bit of tweaking but I'm going to put that off until I've finalised the road width and texture.

I also noticed that the youtube videos were running at half the recording speed... I guess I didn't realise that was happening because I'm so used to running it in the debugger in slow motion :)

Dim lights Embed Embed this video on your site

 
Zombie simulator: Open Steer is a beast PDF Print E-mail
Friday, 12 February 2010 21:58

Several days later, and I'm starting to get the cars working the way I want.

The reason for the delay is Open Steer. It's simply undocumented, and the example demonstrations are over-engineered to say the least. The forums have been minimally helpful.

Since I released the video a few days ago that showed the steering behavior working pretty well, I've been picking apart how Open Steer does it's job in an effort to figure out how to get the cars to do exactly what I want. There is no documentation besides comments in the code, and the internals are pretty complicated in places, so I've found that the best way to get familiar is to set it up to do what I think it should, then step through the code to find out why it's not behaving. That can take a while.

I thought I'd list a few of the more important limitations/weirdness/gotchas that I've found when playing around with this library.

  • All the available methods are aimed at keeping the vehicles moving. One of the possible reasons for this is that the API doesn't really have a proper method for stopping a vehicle. Sure, there's the SimpleVehicle::applyBrakingForce() method which comes close, but it doesn't actually cause the vehicle to stop, it will continue to creep forwards.
  • The LQ Lattice proximity database is definitely the best one to use for what I'm doing, and I'd be surprised if it's not the best for all but the simplest systems. It's purpose is to allow vehicles to only be tested against other vehicles that are nearby, saving valuable CPU.
  • One thing to watch out for when you create an LQ lattice database is that you'll want the size of your lattice to be bigger than the maximum area in which your vehicles can travel. The reason is that a vehicle that is overlapping the edge of the area will be considered to be outside the lattice, so proximity tests will then be made against all the active vehicles, effectively using the brute force method. This includes keeping an eye on the radius of your vehicles. As an example, I'm using a 2D lattice, and I had to make the lattice depth (Y axis) larger than the radius of my largest vehicle, or the brute forth method was used when checking for vehicle proximity.
  • The steerToFollowPath method is approximate at best - sure, it'll keep the vehicle on the path, but it will wildly swing to the left and right as it hits bends, and no amount of tweaking the parameters would fix this - the closest I got was to set the steering force really high, but that caused the car to shudder and wobble as it rolled along the path. If you want your vehicles to closely follow a fixed path, you'll need to come up with your own solution. The way I've done it is simply to apply force directly towards the nearest point on the path. No fooling around with approximations and smoothing for me!
  • Speaking of approximations and smoothing, there's tonnes of cruft in the example plugins. Most of the calculations made in the Pedestran plugin for instance don't really seem to be necessary, and would appear to have been arrived at through a process of trial and error, tweaking here and multiplying there until the vehicles behaved as expected. The MapDrive plugin is similar in that it really is overkill, presumably because it was intended to drive a real robotic vehicle across real terrain.

Overall, Open Steer is worth the effort to use, even if just for the LQ Lattice alone.

As I write this, the car control is probably about 80% complete. I've got the cornering working a lot better, the cars will actually slow down now. They'll also queue up if the car ahead slows or stops. I've been able to overcome the creeping problem and I've even got cars giving way to the right at three way intersections. The last thing to do is to get the cars paying attention to the traffic lights I'll finally be able to move on.

 
Avoiding admin users counting in Google Analytics PDF Print E-mail
Thursday, 11 February 2010 21:45

I hadn't realised, but over time, I'd gradually become "gun-shy" about clicking the links on my own site, and Google Analytics is the reason, but not the cause.

Since setting up my blog a few months back, I've been using BIGSHOT Google Analytics plugin as a convenient way to add the Analytics javascript to my page and although simple, it got the job done.

The only issue I had with Mr. BIGSHOT's effort is the same issue that I had with all the Analytics plugins - they don't distinguish between admin and visitor clicks.

In my case, as a solitary admin, I like to view a page once it's been published, then go back and forth a few times, editing and viewing, to remove all the insults and curse-words. With Google Analytics constantly active, all those clicks on the front-end are counting towards my site's totals for such things as unique visitors, page views and time on site.

That of course throws out the real figures, which over time lead to me avoiding using my own site, and that meant that little problems went unnoticed. Little issues like broken links, categories pointing to nothing, bad font colour choices, RSS feeds in the wrong location on certain pages, etc.

After a few hours of heavy tweaking yesterday, I checked Google Analytics only to discover that I'd apparently been responsible for 50% of my site's page views for the day! Now I've got an indelible "phantom" spike on page views for February 11th that I can't get rid of... enough is enough.

Doing something about it

The first stop was to check the Joomla Extensions site to see if a new plugin had popped up that avoided counting admin clicks. To my surprise, there was new one called WebGuru's Google Analytics for Joomla, proudly boasting that it solved the unsolvable: "Don't track your visits, track your visitors".

I updated the testing installation of my blog to the latest version to try out this bold claim, installed WebGuru's software, and viewed a page. Sure enough, the Google Analytics code was gone.

Aha! A solution, or so I thought.

Trundling off to my online server, I installed the plugin, refreshed the front-end and viewed the page source. No dice, the Google Analytics code stubbornly refused to budge.

WTF? It worked on my test server.

The mystery solved

To cut a long, boring story short, I spent quite a few hours researching what had gone wrong, and it turns out that WebGuru's solution depends on the definition of "logged in".

Joomla is composed of a front end and a back end, both of which can be logged into separately using the same credentials, resulting in separate session cookies. WebGuru's solution relies on examining these cookies, comparing them against the session variables recorded in the jos_sessions table, to see if one of the cookes has a Group ID in the range of the admin user groups. If one is found then an admin user is logged in, so the plug-in simply doesn't add the Google Analytics code to the bottom of the page.

Easy, that is, unless you are logged in through the back-end on a secured web server, which is how I normally am, since I'm just a solitary blogger and I'm always tweaking. The problem here is that the back-end cookie is secured, so it isn't visible from code running on the front-end, which means that the plugin, when run while generating a front-end page, won't see the admin user's session cookie, and so won't know and admin user is logged in.

That's the reason why WebGuru's plugin worked on my development server - I'd disabled most of the security to make it easier to work on, which meant that the plugin could see the admin cookie.

I haven't tested it, but in theory, the WebGuru plugin should work OK if the admin user logs into the front-end whenever they are logged into the back-end.

A workaround

Suffice to say, I tried everything, even time travel, to make it work the way I use Joomla, but to no avail.

I did however come up with a kludge. I altered BIGSHOT's plugin so that when an admin user refreshed the back-end, it would write a list of session cookie ID's that it could see to a table I created in the Joomla database. Then, when the plugin was run from the frontend, it would look at this table to see if the current session id was in it. If it was, then that meant that the back-end could see it, and thus somebody has logged into the back-end, presumably an administrator, Me.

This works because the front-end cookies aren't secured, but it relies on me browsing to my blog first thing to have it create a front-end session, then opening the back-end to put the session into the table. Messy, but not difficult.

I won't be publishing the code for this as it's a horrible hack and I really don't want to be blamed if you start to think your site is underreporting visitors.

In the long run, once the site has settled down enough that I can stop playing around with plug-ins and tweaking settings, I'll have to bite the bullet and start using Joomla as a front-end admin...

 
Zombie simulator: near perfect path-following PDF Print E-mail
Tuesday, 09 February 2010 19:38

I spent quite a few hours working out most of the kinks in the path-finding function, so it's now able to accurately start and end each path at an intersection, where the next decision has to be made on where to go.

After that, I boosted the number of cars in the test environment to 250 to see how it ran... not too badly. The frame rate dropped to about 110 to 190 frames per second depending on how many cars are on-screen at once. Code profiling reveled that there's nothing extremely inefficient going on in the background, except for our friend toOpenGLColor() which continues to make it's presence known by gobbling up 20% of the frame rate. It looks like I will have to tackle that problem some time.

Once I had all the cars on the road, I noticed that they really all looked the same, even though there's four different kinds at the moment. The reason for this is that colours are fixed in the vehicle XML file, so that meant it was time to unleash random car colours I'd been threatening!

I modified the model loader so that the vehicle XML file can be used to specify "random" as a colour choice, or a fixed colour, which allows police cars and taxis to remain a white or yellow while everything else is a hippie-mind-blowing-rainbow-of-colour.

I also implemented picking on the car nodes so I can select them...

Here's a quick video.

Dim lights Embed Embed this video on your site

One thing to note is that the video capture process can cause the number of frames captured per second to fluctuate... the game frame rate fluctuates too, so it makes it appear like the frame rate is steady... except for OpenSteer, which notices the delay and moves the cars further on the next frame if there's a slow down while saving a frame. This of course means cars tend to overshoot way-points occasionally in the video, and they will spin around or suddenly reverse direction. It doesn't happen while actually playing with the engine, honest!

 
<< Start < Prev 1 2 3 4 5 6 7 8 9 10 Next > End >>

Page 1 of 15