Start typing to search packages!
round-manager
By @moxxum
Roblox
Mirroredround-manager
Match/round state machine — the RobloxWare backbone. States cycle
Lobby → Intermission → Active → Results → Lobby with configurable durations,
player ready/spectate handling, map/mode voting during Intermission, and a
StateChanged signal per transition. Pure server-side state: replicate to clients
through netkit however the game likes.
Server realm: RoundManager = "moxxum/round-manager@0.1.0" under
[server-dependencies].
API
local rm = RoundManager.new(config?)
rm.StateChanged:Connect(function(newState, oldState, data) end)
rm:Start() / rm:Stop() / rm:Destroy()
rm:GetState() -- "Lobby" | "Intermission" | "Active" | "Results"
rm:GetTimeRemaining() -- seconds left in a timed state, nil in Lobby
rm:GetParticipants() -- snapshot taken when the round went Active
rm:SetReady(player, bool) / rm:IsReady(player) -- used when RequireReady
rm:SetSpectating(player, bool) / rm:IsSpectating(player)
rm:VoteMap(player, name) / rm:VoteMode(player, name) -- Intermission only → boolean
rm:GetMapVotes() / rm:GetModeVotes() -- { [option] = count }
rm:EndRoundEarly(results?) -- Active → Results now
Config (defaults): IntermissionSeconds = 15, ActiveSeconds = 120,
ResultsSeconds = 10, MinPlayers = 2, RequireReady = false, Maps/Modes
(vote options; omit to skip voting).
StateChanged data: { Map, Mode, Duration, Participants, Results } (fields present
where they make sense; Results is whatever you passed to EndRoundEarly).
Rules: below MinPlayers the machine sits in Lobby (Intermission falls back to
Lobby if players leave). A round ends early when every participant leaves. Ready
flags clear on each return to Lobby; ties and no-vote rounds pick randomly.
Example
local rm = RoundManager.new({
IntermissionSeconds = GameConfig.Round.IntermissionSeconds,
ActiveSeconds = GameConfig.Round.ActiveSeconds,
MinPlayers = 2,
Maps = { "Desert", "City" },
})
rm.StateChanged:Connect(function(newState, _old, data)
Remotes.RoundState:FireAll(newState, data.Map, data.Duration)
if newState == "Active" then
for _, player in data.Participants do
spawnIntoArena(player, data.Map)
end
end
end)
rm:Start()
Test
rojo build test.project.json -o test.rbxl, open in Studio, Play Solo, expect
[round-manager-test] ALL PASS within ~15s (full cycle, voting, early end, spectate).
Package Details
Install command (Click to copy)
Version
0.1.0
License
MIT
Safe for commercial use
The package archive does not include its license text; the license is declared in its manifest metadata.
Automated license review — not legal advice.
