Trying to sort a dictionary for my racing game but sometimes the last player for some reason comes first?

So, I’m creating a racing game and I have to sort the times so I can see which player got which time, and I did the sorting of the dictionary but sometimes, when I’ve tested and come in dead last for some reason i’m first when I print the table?

Also it’s hard to replicate this bug because sometimes it doesnt happen?

Data Structure

Code For Sorting Dictionary

local function sortByRaceTime(a,b)
	return self.finished[a]["RaceTime"] < self.finished[b]["RaceTime"]
end
	
local sortedEntries = {}
	
for key, data in pairs(self.finished) do
	table.insert(sortedEntries, {key = key, data = data})
end
	
table.sort(sortedEntries, function(a,b) 
	return sortByRaceTime(a.key, b.key)
end)
3 Likes

If a new player joins, maybe it will set their time to 0. Does this happen?

3 Likes

Sorry I forgot to add but this is how the data structure looks, also I’m actually testing it with npcs but it works with players aswell, also no it doesnt set anything to 0

2 Likes

Interesting. I still don’t have enough information to see the issue. How are you determining who comes in first or last? What is self.finished and sortedEntries? Which one is the supposed data structure? Are you sure sorted entries is not a dictionary?

2 Likes

okay so here is a video of the bug and show the results UI, so you can see what im talking about, also I have code on the client that just creates the templates from the sorted table I pass from the remote event, and I have tried printing out the sorted table that I pass on the server , ON the server and ON the client and it’s the same table showing up and when the bug happens the first player with the highest time is first

2 Likes

Well im determining that by seeing who has the fastest time by sorted the self.finished table, sortedEntries is the dummy table I use to sort the entries I get from self.finished

2 Likes

Interesting. How exactly are they indexed when you show them on the UI? The data structure image looks OK to me like it’s working properly.

2 Likes

Yeah so basically this is how I do the client side stuff, I just get the table I passed from the remote event

Server Firing Remote

RemoteManager.Results:FireAllClients(sortedEntries)

Client Handling Remote Call

RemoteManager.Results:SetClientCallback(function(...)
	local args = {...}
	
	local finished = args[1]
	
	for place , tbl in pairs(finished) do

	local finishedPlayer = game.Players:FindFirstChild(tbl.key)
	local theirTime = tbl.data["RaceTime"]
	
	local Template = ResultsTemplates.Template:Clone()
	local photo = Template.photo
	local displayName = Template.displayName
	local placeLabel = Template.place
	local timeFinished = Template.timeFinished
	local username = Template.username
	local pb = Template.personalBest
	local xp = Template.xp
	
	if finishedPlayer and finishedPlayer:IsA("Player") then
		local result = Players:GetUserThumbnailAsync(finishedPlayer.UserId, ThumbType, ThumbSize)
		photo.Image = result
		displayName.Text = finishedPlayer.DisplayName
		placeLabel.Text = "#"..place
		timeFinished.Text = theirTime.."s"
		username.Text = "@"..finishedPlayer.Name
		pb.Text = "PB: "..tbl.data["PB"].."s"
		Template.Parent = ResultsWrapper
		Template.Visible = true
	else
		displayName.Text = tbl.key
		placeLabel.Text = "#"..place
		timeFinished.Text = theirTime.."s"
		username.Text = "COMPUTER"
	end
	
	Template.Parent = ResultsWrapper
	Template.Visible = true
		
	end
end)
2 Likes

Looks OK, but since it is an array, change pairs to ipairs and see what happens.

2 Likes

Alright I tried changing to ipairs but it just didnt change anything, when I came in last it’s still putting me as the first index for some reason

1 Like

Interesting. Try sorting the table on the client instead of the server. It might work, but I don’t know if it is sorted when it is sent or not.

2 Likes

Yeah so basically I sort it before I send it to the client, but why do you think sorting on the client would help, is there something happens between sending over to the client via a remote event?

1 Like

I’m not exactly sure what works and what doesn’t when send, but I’ve never expected tables to be sent in the same order.

2 Likes

Okay, so I just changed it to send over an unsorted self.finished table and as I thought it didnt work too, I changed it back to how I had it

1 Like

So, did you sort it on the client as well?

1 Like

Oh the sorting worked but when I came in last it still put me in first place on the UI and in the output in the console aswell

image

1 Like

That did not happen earlier. The sorting function is the same?

Nope didnt change a THING, that’s the thing it’s sometimes works when I’ve come in like the place right before the fastest person or maybe the place right after the 2nd fastest person or the place right before the 4th fastest person or right in front of the 2nd fastest person

I FINALLY figured it out like last night or something so basically instead of just sorting I just inserted the players as they finished and that would automatically tell me who finished first because it would come in order as they crossed the finish line!

@SubtotalAnt8185 Thanks for all your ideas and help!

if participant:IsA("Player") then
	table.insert(self.finished, {
		name = participant.Name,
		raceTime = string.format("%.2f", self.elapsedTime),
		PB = Manager.Get(participant, self.name)
	})
	Manager.UpdateBestRaceTime(participant, self.name, string.format("%.2f", self.elapsedTime))
	participant.Character:PivotTo(workspace.SpawnLocation.CFrame + Vector3.new(0,5,0))
else
	table.insert(self.finished, {
		name = participant.Name,
		raceTime = string.format("%.2f", self.elapsedTime)
	})
	participant:PivotTo(workspace.SpawnLocation.CFrame + Vector3.new(0,5,0))
end

Very interesting! I didn’t even think of that.

I wonder why sorting did not work, it is likely a bug in that case.

1 Like