How to Build an Among Us-Style Game in FiveM (2026)
A deep technical walkthrough of implementing social deduction mechanics in FiveM — lobby management, role assignment, voting systems, NUI design, and why picking a tested resource saves hundreds of hours.
The Technical Challenge of Social Deduction in FiveM
Building an Among Us-style social deduction game inside FiveM is a genuinely complex engineering challenge. It requires server-client synchronization, state machine management, NUI development, framework integration, and careful security design. In this article, we break down every component you would need to build from scratch — and explain why using a tested, premium resource like Alone Imposter can save you hundreds of hours of development.
Architecture Overview
A social deduction minigame needs these core systems:
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ CLIENT │←──→│ SERVER │←──→│ CLIENT │
│ (Player A) │ │ (Authority) │ │ (Player B) │
└─────────────┘ └──────────────┘ └─────────────┘
│ │ │
NUI Layer Game State Machine NUI Layer(Vue 3) Role Assignment(Vue 3)
Input Events Vote Tallying Input Events
Display Timer Management Display
The server is always the authority. Clients send actions (create lobby, invite, vote), but the server validates everything and broadcasts state updates. This prevents cheating — a player cannot give themselves the "not impostor" role or manipulate vote counts.
Component 1: Lobby Management
The lobby system is the foundation. It handles player grouping before the game starts.
Server-Side Lobby State
-- Simplified lobby data structure
local lobbies = {}
lobbies[lobbyId] = {
host = serverId, -- The player who created the lobby
players = {}, -- List of server IDs in the lobby
state = 'waiting039;, -- waiting | playing | voting | result
impostor = nil, -- Assigned when game starts
votes = {}, -- Player votes during voting phase
settings = {
minPlayers = Config.MinPlayers,
maxPlayers = Config.MaxPlayers,
voteTime = Config.VoteTime,
}
}
Key Design Decisions
- One lobby per player: A player cannot be in multiple lobbies simultaneously
- Host authority: Only the host can start the game and invite players
- Server-side validation: Every action (join, leave, start) is validated server-side
Proximity-Based Invites
One of the most important design choices in Alone Imposter is proximity-based invitations. Instead of an ID-based system where you type a player number, the host sees nearby players automatically.
This works through:
- Server receives invite request from host
- Server gets host position via
GetEntityCoords - Server iterates all players, calculating distance
- Players within
Config.InviteRadiusare returned as invite candidates - Host selects from the list in the NUI
- Server sends invite to selected players
This approach is more immersive than ID-based invites and creates natural gathering points where players physically meet up to start games.
Component 2: Role Assignment
Role assignment is where security becomes critical. The impostor role must be determined server-side only and communicated securely.
Secure Approach
function assignRoles(lobbyId)
local lobby = lobbies[lobbyId]
local playerCount = #lobby.players
-- Random selection(server-side only)
local impostorIndex = math.random(1, playerCount)
lobby.impostor = lobby.players[impostorIndex]
-- Send individual role to each player
for _, playerId in ipairs(lobby.players) do
local isImpostor = (playerId == lobby.impostor)
TriggerClientEvent('imposter:roleReveal039;, playerId, isImpostor)
end
endWhy Client-Side Assignment Is Dangerous
If you assign roles on the client side, a cheater with a Lua executor could:
- Read the impostor assignment before reveal
- Modify their own role
- Broadcast the impostor's identity to the group
Server-side assignment with individual TriggerClientEvent calls ensures each player only knows their own role.
Component 3: Voting System
The voting phase is the heart of social deduction. Implementation requires:
Vote Collection
RegisterServerEvent('imposter:castVote039;)
AddEventHandler('imposter:castVote039;, function(targetId)
local source = source
local lobbyId = getPlayerLobby(source)
if not lobbyId then return end
if lobbies[lobbyId].state ~= 'voting039; then return end
if lobbies[lobbyId].votes[source] then return end -- Already voted
-- Validate target is in the lobby
if not isPlayerInLobby(targetId, lobbyId) then return end
lobbies[lobbyId].votes[source] = targetId
-- Broadcast updated vote count to all lobby players
broadcastVoteState(lobbyId)
-- Check if all votes are in
if allPlayersVoted(lobbyId) then
endVotingPhase(lobbyId)
end
end)Key Validations
- One vote per player: The server ignores duplicate votes
- Timer enforcement: When
Config.VoteTimeexpires, voting ends regardless of who has voted - Target validation: You cannot vote for someone who is not in the lobby
- State check: Votes are only accepted during the voting state
Vote Result Calculation
After voting ends, the server tallies votes and determines the outcome:
- Majority vote: The player with the most votes is eliminated (or "ejected")
- Tie handling: A tie could mean no elimination — design choice for the developer
- Win condition: If the impostor is eliminated, the crew wins. If not, the game continues or the impostor wins.
Component 4: NUI Interface
The NUI (NewUI) layer is what players actually see and interact with. For a social deduction game, the NUI needs to be:
Screen States
| State | What Players See |
|---|---|
| Closed | Nothing — NUI is hidden |
| Main Menu | Create game button, host options |
| Lobby | Player list with mugshots, invite button, start button (host only) |
| Role Reveal | Full-screen reveal showing "You are the Impostor" or "You are a Crewmate" |
| Discussion | Player mugshot grid, timer, discussion prompt |
| Voting | Player cards with vote buttons, live tally, countdown timer |
| Result | Win/loss screen, impostor reveal, replay button |
Why Vue 3 + Vite
Modern FiveM NUI development has moved beyond basic HTML/CSS/jQuery. Vue 3 with Vite offers:
- Reactive state management — UI updates automatically when game state changes
- Component architecture — Reusable player cards, vote buttons, timers
- Hot module replacement — Fast development iteration
- Small bundle size — Vite tree-shaking keeps the production build lean
- TypeScript support — Catch bugs at compile time
Alone Imposter uses this exact stack, resulting in a NUI that feels as polished as a standalone application.
Component 5: Player Identity
A critical differentiator for FiveM social deduction is using real character data instead of generic avatars.
Mugshot System
Alone Imposter displays player mugshots — actual character face captures — on player cards. This deepens immersion because you are voting against recognizable characters, not abstract names.
Framework Name Resolution
Character names are resolved from the active framework:
- QBCore/QBX: Pulls first and last name from player data
- ESX: Retrieves character name from the ESX player object
- Fallback: Uses the FiveM player name if no framework is detected
This means the voting screen shows "Marcus Johnson" (the character) instead of "xX_GamerTag_Xx" (the Steam name).
Build vs Buy: The Time Investment Reality
Building this system from scratch is entirely possible. But consider the real time investment:
| Component | Estimated Dev Time |
|---|---|
| Lobby management (server/client) | 20-30 hours |
| Role assignment & security | 5-10 hours |
| Voting system with validation | 15-20 hours |
| NUI design & development (Vue 3) | 40-60 hours |
| Mugshot/identity integration | 10-15 hours |
| Framework compatibility (3 frameworks) | 15-20 hours |
| Testing & bug fixing | 20-30 hours |
| Bilingual support | 5-10 hours |
| Total | 130-195 hours |
At €30-50/hour for a competent FiveM developer, that is €3,900-€9,750 in development costs.
Alone Imposter delivers all of this — tested, optimized, and ready to deploy — for a fraction of that cost.
Ready to Skip the Build Phase?
Alone Imposter handles every technical challenge discussed in this article — lobby management, secure role assignment, validated voting, Vue 3 NUI, framework detection, and multilingual support. All pre-built, pre-tested, and ready to deploy on your server.
→ Get Alone Imposter by Alone Studios
Have technical questions? Join the Discord community — our dev team is active daily.
Ready to Add Social Deduction to Your Server?
Alone Imposter delivers everything discussed in this article — proximity lobbies, mugshot player cards, voting system, Vue 3 NUI. QBCore, ESX & QBOX.
Get Alone Imposter on Tebex