How to Track Every Player and Find Their Distance Version 2.0 [ đźź§ 7/10]

January 23, 2025.

Josh deleted all files on the forums. Many amazing guides became unusable because of this. One of these guides was my own. It had months of dedication put into it, and I was heartbroken when I learned that others couldn’t use it anymore. But many people loved my guide, and I still get notifications for it fairly often. I’ve finally decided to fix it. It is now way simpler to build, and uses a lot less memory! With that, I give you,

How to Track Every Player and Find Their Distance… Version 2.0!

What we'll be making

Gimkit showcase
Sorry, the GIF quality is bad. If you look at the top right, you will see an overlay that contains every player’s positions, as well as another string of text, which you might know to be the new player’s unique ID! In the bottom right, you can barely make out that it shows the position of the closest player, and your distance from them.

For those that are curious, here is a link to the original version:
How to Track Every Player and Find Their Distance [ 🟥 8/10]


Materials

This list is sorted first by the greatest number of devices to the least, then by how much memory they use.

“Property” ×7 (70 memory)
“Item Granter” ×2 (1,570 memory)
“Game Overlay” ×2 (1,350 memory)
“Player Coordinates” ×1 (3,500 memory)
“Trigger” ×1 (40 memory)
“Relay” ×1 (20 memory)
Friends: 2 - 3 recommended, but you can just open the game in separate tabs.
Total memory: 6,550

That is a difference of a whopping 2,315 memory from the first version!


Ladies and gentlemen, let’s get started!

Part 1: Coordinates

Part 1: Coordinates

This is the simplest part of the build, but it is crucial for the system to work. You’ll be needing the “Player Coordinates” and two “Property” devices.

Give one “Property” device these settings:

Property Name: My x
Property Type Number
Default Value: 0
Property Scope: player
When property value changes, transmit on:
Broadcast value change on game start: No

And make another “Property” device like this:

Property Name: My y
Property Type Number
Default Value: 0
Property Scope: player
When property value changes, transmit on:
Broadcast value change on game start: No

And set up the “Player Coordinates” device like so:

When player position changes, transmit on: Update all player data
Update Properties: Yes
X Position Property: My x
Y Position Property: My y

Easy peasy! With that out of the way, we can get into more technical stuff!


Part 2: Setting Player Data

Part 2: Setting Player Data

Now we’ll set up how the player’s coordinates will be sent.

First, make a “Property” with these settings:

Property Name: All player data
Property Type Text
Default Value:
Property Scope: global
When property value changes, transmit on: New all player data relay
Broadcast value change on game start: No

Now get an “Item Granter”. Don’t worry about the settings, we’re just adding a block to it.

Create a new block: When receiving on channel: Update all player data

Set variable (My data) to: create text with (Triggering Player's ID) (,) (Get Property (My x) + 100) (,) (Get Property (My y) + 100) (,)
Set variable (All player data) to: Get Property (All player data)
Set variable (Substring index) to: in text (variable (All player data)) find (first) occurrence of text (Triggering Player's ID)
if variable (Substring index) = 0
do: 
> Set Property (All player data) Value: create text with (variable (All player data)) (variable (My data))
> Broadcast Message On Channel: Check players
else:
> Set Property (All player data) Value: create text with (in text (variable (All player data)) get substring from (first letter) to (letter #) (variable (Substring index) - 1)) (My data) (in text (variable (All player data)) get substring from (letter #) (variable (Substring index) + 33) to (last letter))

Explanation

So this is a lot of code, but what exactly is the point of it? Since we’re dealing with several different players, we don’t want several properties for each player; that would take way too much memory. What if we stored every player in the game’s data in a single property? To do that, we need to make sure that all the player data is the same length as everyone else’s. Since player names can vary in length, we won’t use them. Instead, we can use the player’s unique ID, which always has a length of 24 characters. We’ll also add our position in there, as well as commas to separate everything. We’ll add 100 to our position to ensure that the length of the position remains 3, no matter where we are on the map. (This saves memory and makes the system faster as opposed to the older version.)

Now, we’ll find where our data should go in the string. If it can’t find our player ID, it assumes that we either just joined or the game just started, and adds our data onto the current data. If it does find our data, then it separates all of the data before and after ours, and inserts our new data.

If you’d like to learn more about how text strings work, check out this guide:
The Power of Text Strings [ 🟨 5/10]


These next steps are optional, but are good for playtesting.

Now get a “Relay” and set it up like this:

Relay Audience: All Players
Relay channel: New all player data
Relay when receiving on: New all player data relay

Next, place a “Game Overlay” with these settings:

Overlay Type: Text
Overlay Position: Top Right
Overlay Text:
Visible On Game Start: Yes
Overlay Color: R = 255 G = 255 B = 255
Content Scope: player
Visibility Scope global
Show overlay when receiving on:
Hide overlay when receiving on:

Now give it a block like this:

Create a new block: When receiving on channel: New all player data

Set text: Get Property (All player data)

Congratulations, you’ve finished part 2! You’re almost there, keep it up!


Part 3: Getting Distances

Part 3: Getting Distances

Now let’s go through the whole list of players and get their distances from us! In this system, we will just look for the closest player to us and display their position and distance on a “Game Overlay”.

Let’s first set up the properties that will be used in this system.

Property Name: Closest X
Property Type Number
Default Value: 0
Property Scope: player
When property value changes, transmit on:
Broadcast value change on game start: No

Property Name: Closest Y
Property Type Number
Default Value: 0
Property Scope: player
When property value changes, transmit on:
Broadcast value change on game start: No

Property Name: Players
Property Type Number
Default Value: 0
Property Scope: player
When property value changes, transmit on:
Broadcast value change on game start: No

Property Name: Closest distance
Property Type Number
Default Value: 0
Property Scope: player
When property value changes, transmit on:
Broadcast value change on game start: No

Next, place an “Item Granter” and, once again, don’t worry about changing any of its settings, and add a new block.

Create a new block: When receiving on channel: Check players

Set Property (Players) Value: Get Property (Players) - 1
if Get Property (Players) ≤ 0
do:
> Set Property (Players) Value: (length of (Get Property (All player data)) Ă· 32 + 1)
> Broadcast Message On Channel: Show closest player
else:
> Set variable (Substring index) to: Get Property (Players) Ă— 33 + 1
> if in text (Get Property (All player data)) get substring from (letter #) (variable (Substring index) - 32) to (letter #) (variable (Substring index) - 9) ≠ Triggering Player's ID
> do:
> > Broadcast Message On Channel: Calculate distance
> else:
> > Broadcast Message On Channel: Check Players

What this block does is set the player whose data we’re currently trying to get. If we’re trying to get our data, then we skip the next step so that we don’t accidentally track ourselves.

Now we’ll make one more block in the “Item Granter” that will retrieve the coordinates of the player we’re tracking.

Create a new block: When receiving on channel: Calculate distance

Set variable (Substring index) to: Get Property (Players) Ă— 33
Set variable (X) to: in text (Get Property (All player data)) get substring from (letter #) (Substring index - 7) to (letter #) (Substring index - 5)
Set variable (X) to: variable (X) - 100
Set variable (Y) to: in text (Get Property (All player data)) get substring from (letter #) (Substring index - 3) to (letter #) (Substring index - 1)
Set variable (Y) to: variable (Y) - 100
Set variable (Distance) to: square root ((Get Property (My x) - variable (X))^2 + (Get Property (My y) - variable (Y))^2)
if variable (Distance) < Get Property (Closest Distance
do:
> Set Property (Closest distance) Value: variable (Distance)
> Set Property (Closest X) Value: variable (X)
> Set Property (Closest Y) Value: variable (Y)
Broadcast Message On Channel: Check players

What this does is convert the text string of the “All player data” property to a number, by using a variable to set it, then subtracting 100, which converts it from a text string to a number, and cancels out when we added 100 to the position in the “Update all player data” block.

We’re so close to finishing! Keep it up! Now we’re going to add the display. You can replace this with whatever function you’re trying to create!

Overlay Type: Text
Overlay Position: Top Right
Overlay Text:
Visible On Game Start: Yes
Overlay Color: R = 255 G = 255 B = 255
Content Scope: player
Visibility Scope global
Show overlay when receiving on:
Hide overlay when receiving on:

Now give it a block:

Create a new block: When receiving on channel: Show closest player

Set text: create text with (The closest player to you is at ) (Get Property (Closest X)) (, ) (Get Property (Closest Y)) ( which is ) (Get Property (Closest distance)) ( meters away.)
Set Property (Closest distance) Value: 9999
Broadcast Message On Channel: Check players prep

Add a “Trigger” with these settings:

When triggered, transmit on: Check players
Trigger when receiving on: Check players prep
Trigger Delay: 0.2
Visible In-Game: No
Allowed Team: Any Team
Max Triggers:
Active On Game Start: Yes
Activate when receiving on:
Deactivate when receiving on:
Active Scope: global
Trigger By Player Collision: No

The reason we have this “Trigger” is so that we don’t accidentally try to track players again too soon. Without this, the whole system freezes up. I haven’t tested this with too many people in game, but I do know that the more players in game, the longer the delay has to be. If you want to be safe, I would put the delay at 0.5, but I find 0.2 to work fine.


Congratulations, you have finished your player tracker! I hope you enjoyed this guide and learned something!

Make it your own

Welcome to the “Make it your own” section of the guide, the latest addition to my guides, where I give small challenges to add on to the system and improve your Gimkit Creative knowledge.

  • Make a pseudo-tagging system that sets a property when the tagger gets close enough to another player!

  • Replace player ID with the player name so you can know who you’re tracking (Hint: the maximum length a player’s name can be is 20 characters)


Rate the guide!
  • AMAZING!!!
  • Great!
  • Okay.
  • Needs improvement.
  • Bad.
  • WORST GUIDE EVER ON THE FORUMS
0 voters
Difficulty (Do not vote 11 for fun.)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
0 voters
13 Likes

Not to be mean but couldn’t you just edit the first one, adding the photos and better description? if I’m wrong about this, sorry :slight_smile:
Edit:

Ok I didn’t know that, then I guess (from me) your fine :smile: .

1 Like

It’s too old, after a certain point, you’re not allowed to edit it anymore.

You could’ve just asked one of the TL4s to make it a wiki. In fact, you still can. Would you prefer that and we just unlist this guide?

1 Like

Sure, I guess we could do that. Are you able to disable the wiki when I’ve finished moving it?

Yes, I am! I’ll make it a wiki over there, and once you’re done with all of that then I can unwiki that and unlist this.

1 Like

I’m glad to see this guide being remade and getting images again, since its great for a lot of games and can help make entirely new systems with just slight edits. (I’m pretty sure I even made a guide that was a kind of addon to this guide, speaking of which I might edit it slightly just to work with this new version, if there are any big differences of course).

1 Like

Bumping this since it got buried in the raid.

If you have any other guides of mine you would like me to fix, let me know!

1 Like

This one would be a good one to fix :D

2 Likes

:skull: :skull: :skull:

Too many words I guess

1 Like

Hey there!

Would you like to know how you can add player names to this system? Here’s how!

All you need is 5 extra “Property” devices and 50 memory!

Property settings

Property Name: My name
Property Type: Text
Default Value: �������������������� <<<Be sure to copy-paste this!
Property Scope: player
When property value changes, transmit on:
Broadcast value change on game start: No

Property Name: Tracking ID
Property Type: Text
Default Value:
Property Scope: player
When property value changes, transmit on:
Broadcast value change on game start: No

Property Name: Tracking name
Property Type: Text
Default Value:
Property Scope: player
When property value changes, transmit on:
Broadcast value change on game start: No

Property Name: Closest ID
Property Type: Text
Default Value:
Property Scope: player
When property value changes, transmit on:
Broadcast value change on game start: No


Property Name: Closest Name
Property Type: Text
Default Value:
Property Scope: player
When property value changes, transmit on:
Broadcast value change on game start: No


Updating the code

Go to the block in the first “Item Granter” device.

Edit an existing block: When receiving on channel: Update all player data

// New if statement
if in text (Get Property (My name)) find (first) occurrence of text (Triggering Player's Name) = 0
do:
> Set Property (My name) Value: create text with (Triggering Player's Name) (in text (Get Property (My name) get substring from (letter #) (length of (Triggering Player's Name) + 1) to (last letter)
// Add my name to the variable after ID
Set variable (My data) to: create text with (Triggering Player's ID) (,) (Get Property (My name) (,) (Get Property (My x) + 100) (,) (Get Property (My y) + 100) (,)
Set variable (All player data) to: Get Property (All player data)
Set variable (Substring index) to: in text (variable (All player data)) find (first) occurrence of text (Triggering Player's ID)
if variable (Substring index) = 0
do: 
> Set Property (All player data) Value: create text with (variable (All player data)) (variable (My data))
> Broadcast Message On Channel: Check players
else:
> // replace + 33 with + 54 since that is now the length.
> Set Property (All player data) Value: create text with (in text (variable (All player data)) get substring from (first letter) to (letter #) (variable (Substring index) - 1)) (My data) (in text (variable (All player data)) get substring from (letter #) (variable (Substring index) + 54) to (last letter))

These changes ensure that our name is 20 characters long and accounts for the change in the string length by adding our name to the string. We keep the Player ID so that if there are 2 people with the same name, we can still tell them apart.

Now edit the “Check players” block in the second “Item Granter” device.

Edit an existing block: When receiving on channel: Check players

Set Property (Players) Value: Get Property (Players) - 1
if Get Property (Players) ≤ 0
do:
> Set Property (Players) Value: (length of (Get Property (All player data)) Ă· 54 + 1)
> Broadcast Message On Channel: Show closest player
else:
> Set variable (Substring index) to: Get Property (Players) Ă— 54 + 1
> // Adding some variables and using the new properties and changing numbers to match the new length of 54.
> Set Property (Tracking ID) Value: in text (Get Property (All player data)) get substring from (letter #) (variable (Substring index) - 53) to (letter #) (variable (Substring index) - 30)
> Set variable (Name) to: in text (Get Property (All player data)) get substring from (letter #) (variable (Substring index) - 28) to (letter #) (variable (Substring index) - 9)
> // Finding the separator so that we don't get any ugly question marks in our name.
> Set variable (Find separator) to: in text (variable (Name)) find (first) occurrence of text (ďż˝)
> // This is to prevent the system from glitching if a player with a 20-character-long name joins.
> if variable (Find separator) to: = -1
> do:
> > Set variable (Find separator) to: 20
> Set Property (Tracking name) Value: in text (variable (Name)) get substring from (first letter) to (letter #) (variable (Find separator))
> if Get Property (Tracking ID) ≠ Triggering Player's ID
> do:
> > Broadcast Message On Channel: Calculate distance
> else:
> > Broadcast Message On Channel: Check Players

What this does is allows us to set up so we can display the name, as well as get the ID so you can make your own custom systems! We are also accounting for the change in the string’s length.

Next, we’ll update the second block in the second “Item Granter” device. We won’t have to make many changes here.

Edit an existing block: When receiving on channel: Calculate distance

// Change substring index to 54 since that's how long our strings are now.
Set variable (Substring index) to: Get Property (Players) Ă— 54
Set variable (X) to: in text (Get Property (All player data)) get substring from (letter #) (Substring index - 7) to (letter #) (Substring index - 5)
Set variable (X) to: variable (X) - 100
Set variable (Y) to: in text (Get Property (All player data)) get substring from (letter #) (Substring index - 3) to (letter #) (Substring index - 1)
Set variable (Y) to: variable (Y) - 100
Set variable (Distance) to: square root ((Get Property (My x) - variable (X))^2 + (Get Property (My y) - variable (Y))^2)
if variable (Distance) < Get Property (Closest Distance
do:
> Set Property (Closest distance) Value: variable (Distance)
> Set Property (Closest X) Value: variable (X)
> Set Property (Closest Y) Value: variable (Y)
> // Now we'll set our Closest ID and Closest name properties so that we can display them later.
> Set Property (Closest ID) Value: Get Property (Tracking ID)
Broadcast Message On Channel: Check players

These changes will allow us to display the closest player’s name and ID. Whenever designing specific systems, you should keep in mind that players can have the same name in the game. You should always use their ID.

Now let’s display the player’s name on the second “Game Overlay” device.

Edit an existing block: When receiving on channel: Show closest player

// If the ID is blank, there are no other players online. Use an empty text block.
if Get Property (Closest ID) = ()
do: 
> Set Text: There are currently no other players in this game.
else:
> Set Text: create text with (The closest player to you is ) (Get Property (Closest name)) (. Their ID is ) (Get Property (Closest ID)) (. Their position is ) (Get Property (Closest X)) (, ) (Get Property (Closest Y)) ( which is ) (Get Property (Closest distance)) ( meters away.)
Set Property (Closest distance) Value: 9999
// Reset the Closest ID property to blank.
Set Property (Closest ID) Value: ()
Broadcast Message On Channel: Check players prep

This will now show us if anyone is online, and the closest player’s name and ID.


I hope you enjoyed the extension to this guide! Keep those creative juices flowing!

3 Likes

ONE
BIG
BUMP

another… normal BUMP!

2 Likes

Bump

2 Likes