[VORP] Darts

:trophy: GoldSlush – Darts Script v1.0

:dart: Overview

GoldSlush’s Darts Script introduces fully interactive dart boards to the server, with both Practice Mode (for solo play) and Player vs Player Mode (with wagered matches). It’s built for clarity, immersion, and replayability—offering localized prompts, camera shake feedback, player invites, and real-time scoring.


:gear: Configurable Settings

Blip & Locations

  • Blip: Toggle on/off in Config.Blip.Status, with customizable Config.Blip.Name.
  • DartBoard Locations: Two placements in Saint-Denis; each defines world coords, heading, spawn/waiting locations.

Match Settings

Option Description
MinRounds, MaxRounds Controls min/max rounds per match
MinWager, MaxWager Wager bracket for Player vs Player
PracticeModeCost Fee to play solo in Practice Mode

Localized Text

All user-facing messages (prompts, alerts, notifications) are in Config.Lang. This includes play prompts, error messages, round labels, invite text, notifications when the match starts/ends, score displays, and more—making the script fully translation-ready.


:brain: Core Features & Flow

:rocket: Starting the Game

When near a dartboard, a Play Darts prompt appears. Players choose between:

  • Practice Mode: Pay a fee to throw 3 darts solo.
  • Match Mode: Pick opponent, wager, and round count.

The script checks board availability and funds, displaying localized errors if not possible.

:money_with_wings: Invitations & Match Setup

For match mode:

  • Invites are sent to a player with a 15s alert.
  • Opponent can /accept or /decline in chat.
  • If accepted, both players receive a localized update via vorp:NotifyLeft.
  • If declined or invalid, appropriate localized alerts are shown.

:dart: Throw Mechanics & Realism

Players take turns throwing three darts per round. During aiming:

  • Longer hold increases camera shake, adding realism and challenge.
  • Darts score based on closeness to bullseye— highest is 50, diminishing with distance.

Full scoring is tracked per player and updated server-side in real time.

:man_standing: Turn Management & Movement

  • On your turn, you walk to the board and your prompts activate.
  • Non-active players are frozen from throwing.
  • After each dart, turns switch, and positions update for next thrower appropriately.

:broom: Match Cleanup & Results

After all rounds:

  • Darts are removed
  • Scores are tallied
  • Players are notified with local messages:
    • Practice Mode: “Practice Complete”
    • PvP Mode: Winner is announced or “Draw” if tied
  • Boards reset for next match.

Disconnections mid-match trigger automatic cleanup.

:round_pushpin: 3D Score Displays

Each board displays scores above it using 3D world text:

  • “Home: X”
  • “Away: Y”

These update live during matches.


:wrench: Developer Details

  • Localization: Every text string is in Config.Lang, ready for translation or theme customization.
  • Modular Prompts: Functions like SetupStartPrompt() and SetupGamePrompt() initialize prompts using localized strings.
  • Clean Separation: Client-side handles visuals and prompts; server-side handles match logic and state.
  • Robust Edge Handling: Checks for board availability, funds, player status, disconnections, turn coordination.

:framed_picture: Dartboard Model (Sold Separately)

:wood: Classic Wild West Dartboard
This system uses a standalone dartboard model that must be added separately. Designed to match rustic saloons and frontier cabins, this high-fidelity dartboard features:

  • Authentic wear & tear with faded bullseye and dart hole details
  • Perfect for interactive gameplay or decoration props
  • Dynamic dart impact support included
  • Model Name: dartboard
  • Style: 1900s Western tavern aesthetic

:art: 3D Model and textures created by Emityk, owner of Green Pastures Roleplay.
For modeling inquiries or commissions, contact her on Discord: @emityk.


:hammer_and_wrench: Upcoming Add-ons

  • :dart: Custom Dart Models: Players will soon be able to choose from a variety of personalized dart models for flair and roleplay flavor.

Let me know if you’d like this chunk formatted specifically for a forum post (like Cfx) with headers and markdown or BBCode.

Dart Board Model: https://goldslush.tebex.io/package/6926283
Dart Script : https://goldslush.tebex.io/package/6926285
Video Preview: https://youtu.be/-5jNim_2vLQ

Config File

Config.Blip = {
    Status = true, -- Set to false to disable the blip
    Name = 'Dart Board'
}

Config.MatchSettings = {
    MinRounds = 2, -- Minimum number of rounds in a match (Keep Min 2 or higher)
    MaxRounds = 3, -- Maximum number of rounds in a match
    MinWager = 5, -- Minimum wager amount
    MaxWager = 500, -- Maximum wager amount
    PracticeModeCost = 150, -- Cost to play in practice mode
}

Config.DartLocations = {
    [1] = {
        -- Saint Denis
        Boardlocation = vector3(2773.1865234375, -1139.6630859375, 47.75836944580078),
        BoardHeading = 149.41860961914062,
        PlayerSettings = {
            StartLocation = vector3(2774.685302734375, -1136.9501953125, 47.47013092041015),
            StartHeading = 150.0025634765625,
            WalkToBoardAndCollectLocation = vector4(2773.1865234375, -1139.6630859375, 47.75836944580078, 150.0025634765625),
            WaitingLocation = vector3(2776.526611328125, -1137.79833984375, 47.47186660766601),
            WaitingHeading = 118.7397689819336,
        },
        IsInUse = false,
    },
    [2] = {
        -- Saint Denis
        Boardlocation = vector3(2781.622314453125, -1137.7939453125, 47.75836944580078),
        BoardHeading = -90.45780944824219,
        PlayerSettings = {
            StartLocation = vector3(2777.591796875, -1137.833984375, 47.47206497192383),
            StartHeading = -90.77513122558594,
            WalkToBoardAndCollectLocation = vector4(2781.622314453125, -1137.7939453125, 47.75836944580078, -90.77513122558594),
            WaitingLocation = vector3(2779.781005859375, -1135.5853271484375, 47.46868515014648),
            WaitingHeading = -155.07363891601562,
        },
        IsInUse = false,
    },
}

Config.Lang = {
    playPrompt = "Play Darts",
    checkingBoard = "Checking dartboard status...",
    boardInUse = "This board is currently in use!",
    matchCancelled = "Match selection cancelled.",
    invalidInput = "Invalid input. Please try again.",
    modeSelectTitle = "Darts",
    modeSelectLabel = "Choose Mode",
    modePractice = "Practice Mode",
    modeMatch = "Match vs Player",
    matchDialogTitle = "Darts Match",
    opponentLabel = "Opponent (PlayerID)",
    wagerLabel = "Wager (Cash)",
    roundsLabel = "Choose Rounds",
    noInviteAccept = "No pending dart invitations to accept.",
    noInviteDecline = "No pending dart invitations to decline.",
    inviteAccepted = "Dart match invitation accepted!",
    inviteDeclined = "Dart match invitation declined.",
    dartInviteTitle = "🎯 Dart Match Invitation",
    dartInviteMessage = "Player %s invited you!\nWager: %s | %s\nType 'accept' or 'decline' in chat",
    dartNoWager = "No Wager",
    dartOneRound = "1 Round",
    dartMultipleRounds = "%s Rounds",
    dartHomeLabel = "Home: %s",
    dartAwayLabel = "Away: %s",
    matchEnded = "The match has ended.",
    dartboardNotFound = "Dartboard not found nearby.",
    matchUpdateTitle = "🎯 Match Update",
    matchMissing = "Match data missing for this board.",
    boardConfigMissing = "Board config missing!",
    dartboardMissing = "Dartboard not found. Please check the setup.",
    dartsThrownLabel = "Darts Thrown: %s",
    releasePrompt = "Release Dart",
    aimPrompt = "Aim Dart & Release to Throw Dart",
    inviteDeclinedTitle = "Invite Declined",
    inviteDeclinedMessage = "Player %s declined your invite.",
    invalidPlayerTitle = "Invalid",
    invalidPlayerMessage = "Player is not online!",
    waitingAcceptTitle = "Darts",
    waitingAcceptMessage = "Waiting for the opponent to accept...",
    practiceStartMessage = "🎯 Practice Mode: Throw 3 darts!",
    matchStartMessage = "🎯 Match Started!",
    waitTurnMessage = "Wait for your turn!",
    practiceCompleteTitle = "Practice Complete",
    practiceCompleteMessage = "You've finished your practice round.",
    matchResultTitle = "Match Result",
    matchDrawMessage = "The match is a draw!",
    matchWinMessage = "%s wins with %s points!", -- %s = winner name, %s = score
    startPrompt = "Press [G] to start the match",
    insufficientFundsTitle = "Insufficient Funds",
    insufficientFundsMessage = "You do not have enough cash to play this match.",
}