Skip to content
RustPluginGenerator

OnBigWheelLoss

OnBigWheelLoss is called for each bet slot on a big wheel terminal when the spin did not win, right before the game removes the betted item. Returning a non-null value cancels that removal, so the bet is not lost.

Signature
object OnBigWheelLoss(BigWheelGame bigWheelGame, Item slot2, BigWheelBettingTerminal terminal)

Parameters

Hook parameters
ParameterTypeDescription
bigWheelGameBigWheelGameThe BigWheelGame entity that is paying out, i.e. the wheel the player spun. Use it for its transform position or net ID if you need to identify the specific machine.
slot2ItemThe Item sitting in the terminal's inventory slot being resolved. When the player loses, this is the scrap item that is about to be removed from the betting terminal.
terminalBigWheelBettingTerminalThe BigWheelBettingTerminal that the bet was placed on. Use terminal.lastPlayer to find the betting player.

Return value

Return null (or nothing) to let the game proceed: the item is removed from the terminal, an analytics event is recorded and the loss is confirmed. Returning any non-null value (for example true) stops the original code for that slot, so the item stays in the terminal and the bet is effectively not collected.

How it works

The hook fires inside BigWheelGame.Payout, in the loop that iterates over the five slots of a BigWheelBettingTerminal inventory. For every slot that still holds an item after the winning slots have been handled, the game calls OnBigWheelLoss and, if the hook returns null, removes the item and marks the payout as processed. It therefore fires once per losing bet slot on a spin, not once per spin.

bigWheelGame is the wheel entity, slot2 is the item about to be taken (usually scrap), and terminal gives you terminal.lastPlayer for the bettor and the terminal's own inventory and position. All three are plain references, so you can read amounts, skins and owner IDs directly without any lookup.

The return value is what matters: returning anything non-null skips the item removal for that slot, which refunds the bet. Returning null keeps vanilla behaviour. The hook does not fire for winning slots, so a refund handler built here only touches losses.

Example plugin: Refund losses for a configured list of players

BigWheelLossRefund.cs
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Big Wheel Loss Refund", "RustPluginGenerator", "1.0.0")]
    [Description("Refunds big wheel bets for players listed in the config")]
    public class BigWheelLossRefund : RustPlugin
    {
        private const string PermRefund = "bigwheellossrefund.refund";

        private PluginConfig config;
        private readonly Dictionary<string, int> refundTotals = new Dictionary<string, int>();

        private class PluginConfig
        {
            [JsonProperty("Refunded player user IDs")]
            public List<string> RefundedUserIds = new List<string>();

            [JsonProperty("Announce refund on next tick")]
            public bool Announce = true;
        }

        protected override void LoadDefaultConfig() => config = new PluginConfig();

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<PluginConfig>();
                if (config == null) throw new Exception();
            }
            catch
            {
                PrintWarning("Configuration file is invalid, using defaults");
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void SaveConfig() => Config.WriteObject(config);

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["Refunded"] = "Your {0} x {1} bet was refunded.",
                ["NoPermission"] = "You do not have permission to use this command.",
                ["Total"] = "Refunded bets recorded: {0}"
            }, this);
        }

        private string Msg(string key, string userId = null, params object[] args) =>
            string.Format(lang.GetMessage(key, this, userId), args);

        private void Init()
        {
            permission.RegisterPermission(PermRefund, this);
        }

        private object OnBigWheelLoss(BigWheelGame bigWheelGame, Item betItem, BigWheelBettingTerminal terminal)
        {
            if (terminal == null || betItem == null || betItem.info == null) return null;

            BasePlayer player = terminal.lastPlayer;
            if (player == null || !player.IsConnected) return null;

            string userId = player.UserIDString;
            if (!config.RefundedUserIds.Contains(userId) && !permission.UserHasPermission(userId, PermRefund))
                return null;

            int amount = betItem.amount;
            string shortname = betItem.info.shortname;

            NextTick(() =>
            {
                int total;
                refundTotals.TryGetValue(userId, out total);
                refundTotals[userId] = total + amount;

                if (config.Announce)
                    player.ChatMessage(Msg("Refunded", userId, amount, shortname));
            });

            return true;
        }

        [ChatCommand("wheelrefunds")]
        private void CmdWheelRefunds(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;
            if (!permission.UserHasPermission(player.UserIDString, PermRefund) && !player.IsAdmin)
            {
                player.ChatMessage(Msg("NoPermission", player.UserIDString));
                return;
            }

            int total;
            refundTotals.TryGetValue(player.UserIDString, out total);
            player.ChatMessage(Msg("Total", player.UserIDString, total));
        }

        private void Unload()
        {
            refundTotals.Clear();
        }
    }
}

The plugin keeps a list of refunded user IDs in its config. In OnBigWheelLoss it null-checks the terminal and item, resolves the bettor through terminal.lastPlayer, and checks the configured list. If the player is listed, the hook returns true, which makes the game skip slot2.Remove() and leave the scrap in the terminal. Every refund is counted so admins can check totals with a chat command, which is permission-gated. The hook itself does no logging to keep spin traffic quiet.

Common use cases

  • VIP loss insurance

    Refund losses for players with a permission or a per-player flag stored in config, giving donors a soft gambling perk without changing the wheel payouts.

  • Gambling event tracking

    Count losses per player from the item amount and the terminal's last player, then hand the totals to a rewards or stats plugin on a timer.

  • Scrap economy tuning

    Return a non-null value selectively (for example only when the bet item's skin matches a token) to turn the wheel into a custom game mode.

Pitfalls

  • Fires per losing slot

    A single spin can trigger the hook up to five times because the game loops over all terminal slots. Do not treat one call as one spin when adding up totals.

  • Returning true leaves items in the terminal

    Cancelling the removal does not move the item anywhere; it stays in the betting terminal inventory. If you want to move it, do it yourself on the next tick after returning null.

  • lastPlayer may be null

    On terminals touched by disconnected or edge-case players terminal.lastPlayer can be null, so always null-check before reading UserIDString.

Build a plugin with OnBigWheelLoss

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: VIP loss insurance using the OnBigWheelLoss hook, with a config file and a permission
Generate this plugin

Edit the prompt on the next screen. 2 free plugins a month, no card.

Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.

Build a plugin with OnBigWheelLoss

Generate