Back to Blog
Technical 13 min read February 12, 2026

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.

among us fivem fivem among us script imposter game fivem fivem game modes fivem lua scripting fivem nui development

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

lua
-- 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 = 'waiting', -- 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:

  1. Server receives invite request from host
  2. Server gets host position via GetEntityCoords
  3. Server iterates all players, calculating distance
  4. Players within Config.InviteRadius are returned as invite candidates
  5. Host selects from the list in the NUI
  6. 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

lua
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:roleReveal', playerId, isImpostor)

end

end

Why 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

lua
RegisterServerEvent('imposter:castVote')
AddEventHandler('imposter:castVote', function(targetId)

local source = source

local lobbyId = getPlayerLobby(source)

if not lobbyId then return end

if lobbies[lobbyId].state ~= 'voting' 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.VoteTime expires, 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

StateWhat Players See
ClosedNothing — NUI is hidden
Main MenuCreate game button, host options
LobbyPlayer list with mugshots, invite button, start button (host only)
Role RevealFull-screen reveal showing "You are the Impostor" or "You are a Crewmate"
DiscussionPlayer mugshot grid, timer, discussion prompt
VotingPlayer cards with vote buttons, live tally, countdown timer
ResultWin/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:

ComponentEstimated Dev Time
Lobby management (server/client)20-30 hours
Role assignment & security5-10 hours
Voting system with validation15-20 hours
NUI design & development (Vue 3)40-60 hours
Mugshot/identity integration10-15 hours
Framework compatibility (3 frameworks)15-20 hours
Testing & bug fixing20-30 hours
Bilingual support5-10 hours
Total130-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