Ranking System in Racing Game

Hey guys,

This topic has been driving me up the walls and has shown me that I really don’t quite understand how arrays, lists, etc. work. I’ve already been trying to google for WEEKS (!!) now in order to find out how to do this kinda stuff properly, but this challenge has been way over my head so far.

So, here’s the design: I have a racing game and I want to always track the players positions. Every car has 3 variables:

lap = The lap the player is on
checkpoint = The number of checkpoints the player has passed
distanceToCheckpoint = The distance to the next checkpoint.

In terms of logic, I’m trying to sort it all in this order: Lap → Checkpoint → Distance.

So first I have to check over the laps the cars are on.
But if they’re on the same lap, I have to check which checkpoints they’re on.
But if they’re on the same checkpoint, I have to check which car is the closest to the next checkpoint.

I’ve been checking Unity Answers, the Unity Forums and some other places and since Javascript now supports Lists, I think most people suggest that lists should be used for something like that.

My issue is that this is really goddamn complicated, since I constantly have to Compare the variables within the arrays / lists between 4+ cars and then figure out who’s 1st, who’s 2nd, who’s 3rd, etc.

I found out that I can use a Compare Function like this:

 function CompareCheckpoints(carP1: GameObject, carP2: GameObject): int 
 {
   var scriptA = carP1.GetComponent(carSettings);
   var scriptB = carP2.GetComponent(carSettings);
   if (scriptA.checkpoint > scriptB.checkpoint) return -1;
   if (scriptA.checkpoint < scriptB.checkpoint) return 1;
   return 0;
 }

…in order to find out which car is in the first place based on its checkpoint var. Now, this works nicely for 2 cars, but I’d have to do a whole lot of > and < in order to find out the differences between multiple cars.

So I kinda think I know how this could be done in a very, very complicated way, but I’m hoping someone here already coded something like this and could give me a hint on how to go about it in terms of logic / code, preferably in Javascript :wink:

Well, trying not be condescending but if you think games are easy to make because they are easy to play, then …well…

The way you describe is pretty much the way to go. What you consider complex is not and you seem to have the correct thinking as well so just go on with it.

  1. Get the current lap and order your cars
  2. Get the current waypoint and order again
  3. Get the closest to the waypoint and final order

No easier way I can think of that would not take advanced complex algorithm to gain that little nano second you can’t care less about, and this is pretty efficient too since it is just a bunch of arithmetic computation. One thing you can do is run the method only at lower frequency, like 2 times per second or even once per second as it is enough to keep track of position.

One thing you could do is optimise your ordering with binary search for instance.

EDIT based on comments:

Each car has a script that keep track of the lap and waypoint
You could have a value that is :

 counter = lapCount * 1000 + waypointCount * 100 + distanceToPreviousWaypoint;

The you have LapTracker that gather all cars into a list or array and order by that value

m_targetList.Sort(delegate(GameObject c1, GameObject c2){
     return c1.GetComponent<Tracker>().counter.CompareTo
                 (c2.GetComponent<Tracker>().counter));   
         });

Note thsi is only valid if the distance between waypoint is less than 100 units. If more than that then you need to change the multipliers for 10000 and 1000 to make it consistent.

Or you could do it with trigger colliders.

Stretch a trigger collider across the start line. Have the car store the lap its on and if the car is the first one to hit the trigger tell the leaderboard that car is first for that lap.

Say you got four cars and one is in the pits. 3 cars are on lap 3 but when that car hits the start line increment the lap to 1 for that car then check its position for lap 1. It’ll be fourth.

Put triggers on each way point just use the same logic without incrementing the lap.

Youll have to watch out for cars going off and going through a trigger twice but you only really need to set it to the same value as the last car without incrementing the number of cars that have gone through that trigger.

Sorry for typos, on my phone!