[Standalone/Any Framework] CritteR's Impromptu Races - Quick races, anywhere

Heyo :wave:

CritteR’s Impromptu Races is a simple 1 vs. 1 racing resource that aims to provide an easy environment for players to challenge their driving skills! Simply add a waypoint where you want to end the race, challenge a player (with money or not), and start racing!

BUY IT FROM TEBEX!

Installing the resource:

  1. Add the resource in your resources folder.
  2. (Optional) Connect the resource with your framework of choice in the public/server_connection.lua and public/client_connection.lua files.
  3. (Optional) Modify the UI elements in the public/client_pracing_public_ui.lua and public/client_pracing_public_menu.lua files.
  4. (Optional) Change the resource config and localization strings in the public/sh_utils.lua file.

Usage:

  • Go next to a player and use the command /race [source / player name] (entry bet) by default (command name is editable in sh_utils.lua)
  • The player that you challenged will receive your request and they will be allowed to see the entry bet and the finish line.
  • The player that you challenged has to drive next to you in order to accept the challenge.
  • The challenge request will be canceled if the user doesn’t answer in 30 seconds. A player cannot start more than one race at one time.
  • After the challenged accepts your request, the race countdown will start.
  • First to reach the finish line wins and receives the other user’s entry bet money (if bets are allowed).

Hooks:

Below you can see the hooks that you can use to monitor the races outside of the resource. Those events are server-side only.

AddEventHandler('crit_ImpromptuRaces:RaceInitiated', function(data)
    --Event triggered when a player challenges another player to a race.
    --[[
        data = {
            type = "raceInitiated",
            raceid = id of the race. starts at 1 every time the resource starts.
            endPoint = vector3, coordonates of the finish line
            startPoint = vector3, coordonates of the start line
            initiator = source of the player that started the race
            opponent = source of the player that responded to the race
            prize = prize of the race. this is the combined bet money for the two players.
            timestamp = os.time() from when the race was initiated.
        }
    ]]
end)
AddEventHandler('crit_ImpromptuRaces:RaceRejected', function(data)
    --Event triggered when a player rejects a race challenge.
    --[[
        data = {
            type = "raceRejected",
            raceid = id of the race. starts at 1 every time the resource starts.
            endPoint = vector3, coordonates of the finish line
            startPoint = vector3, coordonates of the start line
            initiator = source of the player that started the race
            opponent = source of the player that responded to the race
            prize = prize of the race. this is the combined bet money for the two players.
            timestamp = os.time() from when the race was rejected.
        }
    ]]
end)
AddEventHandler('crit_ImpromptuRaces:RaceAborted', function(data)
    --Event triggered when a player aborts a race challenge. Either by canceling it, dying or disconnecting.
    --[[
        data = {
            type = "raceAborted",
            raceid = id of the race. starts at 1 every time the resource starts.
            endPoint = vector3, coordonates of the finish line
            startPoint = vector3, coordonates of the start line
            initiator = source of the player that started the race
            opponent = source of the player that responded to the race
            prize = prize of the race. this is the combined bet money for the two players.
            timestamp = os.time() from when the race was aborted.
        }
    ]]
end)
AddEventHandler('crit_ImpromptuRaces:RaceStarted', function(data)
    --Event triggered when a player accepts a race challenge, and starts the race.
    --[[
        data = {
            type = "raceStarted",
            raceid = id of the race. starts at 1 every time the resource starts.
            endPoint = vector3, coordonates of the finish line
            startPoint = vector3, coordonates of the start line
            initiator = source of the player that started the race
            opponent = source of the player that responded to the race
            prize = prize of the race. this is the combined bet money for the two players.
            timestamp = os.time() from when the race was started. (after the countdown)
        }
    ]]
end)
AddEventHandler('crit_ImpromptuRaces:RaceFinished', function(data)
    --Event triggered when a race is finished. Meaning that someone won.
    --[[
        data = {
            type = "raceFinish",
            raceid = id of the race. starts at 1 every time the resource starts.
            endPoint = vector3, coordonates of the finish line
            startPoint = vector3, coordonates of the start line
            initiator = source of the player that started the race
            opponent = source of the player that responded to the race
            prize = prize of the race. this is the combined bet money for the two players.
            timestamp = os.time() from when the race finished.
            raceTimeMs = how much time it took for the winner to ... win. In miliseconds.
            raceTimeString = same as raceTimeMs, but in a more readable format. h m s .ms
        }
    ]]
end)

What can I modify?

All of the UI, all text strings, the command name, and all the functions needed for you to connect this to your framework. Other parts of the code can be opened on request. The resource also has a couple of hooks that allows you to see every race that is initiated, accepted, rejected, aborted and finished.

What can’t I modify?

Server-side race logic, blips and checkpoints, and the client-side race logic.

Support:

Feel free to reach out to me on the forums, or through Tebex if you need any help, or have any issues with the script. I will gladly explain to you what to change in order to connect this resource to your server, but I cannot tell you how exactly to connect it to your framework, as I don’t use them.

BUY IT FROM TEBEX!

Code is accessible UI and hooks yes, the race logic is escrowed.
Subscription-based No
Lines (approximately) ~500 lines locked / ~500 unlocked
Requirements A framework / money resource if you want to use the entry fee feature
Support Yes




4 Likes

Oh sweet. This is super simple and well documented, I think I’ve seen it in action on a server I played on as well. Thanks mate, I’ll definitely come back to grab this in the future!

1 Like

Thanks @KazumoR !

I did a small update based on player feedback:

v1.0.4

  • fix: Actually cancel a race when a player leaves the server (feature was disabled. oops.)
  • fix: Fully check server-side if a player actually finished the race, to prevent cases of players maliciously triggering the server event.
1 Like

Update notes:

v1.0.5

  • vendor: Updated warmenu to the last available version. (You can still rewrite the entire UI however you like).
  • feat: Disable self-challenging to a race (you can re-enable that in sh_utils.lua)
  • feat: Added locales error strings related to self-race.
  • fix: Other small optimizations.

For any questions or concerns related to the resource, feel free to reach out!

This sick blood! Looking forward to more scripts.

1 Like

I got this for my DriftV server and it’s awesome! Super easy to connect to my money script as well. looking forward for more awesome scripts. Thanks.

1 Like

Update v1.0.6


fix: More accurate distance check to make sure players can still finish their race, even when GTA fails to calculate the Z-coord of the blip.

fix: Moved the command from the escrowed scripts to public/client_connection.lua


Files modified in the last update:

  • all private folder
  • public/client_connection.lua
  • fxmanifest.lua

Update v1.0.7


fix: Minor code cleanup


Files modified in the last update:

  • all private folder
  • fxmanifest.lua