Quick actions

cmd+k|ctrl+k

Navigation

Languages

Competition

Snippet info

Language

Lua

Visibility

public

Author

iwillnever

Created

2025-05-03T18:44:32.506984Z

Updated

2026-03-10T15:42:05.45722Z

print("Competition show!");

-- BFDI:R SB EDITION
-- CONSTANTS
local DEFAULT_TYPEWRITER_DELAY = 3

local CODENAME = "BFDI:R"
local VERSION = "v1"
--
local LSB = false
--
print(CODENAME.." "..VERSION)
--
local instN = Instance.new
local create = function(c, par)
    return function(t)
        t = t or {}
        local inst = instN(c)
        if inst:IsA("GuiObject") then
            inst.BackgroundColor3 = Color3.new(1,1,1)
        end
        if inst:IsA("TextLabel") or inst:IsA("TextBox") then
            inst.Font = "SourceSans"
        end
        for i, v in t do
            inst[i] = v
        end
        if par and not t.Parent then
            inst.Parent = par
        end
        return inst
    end
end
local clone = function(c, par)
    return function(t)
        t = t or {}
        local inst = c:Clone()
        for i, v in t do
            inst[i] = v
        end
        if par and not t.Parent then
            inst.Parent = par
        end
        return inst
    end
end
function safeDestroy(i)
    if i == nil then
        return
    end
    pcall(game.Destroy,i)
end

function lerp(a, b, t)
    return a + (b - a) * t
end

function loadurlstring(rawurl)
    local HttpService = game:GetService("HttpService")
    return loadstring(HttpService:GetAsync(rawurl))
end

local players = game:GetService'Players'
local HttpService = game:GetService'HttpService'

local inGame = {}
local inShow = {}
local plrDatas = {}

-- INSTANCES
local RIG = players:CreateHumanoidModelFromDescription(create("HumanoidDescription", script){
    TorsoColor = BrickColor.Blue().Color,
    HeadColor = BrickColor.White().Color,
    LeftArmColor = BrickColor.White().Color,
    RightArmColor = BrickColor.White().Color,
    LeftLegColor = BrickColor.White().Color,
    RightLegColor = BrickColor.White().Color,
}, "R6")
-- LISTS
local MakeLobby = loadstring(HttpService:GetAsync"https://glot.io/snippets/h70e617rl4/raw/lobby.lua")()
local ChallengeList = loadstring(HttpService:GetAsync("https://glot.io/snippets/h8psgwrkrd/raw/maps.lua"))()
local Objectifier = loadstring(HttpService:GetAsync("https://glot.io/snippets/h8ozoc3omc/raw/standalone.lua"))()
-- LIBRARIES
-- SIGNAL LIBRARY
local Signal = loadurlstring("https://gist.githubusercontent.com/stravant/b75a322e0919d60dde8a0316d1f09d2f/raw/f6a8900676185457211ec25d22d681c20ee792cb/GoodSignal.lua")()
-- MODULES
-- FAKEPLAYER
local FPlayers = {FakePlayerCount = 0, _FPlrs = {}}
do

local Players = game:GetService("Players")
--- FPlayer Class ---
local _FPlayer = {}
function _FPlayer.__newindex(t, i, v)
    if i == "Character" then
        local cons = rawget(t, "_cons")
        if cons.charNet then
            cons.charNet:Disconnect()
        end
        safeDestroy(t.Character)
        rawset(t, i, v)
        if not v then
            return
        end
        cons.charNet = v.AncestryChanged:Connect(function()
            for i, v in v:GetChildren() do
                if v:IsA("BasePart") and v:CanSetNetworkOwnership() then
                    v:SetNetworkOwner(nil)
                end
            end
        end)
        t.CharacterAdded:Fire(v)
        return
    end
    rawset(t, i, v)
end
---------------------
function FPlayers.new()
    FPlayers.FakePlayerCount = FPlayers.FakePlayerCount + 1
    local data = {
        Backpack = create("Folder")(),
        PlayerGui = create("Folder")(),
        Character = nil,
        CharacterAdded = Signal.new(),
        UserId = -FPlayers.FakePlayerCount,
        Name = "FakePlayer"..FPlayers.FakePlayerCount,
        DisplayName = "FakePlayer"..FPlayers.FakePlayerCount,
        ClassName = "Player",
        _cons = {}
    }
    local c
    data.CharacterAdded:Connect(function(v)
        if c then
            c:Destroy()
        end
        c = v
    end)
    function data:IsA(class)
        return class == self.ClassName
    end
    function data:LoadCharacter()
        if c then
            c:Destroy()
        end
        self.Character = RIG:Clone()
        self.Character.Parent = script
        c = self.Character
    end
    data = setmetatable(data, _FPlayer)
    FPlayers._FPlrs[-data.UserId] = data
    data:LoadCharacter()
    return data
end
function FPlayers:IsFake(plr)
    return self._FPlrs[-plr.UserId] ~= nil
end
function FPlayers:GetPlayerFromCharacter(char)
    for i, v in self._FPlrs do
        if v.Character == char then
            return v
        end
    end
    return Players:GetPlayerFromCharacter(char)
end

end
-- PLAYER DATA MODULE
local plrData = {
    ufeList = {}
}
function plrData.initData(plr)
    local data = {
        player = plr,
        team = "",
        inGame = false,
        cons = {},
        
        voting = false,
        
        VotingStarted = Signal.new(),
        VotingStopped = Signal.new(),
    }
    data.VotingStarted:Connect(function()
        print("voting engage ")
        data.voting = true
    end)
    plrDatas[plr.UserId] = data
    return data
end
function plrData.unload(plr)
    local data = plrData.getData(plr)
    for i, v in data.cons do
        v:Disconnect()
    end
    
end

function plrData.getData(plr)
    return plrDatas[plr.UserId]
end
plrData.get = plrData.getData
-- MUSIC MODULE
local music = {id = "", vol = 1, volMult = 1}
local musicData = {
    intermission = "rbxassetid://76235338866803",
    sweeper = "rbxassetid://1846476088",
    
    lobby1 = "rbxassetid://121281026041996",
    lobby2 = "",
    lobby3 = ""
}
function music:update(snd)
    local resetPos = false
    if snd.SoundId ~= self.id then
        resetPos = true
    end
    snd.SoundId = self.id
    snd.Volume = self.vol * self.volMult
    if resetPos then
        snd.TimePosition = 0
    end
end
function music:updateAll()
    for _, v in plrDatas do
        local gui = v.gui
        local mus = gui:FindFirstChild'Mus'
        if mus then
            self:update(mus)
        end
    end
end
function music:play(name)
    local data = musicData[name] or ""
    self.id = data
    self.volMult = 1
    self:updateAll()
end
function music:fadeout(length)
    length = length or 1
    local id = self.id
    local a = 0
    task.spawn(function()
    while a < length do
        a += task.wait()
        if id ~= self.id then
            break
        end
        self.volMult = lerp(self.volMult, 0, a/length)
        self:updateAll()
    end
    if id ~= self.id then
        return
    end
    self:play("")
    end)
end
-- TIMER MODULE
local timer = {
    text = "Hi",
    visible = false,
    renders = {}
}
function timer:render(box)
    local data = box
    data.Visible = self.visible
    data.PlaceholderText = tostring(self.text)
end
function timer:connect(box)
    local data = box
    table.insert(self.renders, data)
    self:render(data)
end

function timer:renderAll()
    for i, v in self.renders do
        if not v:IsDescendantOf(game) then
            table.remove(self.renders, i)
        else
            self:render(v)
        end
    end
end
function timer:set(text)
    self.text = text
    self:renderAll()
end
function timer:setVisible(b)
    self.visible = b
    self:renderAll()
end
-- HINT MODULE
local hint = {
    text = "Hi",
    maxVis = -1,
    visStart = 0,
    charName = nil,
    tC = nil,
    renders = {},
    
    
}

function hint:render(box)
    local data = box
    local tbox = data[1]
    local charbox = data[2]
    local charN = data[3]
    charN.PlaceholderText = tostring(self.charName)
    tbox.MaxVisibleGraphemes = self.maxVis + self.visStart
    tbox.PlaceholderText = self.text
    tbox.Visible = self.charName == nil and self.text ~= ""
    charbox.MaxVisibleGraphemes = self.maxVis + self.visStart
    charbox.PlaceholderText = self.text
    charbox.Visible = self.charName ~= nil and self.text ~= ""
end
function hint:connect(hTBox, charBox, charNBox)
    local data = {hTBox, charBox, charNBox}
    table.insert(self.renders, data)
    self:render(data)
end

function hint:renderAll()
    for i, v in self.renders do
        if not v[1]:IsDescendantOf(game) then
            table.remove(self.renders, i)
        else
            self:render(v)
        end
    end
end
function hint:set(text, doRender)
    self.text = text
    if doRender then
        self:renderAll()
    end
end
function hint:hide()
    self.text = ""
    self:renderAll()
end
function hint:typewriter(text, fps, del, charname, hide, add)
    if text == "" then
        self:set(text, true)
    end
    fps = fps or 30
    local tLength = #text
    local tTime = tLength / fps
    self.visStart = add and #self.text or 0
    if add then
        self:set(self.text..text)
    else
        self:set(text)
    end
    self.charName = charname
    if self.tC and coroutine.status(self.tC) ~= 'dead' then
        coroutine.close(self.tC)
    end
    self.tC = task.spawn(function()
        local a = 0
        while a < tTime do
            a += task.wait()
            self.maxVis = math.floor((a / tTime) * tLength)
            self:renderAll()
        end
        self.maxVis = -1
        if hide then
            local delayTime = del ~= true and del or DEFAULT_TYPEWRITER_DELAY
            task.wait(tTime + delayTime)
            self:hide()
        end
    end)
    if del and not hide then
        del = del == true and DEFAULT_TYPEWRITER_DELAY or del
        task.wait(tTime + del)
    end
    return tTime
end
-- VOTING
local voting = {
    immune = {},
    votes = {},
    voters = {},
    ufe = {},
    voteList = {},
    names = {},
    tiebreaker = false,
    voted = false
}
function voting:upForEliminate(plr)
    local icon
    if FPlayers:IsFake(plr) then
        icon = "rbxassetid://8508980527"
    else
        icon = ("rbxthumb://asset=AvatarHeadShot&id=&s&w=352&h=352"):format(plr.UserId)
    end
    local display = plr.DisplayName
    local char = plr.Character
    local hum
    if char:FindFirstChildOfClass'Humanoid' then
        hum = char:FindFirstChildOfClass'Humanoid'
    end
    if hum then
        display = hum.DisplayName
    end
    table.insert(self.ufe, {plr, icon, display, plr.UserId, char})
end
function voting:begin(plrs)
    self.voted = false
    for i, v in plrs do
        local display = v.DisplayName
        local char = v.Character
        local hum
        if char and char:FindFirstChildOfClass'Humanoid' then
            hum = char:FindFirstChildOfClass'Humanoid'
        end
        if hum then
            display = hum.DisplayName
        end
        self.names[v.UserId] = display
        
        local plrData = plrData.get(v)
        table.insert(self.voters, v)
        if not self:hasImmunity(v) then
            self:upForEliminate(v)
        end
    end
    for i, v in self.voters do
        local data = plrData.get(v)
        data.VotingStarted:Fire(self.ufe)
    end
end
function voting:stop()
    table.clear(plrData.ufeList)
    for i, v in self.voters do
        local data = plrData.get(v)
        data.VotingStopped:Fire()
    end
end
function voting:hasImmunity(plr)
    return table.find(self.immune, plr) ~= nil
end
function voting:immunity(plr)
    table.insert(self.immune, plr)
end
function voting:vote(userId, voter)
    local t = self.votes[userId]
    if not t then
        self.votes[userId] = {}
        t = self.votes[userId]
    end
    table.insert(t, voter.UserId)
end
function voting:getList()
    local list = {}
    local voteds = {}
    Random.new():Shuffle(self.ufe)
    for i, v in self.ufe do
        local plr = v[1]
        local char = v[5]
        local display = v[3]
        local userId = v[4]
        local votes = 0
        if self.votes[userId] then
            for i, v in self.votes[userId] do
                if table.find(voteds, v) then
                    continue
                end
                table.insert(voteds, v)
                votes += 1
            end
        end
        
        table.insert(list, {
            votes,
            plr,
            display,
            char
        })
    end
    self.voteList = list
    self:sort()
    
    self.tiebreaker = false
    
    local highest
    for i, v in self.voteList do
        if not highest or highest[1] < v[1] then
            highest = v
        end
    end
    for i, v in self.voteList do
        if highest ~= v and highest and highest[1] == v[1] then
            self.tiebreaker = true
        end
    end
    for i, v in self.voteList do
        if v == highest and not self.tiebreaker then
            v[5] = true
        end
    end
    return list
end
function voting:sort()
    table.sort(self.voteList, function(a, b)
        return a[1] < b[1]
    end)
end
function voting:reset()
    table.clear(self.names)
    table.clear(self.immune)
    table.clear(self.votes)
    table.clear(self.voteList)
    table.clear(self.voters)
end
-- GUI MODULE
local gui = {}
local guiTemp = create("ScreenGui"){
    Parent = script,
    IgnoreGuiInset = true,
    ResetOnSpawn = false,
    DisplayOrder = -4
}
create"Sound"{
    Name = "Mus",
    Looped = true,
    Playing = true,
    Volume = 1,
    Parent = guiTemp
}
do
    local hint = create"TextBox"{
        Text = "",
        Interactable = false,
        TextScaled = true,
        PlaceholderText = "1234567890 hi",
        PlaceholderColor3 = Color3.new(),
        Size = UDim2.new(1,0,0.1,0),
        Name = "Hint",
        Parent = guiTemp
    }
    local timerhint = create"TextBox"{
        Text = "",
        Interactable = false,
        TextScaled = true,
        PlaceholderText = "1234567890 hi",
        PlaceholderColor3 = Color3.new(),
        Size = UDim2.new(0.25,0,0.1,0),
        AnchorPoint = Vector2.new(0.5, 0),
        Position = UDim2.new(0.5, 0, 0.05, 0),
        Name = "Timer",
        Parent = guiTemp
    }
    local charhint = create"TextBox"{
        Text = "",
        Interactable = false,
        TextScaled = true,
        PlaceholderText = "1234567890 hi",
        PlaceholderColor3 = Color3.new(),
        Size = UDim2.new(0.6,0,0.085,0),
        AnchorPoint = Vector2.xAxis/2 + Vector2.yAxis,
        Position = UDim2.new(0.5,0,0.775,0),
        Name = "HintChar",
        Parent = guiTemp,
        Visible = false
    }
    create"TextBox"{
        Text = "",
        Interactable = false,
        TextScaled = true,
        PlaceholderText = "Announcer",
        PlaceholderColor3 = Color3.new(),
        Size = UDim2.new(0.2,0,0.45,0),
        AnchorPoint = Vector2.yAxis,
        Position = UDim2.new(0,0,0,0),
        Name = "Char",
        Parent = charhint
    }
    
    -- Voting
    local voting = create("Frame", guiTemp){
        Name = "Voting",
        Size = UDim2.new(0.5,0,0.6,0),
        Position = UDim2.new(0.5,0,0.5,0),
        AnchorPoint = Vector2.one/2,
        Visible = false
    }
    local button = create("TextButton", voting){
        Name = "Button",
        Size = UDim2.new(1,0,0.25,0),
        BackgroundTransparency = 1,
        TextTransparency = 1
    }
    local list = create("ScrollingFrame", voting){
        ScrollingDirection = "Y",
        CanvasSize = UDim2.new(1,0,2,0),
        Size = UDim2.new(1,0,1,0),
        AutomaticCanvasSize = "Y",
        Name = "List"
    }
    create("ImageLabel", button){
        Size = UDim2.new(0.25,0,1,0),
        Name = "Icon",
        Interactable = false
    }
    create("TextBox", button){
        AnchorPoint = Vector2.new(1,0),
        Size = UDim2.new(0.75,0,1,0),
        Position = UDim2.new(1,0,0,0),
        Name = "Display",
        Text = "",
        PlaceholderColor3 = Color3.new(),
        TextScaled = true,
        Interactable = false,
    }
    create("UIListLayout", list){
        FillDirection = "Vertical"
    }
end
function gui:load(plrData)
    local player = plrData.player
    local gui = guiTemp:Clone()
    timer:connect(gui.Timer)
    hint:connect(gui.Hint, gui.HintChar, gui.HintChar.Char)
    music:update(gui.Mus)
    plrData.gui = gui
    gui.Parent = player.PlayerGui
    
    local voteFrame = gui.Voting
    local voteTemp = voteFrame.Button
    voteTemp.Visible = false
    
    local buttons = {}
    
    local function beginVoting()
        plrData.voting = true
        voteFrame.Visible = true
        print(voteFrame.Visible)
        for i, v in buttons do
            safeDestroy(v)
        end
        for i, v in voting.ufe do
            local button = voteTemp:Clone()
            button.Icon.Image = v[2]
            button.Visible = true
            button.Display.PlaceholderText = v[3]
            button.Parent = voteFrame.List
            button.MouseButton1Click:Connect(function()
                voting:vote(v[4], player)
                plrData.voting = false
                voteFrame.Visible = false
            end)
        end
    end
    
    if plrData.voting then
        beginVoting()
    end
    
    plrData.cons.votingUI = plrData.VotingStarted:Connect(beginVoting)
    plrData.cons.votingStop = plrData.VotingStopped:Connect(function()
        voteFrame.Visible = false
        plrData.voting = false
    end)
    plrData.cons.gui = gui.AncestryChanged:Connect(function()
        plrData.cons.votingUI:Disconnect()
        plrData.cons.votingStop:Disconnect()
        plrData.cons.gui:Disconnect()
        safeDestroy(gui)
        self:load(plrData)
    end)
end
-- HOST MODEL
local host = {model = nil, name = "Announcer"}
function host:load(cf)
    if self.model then
        safeDestroy(self.model)
    end
    local model = create"Model"{}
    local part = create"Part"{
        Anchored = true,
        Size = Vector3.new(2,3,2),
        Name = "HumanoidRootPart",
        Parent = model
    }
    model.PrimaryPart = part
    create"Decal"{
        Parent = part,
        Texture = "rbxassetid://77626118113724"
    }
    self.model = model
    model:PivotTo(cf)
    model.Parent = script
    return model
end
-- MOVEMENT
local movement = {}
function movement:_getChar(plr)
    local char = plr and plr:IsA("Player") and plr.Character or plr
    if not char then
        return
    end
    return char, char:FindFirstChildOfClass'Humanoid'
end
function movement:_baseUpdate(humanoid, base, add, mult, disabled, prop)
    if disabled then
        humanoid[prop] = 0
        return
    end
    humanoid[prop] = (base + add) * mult
end
function movement:_createBase(humanoid, prop)
    for i, v in humanoid:GetChildren() do
        if v.Name:find(prop) then
            v:Destroy()
        end
    end
    local base = create("NumberValue", humanoid){
        Name = prop.."Base",
        Value = humanoid[prop]
    }
    local add = create("NumberValue", humanoid){
        Name = prop.."Add",
        Value = 0
    }
    local mult = create("NumberValue", humanoid){
        Name = prop.."Mult",
        Value = 1
    }
    local disabled = create("BoolValue", humanoid){
        Name = prop.."Disabled",
        Value = false
    }
    add.Changed:Connect(function(v)
        self:_baseUpdate(humanoid, base.Value, v, mult.Value, disabled.Value, prop)
    end)
    base.Changed:Connect(function(v)
        self:_baseUpdate(humanoid, v, add.Value, mult.Value, disabled.Value, prop)
    end)
    mult.Changed:Connect(function(v)
        self:_baseUpdate(humanoid, base.Value, add.Value, v, disabled.Value, prop)
    end)
    disabled.Changed:Connect(function(v)
        self:_baseUpdate(humanoid, base.Value, add.Value, mult.Value, v, prop)
    end)
end
function movement:initMove(plr)
    local char, humanoid = self:_getChar(plr)
    if not humanoid then
        return
    end
    self:_createBase(humanoid, "WalkSpeed")
    self:_createBase(humanoid, "JumpPower")
end
function movement:_setBase(plr, prop, type, value, operator)
    local char, humanoid = self:_getChar(plr)
    if not humanoid then
        return
    end
    if operator == "+" then
        humanoid[prop..type].Value += value
    elseif operator == "-" then
        humanoid[prop..type].Value -= value
    else
        humanoid[prop..type].Value = value
    end
end
function movement:setSpeed(plr, speed)
    movement:_setBase(plr, "WalkSpeed", "Base", speed, "=")
end
function movement:addSpeed(plr, speed)
    movement:_setBase(plr, "WalkSpeed", "Add", speed, "+")
end
function movement:multiplerSpeed(plr, speed)
    movement:_setBase(plr, "WalkSpeed", "Mult", speed, "+")
end
function movement:disableSpeed(plr, bool)
    movement:_setBase(plr, "WalkSpeed", "Disabled", bool, "=")
end

function movement:setJumpPower(plr, power)
    movement:_setBase(plr, "JumpPower", "Base", power, "=")
end
function movement:addJumpPower(plr, power)
    movement:_setBase(plr, "JumpPower", "Add", power, "+")
end
function movement:multiplerJumpPower(plr, power)
    movement:_setBase(plr, "JumpPower", "Mult", power, "+")
end
function movement:disableJumpPower(plr, bool)
    movement:_setBase(plr, "JumpPower", "Disabled", bool, "=")
end

function movement:toggle(plr, bool)
    self:disableSpeed(plr, not bool)
    self:disableJumpPower(plr, not bool)
end

function movement:moveTo(plr, cf)
    local char, humanoid = self:_getChar(plr)
    if not humanoid then
        return
    end
    char:PivotTo(cf)
end


-- GAME STATE 
local gameState = {
    hint = hint,
    host = host,
    timer = timer,
    movement = movement,
    music = music,
    voting = voting,
    
    contestPos = CFrame.new(6000,0,0),
    lobbyPos = CFrame.new(-6000,0,0),
    
    gameType = "ffa",
    ongoing = false
}
-- DIALOG
local dialog = {}
function dialog:say(who, text, delayTime, hideAfter, add)
    local charName = tostring(who)
    if who == host then
        charName = host.name
    elseif who:IsA("Player") then
        local name = who.DisplayName
        local hum = who.Character and who.Character:FindFirstChildOfClass("Humanoid") 
        if hum then
            name = hum.DisplayName
        end
        charName = name
    end
    hint:typewriter(text, 30, delayTime, who ~= nil and charName, hideAfter, add)
end
-- LOBBY
local lobby = MakeLobby(gameState.lobbyPos)
-- SHOW MODULE
local show = {
    contestants = {}
}
function show:start()
    host:load(lobby:GetPivot()*CFrame.new(0,4,0))
    for i, v in inGame do
        table.insert(self.contestants, v)
        task.spawn(function()
            Objectifier.objectify(v.Character, v)
            movement:initMove(v.Character)
            plrData.getData(v).refChar = v.Character:Clone()
        end)
    end
    hint:typewriter("")
    task.wait(1)
end
-- CHALLENGE LOADER
local startQuotes = {
    "Go!",
    "Begin."
}
local challenge = {current = nil, players = {}, characters = {}}
function challenge:loadChallenge(name)
    local chosen = ChallengeList[name]
    if not chosen then
        return
    end
    music:fadeout(2.5)
    task.wait(1)
    math.randomseed(tick())
    self.players = table.clone(show.contestants)
    table.clear(self.characters)
    for i, v in self.players do
        self.characters[v] = v.Character
    end
    chosen = chosen(self, gameState)
    self.current = chosen
    chosen.teleport()
    chosen.dialog(hint, gameState)
    hint:set("",true)
    for i = 3, 1, -1 do
        hint:set(hint.text..`{i}, `, true)
        task.wait(1)
    end
    hint:typewriter(startQuotes[math.random(#startQuotes)], nil, 3, gameState.host.name, true)
    chosen.start()
    local winners, extra
    while true do
        winners, extra = chosen.loop(task.wait())
        if winners then
            break
        end
    end
    chosen.ended(winners, extra)
    task.wait(5)
    for i, v in challenge.characters do
        movement:moveTo(v, lobby:GetPivot()*CFrame.new(0,4,0))
    end
end
-- STATES
local notVotedQuotes = {
    "Contestants, you should vote someone out",
    "Come on, guys... Vote someone out.",
    "I haven't received a vote..."
}
local states = {}
function states:_musicLobby()
    music:play("lobby"..math.random(1,1))
end
function states:preVote()
    self:_musicLobby()
    hint:hide()
    timer:setVisible(true)
    for i = 30, 0, -1 do
        timer:set(i, true)
        task.wait(1)
    end
    timer:setVisible(false)
end
function states:voting(players)
    local function eliminate()
    end
    music:fadeout(2.5)
    task.wait(1)
    local cas = lobby.CakeAtStake
    local stand = cas.Stand
    players = players or show.contestants
    local rotation = math.pi/(#players)
    local current = CFrame.identity
    local radius = stand.Size.X
    for i, v in players do
        movement:toggle(v, false)
        movement:moveTo(v, stand.CFrame * CFrame.new(0, 3, 0) * current * CFrame.new(0,0,radius))
        current *= CFrame.Angles(0, rotation, 0)
    end
    host:load(stand.CFrame*CFrame.new(0,4,0))
    task.wait(1)
    dialog:say(host, "Welcome to Cake at Stake.", true)
    dialog:say(host, "You will have to vote someone out.", true)
    dialog:say(host, "Let's vote", 2)
    voting:begin(show.contestants)
    local begin
    local notVoted = 0
    local function voteRandom()
        dialog:say(host, "Alright then.", 1.5)
        math.randomseed(os.time())
        dialog:say(host, "I choose... ", math.random(3,5))
        local eliminated = voting.ufe[math.random(#voting.ufe)]
        eliminated[5] = true
        local display = eliminated[3]
        dialog:say(host, display..".", 3)
        dialog:say(host, display..", you have been eliminated.")
    end
    function begin()
        timer:setVisible(true)
        for i = 30, 0, -1 do
            timer:set(i)
            task.wait(1)
        end
        timer:setVisible(false)
        voting:stop()
        if not voting.voted then
            notVoted += 1
            if not notVoted == 4 then
                notVoted = true
                return
            end
            dialog:say(host, notVotedQuotes[math.random(#notVotedQuotes)], 3, true)
            if notVoted == 2 then
                dialog:say(host, "If you don't vote someone out, I will eliminate one of you randomly.", 2, true)
            end
            begin()
            return
        end
        dialog:say(host, "Alright, I have gathered the votes", true)
    end
    begin()
    if not notVoted then
        voteRandom()
        eliminate()
        return
    end
    dialog:say(host, "If you get a prize, that means you're safe.", true)
    if #voting.immune > 0 then
        hint:set("",true)
        for i, v in voting.immune do
            local name = voting.names[v.UserId]
            hint:set(hint.text..name..", ", true)
            task.wait(0.25)
        end
        task.wait(0.25)
        dialog:say(host, "has immunity, so they get a prize.", 3)
        task.wait(0.5)
    end
    
    local list = voting:getList()
    -- Vote fakeout
    local safeLast = math.random(1,2) == 1
    for i, v in list do
        local votes = v[1]
        local display = v[3]
        local nextVotes = list[i+1]
        if safeLast and nextVotes and nextVotes[5] then
            dialog:say(host, ("%s..."):format(display),1.5)
            dialog:say(host, (" is safe with %s votes."):format(votes),2,false,true)
        elseif v[5] and safeLast then
            dialog:say(host, ("%s is eliminated with %s votes."):format(display, votes),3,true)
        elseif v[5] then
            dialog:say(host, ("%s..."):format(display),1.5)
            dialog:say(host, (" is eliminated with %s votes."):format(votes),3,true,true)
        else
            dialog:say(host, ("%s is safe with %s votes."):format(display, votes),2)
        end
    end
    if voting.tiebreaker then
        dialog:say(host, "Seems like we have a tiebreaker.")
    end
    eliminate()
end
-- JOIN MODULE
local enter = {}

function enter.join(plr)
    if table.find(inGame, plr) then
        return
    end
    table.insert(inGame, plr)
    local data = plrData.initData(plr)
    data.cons['refRespawn'] = plr.CharacterAdded:Connect(function(char)
        math.randomseed(os.time())
        if char:GetAttribute("R") or not data.refChar then
            return
        end
        char:Destroy()
        local clone = data.refChar:Clone()
        clone:SetAttribute("R", true)
        plr.Character = clone
        clone.Parent = workspace
        movement:initMove(clone)
        movement:moveTo(plr, lobby:GetPivot()*CFrame.new(0,4,0))
    end)
    gui:load(data)
    movement:moveTo(plr, lobby:GetPivot()*CFrame.new(0,4,0))
end
function enter.leave(plr)
    if not table.find(inGame, plr) then
        return
    end
    local index = table.find(inGame, plr)
    table.remove(inGame, index)
    plrData.unload(plr)
end

-- CMD LISTEN
local ready = false
function listen(plr)
    plr.Chatted:Connect(function(m)
        if m:sub(1,3) == "/e " then
            m = m:sub(4)
        end
        if m == "-join" then
            enter.join(plr)
        end
        if m == "-leave" then
            enter.leave(plr)
        end
        if plr ~= owner then return end
        if m == "-r" then
            ready = true
        end
        if m == "-t" then
            hint:typewriter"test sentence"
        end
        if m == "-tc" then
            hint:typewriter("hello hi hey",nil,false,plr.DisplayName)
        end
        if m == "-f" then
            enter.join(FPlayers.new())
        end
    end)
end
for i, v in players:GetPlayers() do
    listen(v)
end
players.PlayerAdded:Connect(listen)
-- GAME LOOP 

host:load(owner.Character.HumanoidRootPart.CFrame)
--enter.join(owner)

music:play"intermission"

hint:typewriter("Waiting for players..")

local dialog = true
if dialog then
create("Dialog", host.model.PrimaryPart){
    InitialPrompt = "Chat -join to join the competition (this is unfinished, game loop is not complete but do you want to test? do -join to test)"
}
end

--enter.join(FPlayers.new())

repeat task.wait() until ready
show:start()
challenge:loadChallenge("sweeper")
states:preVote()
states:voting()
INFO