OK Guys, I'll present the reason I'm in debt with Tank Battles (the programming game I talked about). It's called Dirty Racers and it's a fast racing and combat game that I subscribed to a indie game contest that will be part of the Brazilian Simposium on Games (SBGames) this year. I've been replacing my sleeping nights with a LOT of jME and jMEPhysics2 programming and tweeking. From the lessons learnt I will be posting a TestCar.java (with related classes) any time soon for those interested in vehicle simulations.
By this time I'm using only fixed function (aka no shaders). The performance is quite nice: 250+ fps with 4 cars (9 physics dynamic objects each), per triangle collision for the terrain mesh.
Effects are only particle systems;
Dome implemented from the SkyDome example from the wiki;
TerrainPage with procedural splatting only;
Each car has a different driving feeling (4wd vs. front vs. rear traction; acceleration, speed, handling);
Physics by JMEPhysics 2 with dynamic obstacles spread on the tracks;
Each track has its own feel because of the different physics material for the terrain;
Joystick supported (and recomended for 2 players split screen);
Splitscreen mode for versus race.
Main Menu with demo in the background:
In game on the Desert track:
Next I plan to use some reflection and lighting shader on the cars and a different one for the terrain with some bumpmapping, as well as applying a shadow pass.
- I do this calibration by recording some laps I make myself (I'm quite good at racing games - :))
Is this automated stuff? That would mean that different drivers used for callibertion could result in different AI personalities.. no? That would be cool.. You could even automatically download AI's based on other people's driving into your own game, since I reckon they won't take too much data... (kind of Spore like)
The last one doesn’t really expose any implementation details, but is quite interesting.
My implementation is REALLY simple, but I liked the results and you’ll see it in action on the video I’ll post this weekend. Some things:
For AI cars, tracks are (as in most race games) a collection of WayPoints, in my case each waypoint is a Large jME sphere (not in the scene graph, so not drawn)
Each car has, at any time, a reference to the current waypoint it has to go to.
I only have to test collisions of the car with its current waypoint.
When reaching the waypoint, the car references the next one and so on.
This is the basics… How to make it work is the key. Some more considerations:
Each car allways tries to turn towards the waypoint (unless trying to pass or avoid something else - later)
Each waypoint has an attribute with its IDEAL speed for that point (this is really necessary for the car to make tight turns)
Each car always acclerate to the next waypoint, and when near it brakes (proportionally to the distance) to the ideal speed.
This is enough to make them follow the track and make very good times… Just have to calibrate the waypoint's location and speed.
I do this calibration by recording some laps I make myself (I'm quite good at racing games - :))
The style part:
When turning towards the next waypoint, each car steers its wheels proportionally to the relactive angle (facing direction vs. where to go to -vector3f vector3f)
This would make them DEADLY stable and fast, so I introduce a random style factor. Each car has a coeficient of agressivness, which makes it turn more than it needs… That makes it occilate more than others (and the same happens when trying to pass)
The other stuff:
Each car always tests if it'd be efficient to fire against some other in front of it. Does it when it's almost in front (so doesn't miss) and when the car is not so near, maybe staying in the way.
When near the car in front, tries to pass, to the right or left, depending on where's the next waypoint, distance to it and hows the relactive angle between the facing and the next car.
Since the physics are simulated, there's A LOT of randomness in all the races and the times vary constantly. The cars also have different behavior, because of the rear vs. front vs 4wd tractions and different max speeds and accelerations. But if I put one car alone (no fire hits) it's really fast and constant. That's what's expected from a good driver.
An example, AI car laps:
45.573s (first one, froms tart)
My personal record in this particular track is: 43.271s
This is the hard mode (not final calibration). For medium and easy modes I just add some speed limiter factor to apply against the ideal speed for that sector. This limiter is proportional to the position (1st has the biggest limiter), but this happens only in medium and easy difficulties. In hard mode there are no limits for the AI cars.
Next steps will be:
Make more than one available set of waypoints (different trajectories)
Making the cars get better in long races, learning from mistakes (race strategy also)
Making different CarDriver agents for each car type (parameters or some recordable learning, like neural networks)
Static obstacles are placed where set, but dynamic ones are placed randomply. The number of them depends on the quality you choose in the beggining, because they are physics nodes and consume CPU power.
I'm here to announce that I'm releasing the full source code for Dirty Racers… The game got third (3rd) place in the contest and I have some plans on modding some things and creating more content to it… But I'm happy to share the code with the comunity.
The code has valuable things, but some parts are not so well organized because of the tight schedule used to produce the game. It's been conceived, developed, tested and debuged in only three months, between july and september…
Anyway, here's the link for the first version of the code… I plan to put it in a CVS or SVN and create a home page for it soon:
(edit) The zip file above is the whole Eclipse project, without the compiled classes, so you'll have to import it inside Eclipse and run the init.DirtyRacers class from there…