4.1 Introduction: Voting as the Core Mechanic
While murder removes one player per night, banishment is the only mechanism by which Traitors can be eliminated from the game. This asymmetry, explored in depth in the chapter on Information Asymmetry, makes voting dynamics central to both strategic planning and dramatic tension.
The voting system must achieve multiple design goals:
- Enable Faithful Victory: Provide a path for the majority to prevail
- Enable Traitor Survival: Allow skilled Traitors to avoid detection
- Create Drama: Generate conflict, alliance shifts, and emotional moments
- Maintain Legitimacy: Feel fair even when outcomes are tragic
The plurality system achieves these goals through elegant simplicity (each player casts one vote, the player with the most votes is eliminated) while creating space for complex strategic manoeuvre.
4.2 First-Past-The-Post in Small Groups
4.2.1 The Plurality System
The Traitors uses plurality voting (first-past-the-post):
- Each player casts exactly one vote
- The player receiving the most votes is banished
- No majority threshold required
- All votes are revealed sequentially
Mathematical Properties:
For n voters and m candidates:
- Minimum winning votes: ⌊n/m⌋ + 1 (theoretical)
- Practical minimum: Often just 3-4 votes with split field
- Maximum possible tie: n/m votes each (if evenly distributed)
4.2.2 Strategic Implications of Plurality
Vote Splitting: With multiple viable targets, votes can fragment:
| Scenario | Player A | Player B | Player C | Others | Result |
|---|---|---|---|---|---|
| Concentrated | 8 | 2 | 1 | 1 | A banished (clear) |
| Split | 4 | 4 | 3 | 1 | Tie: A and B |
| Fragmented | 3 | 3 | 3 | 3 | Multi-way tie |
Strategic Opportunity: Traitors can exploit splits by:
- Quietly voting for a non-target to reduce winning threshold
- Coordinating on unexpected target when field is split
- Supporting two competing anti-Traitor candidates to divide opposition
4.2.3 The Swing Voter Phenomenon
In close votes, the last few voters have disproportionate power:
Scenario: 5 votes for A, 5 votes for B, 2 voters remaining
Each remaining voter can:
- Decide the outcome (vote for either leader)
- Create a tie (one each)
- Neither outcome is "wrong" from a strategic standpoint
Behavioural Implications:
- Late voters face more scrutiny
- "Following the herd" is safer for reputation
- Strategic deviations are more visible and memorable
4.2.4 The Dagger Modification
When Daggers are in play, the calculus changes:
Standard Vote: 1 point per vote
Dagger Vote: 2 points
Strategic Implications:
- Dagger holder can swing close votes single-handedly
- Reveals that holder lacks Shield (vulnerability signal)
- Near-mandatory use (no advantage to holding)
- Endgame value increases as voting pool shrinks
Example:
- 10 voters, 4 for A, 4 for B, 2 for C
- Dagger holder for A: 6 for A, 4 for B, 2 for C → A banished
- Dagger holder against flow could save an ally or punish an enemy
4.3 Coalition Formation
4.3.1 Alliance Structures
Alliances form naturally in The Traitors as players seek:
- Information sharing partners
- Voting coordination
- Murder protection (Traitors may spare allied players)
- Emotional support
Common Alliance Types:
| Type | Size | Strength | Vulnerability |
|---|---|---|---|
| Dyad | 2 | High trust, flexible | Easily targeted, limited influence |
| Triad | 3 | Voting bloc potential | Internal tension, "who's the third wheel" |
| Faction | 4-6 | Dominant voting power | Visible target, requires coordination |
| Outer Alliance | 2-3 + periphery | Flexible membership | Loyalty unclear |
4.3.2 The "Andrea's Angels" Phenomenon
Named for a UK alliance pattern (explored further in International Variations), this describes a charismatic leader with devoted followers:
Structure:
Andrea (Leader)
/ | \
Ally 1 Ally 2 Ally 3
Strengths:
- Clear vote coordination
- Emotional investment creates loyalty
- Leader provides strategic direction
Vulnerabilities:
- Leader death/banishment dissolves group
- Traitors can infiltrate through leader relationship (see Secret Traitor analysis)
- Creates obvious voting bloc for opposition to target
4.3.3 Alliance Formation Dynamics
Early Game (Episodes 1-3):
- Alliances form around proximity (who you room near)
- Pre-existing relationships (if known)
- First-impression chemistry
- Shared suspicions
Mid Game (Episodes 4-8):
- Alliances consolidate or fracture based on banishment outcomes
- "We both voted for [Faithful]" guilt bonding
- "You were right about [Traitor]" validation bonding
- Strategic realignments as power shifts
Late Game (Episodes 9+):
- Alliances become explicit voting blocs
- "We have the numbers" calculations
- Betrayal pressure intensifies (who might flip?)
- Endgame positioning supersedes loyalty
4.3.4 Coalition Mathematics
For a voting bloc to be dominant:
Requirement: bloc_size > n/2 (simple majority)
With Dagger: bloc_size > (n - dagger_bonus)/2
Practical Thresholds (typical 12-player mid-game):
| Bloc Size | Voting Power | Status |
|---|---|---|
| 2-3 | 16-25% | Vulnerable minority |
| 4-5 | 33-42% | Significant bloc |
| 6 | 50% | Tie or majority |
| 7+ | 58%+ | Dominant coalition |
4.4 Traitor Voting Strategy
4.4.1 The Blending Strategy
The default Traitor approach: vote with the majority.
Logic: Traitors aim to appear as normal Faithfuls. Normal Faithfuls often vote with consensus. Therefore, Traitors should follow consensus voting.
Execution:
- Monitor pre-vote discussion for emerging consensus
- Commit to consensus target when voting
- Express appropriate doubt/reluctance before committing
Risk: Provides no distinctive value; may be detected through lack of contribution to finding Traitors
4.4.2 Vote Pattern Analysis Defense
Sophisticated Faithfuls analyse voting patterns:
Detection Method: "Who has never voted for a Traitor?"
Traitor Counter-Strategy:
- Occasionally vote for fellow Traitors who are already doomed
- Support anti-Traitor votes when outcome is certain
- Lead accusations against struggling Traitors (the "hero play")
4.4.3 The "Hero Play"
The most advanced Traitor voting strategy: publicly leading the charge against a fellow Traitor.
Conditions for Execution:
- Fellow Traitor is under heavy suspicion (likely banishment regardless)
- Own position is secure enough to risk attention
- Post-banishment reward (credibility boost) outweighs cost (fellow Traitor's loss)
Examples from Analysis:
- Harry sacrificing Paul (UK S2)
- Cirie casting decisive vote against Cody (US S1)
Effect: Transforms from "undetected Traitor" to "brilliant Traitor hunter" in Faithful perception. This strategy is characteristic of certain strategic archetypes.
Risk: If discovered later, the betrayal amplifies backlash. Fellow Traitors may refuse future coordination.
4.4.4 Protecting Fellow Traitors
When a fellow Traitor is accused:
Visible Defense (High Risk):
- Directly argue for innocence
- Challenge evidence presented
- Propose alternative suspects
Subtle Protection (Lower Risk):
- Quietly vote for someone else without championing the Traitor
- Introduce procedural delays ("shouldn't we hear from everyone?")
- Question accuser's motives without defending accused
When to Sacrifice:
- Traitor is certainly doomed (protection wastes credibility)
- Traitor has become liability (poor play, suspicious behaviour)
- Sacrifice enables "hero play" opportunity
- Remaining Traitor(s) are better positioned
4.4.5 Vote Coordination Among Traitors
Traitors can coordinate votes during Conclave discussions:
Coordination Benefits:
- Concentrate votes on desired target
- Split votes to create ties
- Signal to each other during Round Table
Coordination Risks:
- Identical voting creates pattern
- Non-verbal signals may be detected
- Disagreement visible if coordination fails
Observed Pattern: Successful Traitors often vote together but not identically; they coordinate on targets but not on every vote.
4.5 Faithful Voting Strategy
4.5.1 Evidence-Based Voting
The normative Faithful approach: vote based on observable evidence.
Evidence Categories:
| Category | Weight | Example |
|---|---|---|
| Caught lying | 0.35 | Claimed to be somewhere they weren't |
| Voted for Faithfuls consistently | 0.25 | 3+ Faithful votes, no Traitor votes |
| Behavioural shift | 0.20 | Changed personality after selection |
| Mission sabotage (suspected) | 0.15 | Actions that undermined success |
| Gut feeling | 0.05 | "Something feels wrong" |
4.5.2 Pattern Recognition Across Rounds
Vote History Analysis:
Episode 3:
- Player X voted for A (Faithful)
- Player X voted differently from Players Y, Z (both Traitors)
Episode 5:
- Player X voted for B (Traitor)
- First vote against a Traitor
Interpretation: X more likely Faithful (eventually found Traitor)
Murder Target Analysis:
Never murdered:
- Very visible player Y
- Very trusted player Z
Interpretation: Y or Z may be Traitors (protected by faction)
4.5.3 The "Untouchable" Heuristic
Astute Faithfuls (like Jaz in UK S2) focus on who survives rather than who acts suspiciously:
Logic: Traitors don't murder each other. Players who should be targets but survive may be Traitors.
Application:
- Identify high-value Faithful targets (leaders, alliance heads)
- Note who survives despite being "obvious" targets
- Weight survival pattern in voting decisions
Limitation: Traitors may deliberately spare some Faithfuls to create false suspects.
4.5.4 The Seer's Dilemma
When a Faithful has privileged information (from special mechanics or sharp observation):
The Problem: How to convince others of truth that cannot be proven?
Strategies:
- Build credibility through smaller accurate predictions first
- Form alliance before revealing information
- Present information as "suspicion" rather than "certainty"
- Accept that some correct information will be rejected
From Transcript Analysis:
"I was convinced. I was convinced. I would've put my house on it."
"When she stood on that circle and went, 'I'm a Faithful,' I felt like I'd been hit by a bus."
Even high-confidence predictions fail when social dynamics override analytical conclusions. This phenomenon is examined in detail in Audience Psychology.
4.5.5 Defensive Voting
When a Faithful is under accusation:
Self-Voting: Never an option (rules prohibit or votes don't count)
Counter-Accusation: "You're accusing me because..."
- Creates alternative narrative
- Risks escalating conflict
- Most effective when targeting a plausible alternative
Vote Marshaling: Ensure allies vote elsewhere
- Distribute alternative targets among trusted allies
- Accept that some allies may follow herd to protect themselves
4.6 Tie-Breaking Dynamics
4.6.1 Standard Revote
When votes are tied:
- Tied players cannot vote
- All other players vote only between tied candidates
- Plurality determines banishment
- If still tied: version-dependent resolution
Strategic Implications:
- Tied players have no agency
- Swing voters gain maximum power
- Pre-revote lobbying intensifies
- Alliances with tied players become irrelevant
4.6.2 Extended Tie Protocols
Portugal Variant:
- Standard revote between tied players
- If still tied: tied players become ineligible
- New vote among all remaining candidates
- Repeat until resolved or only 2 players remain
Effect: Prevents gaming through manufactured ties.
4.6.3 Final Three Exception (US S2)
In final 3 scenarios:
- Standard rules would leave only 1 voter if 2 are tied
- Modified rule: All players can vote for any candidate
- Creates unique dynamics where everyone has stake
4.6.4 Strategic Tie Creation
Traitors may intentionally create ties:
Goals:
- Create chaos that delays banishment
- Force revote where Traitor has no vote (if Traitor is tied)
- Test alliance strength under pressure
Execution:
- Coordinate Traitor votes for secondary target
- Encourage vote splitting through discussion
- Surprise swing to create unexpected tie
4.7 Endgame Voting
4.7.1 The "End Game or Continue" Decision
Modern format (UK, US):
- After each Round Table, survivors vote: "End" or "Continue"
- Unanimous "End" required to finish
- Any "Continue" vote triggers another banishment round
Strategic Calculus:
| Player Status | End Preference | Continue Preference |
|---|---|---|
| Confident Faithful | End (if believe all Traitors gone) | Continue (if suspicious of survivors) |
| Uncertain Faithful | Depends on confidence level | Depends on risk tolerance |
| Traitor | End (survive and win) | Rarely (already winning if surviving) |
4.7.2 The Defection Decision
A single "Continue" vote forces another round:
When to Defect (Faithful):
- Genuinely suspicious of survivor(s)
- Believe additional information will emerge
- Risk tolerance for extended gameplay
When to Defect (Traitor):
- Almost never (already winning by surviving)
- Unless: another Traitor is likely to be caught, and own safety is certain
4.7.3 Final Two Dynamics
When only 2 players remain, the game ends automatically:
- If both Faithful: Split prize
- If one/both Traitor(s): Traitor(s) take all
The Trust Apocalypse:
At final 2, there is no voting, just revelation. All strategic behaviour has concluded. The moment is pure outcome, determined by all previous decisions.
4.7.4 The No-Reveal Innovation (2024+)
Endgame banishments no longer require role revelation:
Effect on Voting:
- Cannot confirm if decisions were correct
- No "process of elimination" certainty
- Must trust analytical judgment without feedback
Psychological Impact (see also Emotion and Deception Engine):
- Heightened uncertainty maintained to finale
- No relief/confirmation between rounds
- Final reveal more dramatic
4.8 Mathematical Models for Vote Prediction
4.8.1 Individual Vote Probability
For player i voting for target j:
P(Vote_i→j) depends on:
- Suspicion level: S_i(j)
- Alliance structure: A(i,j)
- Social pressure: SP(j)
- Strategic considerations: Strat_i(j)
Combined Model:
Raw_score(i,j) = w_s × S_i(j) + w_a × (1-A(i,j)) + w_sp × SP(j) + w_st × Strat_i(j)
P(Vote_i→j) = exp(Raw_score(i,j)) / Σ_k exp(Raw_score(i,k))
Where w_s, w_a, w_sp, w_st are weights summing to 1.
Go Implementation:
import "math"
// VoteWeights represents the weighting factors for vote prediction
type VoteWeights struct {
Suspicion float64 // w_s: weight for suspicion level
Alliance float64 // w_a: weight for alliance factor
Social float64 // w_sp: weight for social pressure
Strategic float64 // w_st: weight for strategic considerations
}
// DefaultVoteWeights returns balanced voting weights that sum to 1.0
func DefaultVoteWeights() *VoteWeights {
return &VoteWeights{
Suspicion: 0.35,
Alliance: 0.25,
Social: 0.25,
Strategic: 0.15,
}
}
// VotePredictionModel calculates vote probabilities for a player
type VotePredictionModel struct {
Voter PlayerID
Weights *VoteWeights
}
// VoteFactors contains all factors influencing a vote for a specific target
type VoteFactors struct {
Suspicion float64 // S_i(j): suspicion level [0,1]
Alliance float64 // A(i,j): alliance strength [0,1]
SocialPressure float64 // SP(j): social pressure to vote for target [0,1]
Strategic float64 // Strat_i(j): strategic value of voting for target [0,1]
}
// CalculateRawScore computes the raw score for voting for a target
// Raw_score(i,j) = w_s × S_i(j) + w_a × (1-A(i,j)) + w_sp × SP(j) + w_st × Strat_i(j)
func (vpm *VotePredictionModel) CalculateRawScore(factors *VoteFactors) float64 {
w := vpm.Weights
return w.Suspicion*factors.Suspicion +
w.Alliance*(1.0-factors.Alliance) + // Lower alliance = higher vote likelihood
w.Social*factors.SocialPressure +
w.Strategic*factors.Strategic
}
// CalculateVoteProbabilities returns probability distribution over all candidates
// P(Vote_i→j) = exp(Raw_score(i,j)) / Σ_k exp(Raw_score(i,k))
func (vpm *VotePredictionModel) CalculateVoteProbabilities(
candidates []PlayerID,
factorsMap map[PlayerID]*VoteFactors,
) map[PlayerID]float64 {
// Calculate raw scores for all candidates
rawScores := make(map[PlayerID]float64)
for _, candidate := range candidates {
factors := factorsMap[candidate]
rawScores[candidate] = vpm.CalculateRawScore(factors)
}
// Apply softmax transformation
// exp(score) for each candidate
expScores := make(map[PlayerID]float64)
sumExp := 0.0
for _, candidate := range candidates {
exp := math.Exp(rawScores[candidate])
expScores[candidate] = exp
sumExp += exp
}
// Normalise to get probabilities
probabilities := make(map[PlayerID]float64)
for _, candidate := range candidates {
probabilities[candidate] = expScores[candidate] / sumExp
}
return probabilities
}
// GetMostLikelyVote returns the candidate with highest vote probability
func (vpm *VotePredictionModel) GetMostLikelyVote(
candidates []PlayerID,
factorsMap map[PlayerID]*VoteFactors,
) (PlayerID, float64) {
probs := vpm.CalculateVoteProbabilities(candidates, factorsMap)
var maxCandidate PlayerID
maxProb := 0.0
for candidate, prob := range probs {
if prob > maxProb {
maxProb = prob
maxCandidate = candidate
}
}
return maxCandidate, maxProb
}
4.8.2 Vote Outcome Prediction
For n voters and candidates C:
Monte Carlo Approach:
- For each voter, sample vote according to P(Vote_i→j)
- Tally votes across candidates
- Identify winner (or tie scenario)
- Repeat N times
- Report probability distribution over outcomes
Expected Margin:
E[Votes(j)] = Σ_i P(Vote_i→j)
Var[Votes(j)] = Σ_i P(Vote_i→j) × (1 - P(Vote_i→j))
Go Implementation:
import (
"math"
"math/rand"
"sort"
)
// VoteOutcomeSimulator predicts vote outcomes using Monte Carlo simulation
type VoteOutcomeSimulator struct {
Voters []PlayerID
Candidates []PlayerID
VoteProbabilities map[PlayerID]map[PlayerID]float64 // voter -> candidate -> probability
}
// NewVoteOutcomeSimulator creates a simulator from individual vote models
func NewVoteOutcomeSimulator(
voters []PlayerID,
candidates []PlayerID,
models map[PlayerID]*VotePredictionModel,
factorsMaps map[PlayerID]map[PlayerID]*VoteFactors,
) *VoteOutcomeSimulator {
sim := &VoteOutcomeSimulator{
Voters: voters,
Candidates: candidates,
VoteProbabilities: make(map[PlayerID]map[PlayerID]float64),
}
// Calculate vote probabilities for each voter
for _, voter := range voters {
model := models[voter]
factors := factorsMaps[voter]
sim.VoteProbabilities[voter] = model.CalculateVoteProbabilities(candidates, factors)
}
return sim
}
// SimulationResult contains the outcome of a single simulation run
type SimulationResult struct {
Tally map[PlayerID]int
Winner PlayerID
IsTie bool
TiedWith []PlayerID
}
// RunMonteCarloSimulation runs N simulations and returns outcome distribution
func (vos *VoteOutcomeSimulator) RunMonteCarloSimulation(n int) map[PlayerID]float64 {
winCounts := make(map[PlayerID]int)
for i := 0; i < n; i++ {
result := vos.simulateSingleVote()
if !result.IsTie {
winCounts[result.Winner]++
} else {
// Distribute tie among tied candidates
for _, tied := range result.TiedWith {
winCounts[tied]++
}
}
}
// Convert to probabilities
outcomes := make(map[PlayerID]float64)
for candidate, count := range winCounts {
outcomes[candidate] = float64(count) / float64(n)
}
return outcomes
}
// simulateSingleVote runs one vote simulation
func (vos *VoteOutcomeSimulator) simulateSingleVote() *SimulationResult {
tally := make(map[PlayerID]int)
// Each voter samples their vote according to probability distribution
for _, voter := range vos.Voters {
probs := vos.VoteProbabilities[voter]
vote := sampleFromDistribution(vos.Candidates, probs)
tally[vote]++
}
// Find winner(s)
maxVotes := 0
for _, votes := range tally {
if votes > maxVotes {
maxVotes = votes
}
}
var winners []PlayerID
for candidate, votes := range tally {
if votes == maxVotes {
winners = append(winners, candidate)
}
}
return &SimulationResult{
Tally: tally,
Winner: winners[0],
IsTie: len(winners) > 1,
TiedWith: winners,
}
}
// sampleFromDistribution samples a candidate based on probability distribution
func sampleFromDistribution(candidates []PlayerID, probs map[PlayerID]float64) PlayerID {
r := rand.Float64()
cumulative := 0.0
for _, candidate := range candidates {
cumulative += probs[candidate]
if r <= cumulative {
return candidate
}
}
return candidates[len(candidates)-1]
}
// ExpectedVotes calculates the expected vote count for each candidate
// E[Votes(j)] = Σ_i P(Vote_i→j)
type ExpectedVotes struct {
Expected map[PlayerID]float64
Variance map[PlayerID]float64
}
func (vos *VoteOutcomeSimulator) CalculateExpectedVotes() *ExpectedVotes {
result := &ExpectedVotes{
Expected: make(map[PlayerID]float64),
Variance: make(map[PlayerID]float64),
}
for _, candidate := range vos.Candidates {
var expected, variance float64
for _, voter := range vos.Voters {
p := vos.VoteProbabilities[voter][candidate]
// E[Votes(j)] = Σ_i P(Vote_i→j)
expected += p
// Var[Votes(j)] = Σ_i P(Vote_i→j) × (1 - P(Vote_i→j))
variance += p * (1 - p)
}
result.Expected[candidate] = expected
result.Variance[candidate] = variance
}
return result
}
// GetExpectedWinner returns the candidate with highest expected votes
func (ev *ExpectedVotes) GetExpectedWinner() (PlayerID, float64) {
var winner PlayerID
maxExpected := 0.0
for candidate, expected := range ev.Expected {
if expected > maxExpected {
maxExpected = expected
winner = candidate
}
}
return winner, maxExpected
}
// GetConfidenceInterval returns the 95% confidence interval for a candidate's votes
func (ev *ExpectedVotes) GetConfidenceInterval(candidate PlayerID) (float64, float64) {
expected := ev.Expected[candidate]
stdDev := math.Sqrt(ev.Variance[candidate])
// 95% CI ≈ mean ± 1.96 × stdDev
return expected - 1.96*stdDev, expected + 1.96*stdDev
}
4.8.3 Coalition Stability Analysis
For coalition C within voter set V:
Stability Score:
Stability(C) = min(P(Vote_i→target | i ∈ C)) × size(C)
A coalition is stable if all members have high probability of voting together.
Defection Pressure:
Defection_i = max_j(S_i(j) | j ∈ C, j ≠ target)
If any coalition member is highly suspicious of another member, defection is likely.
Go Implementation:
// Coalition represents a voting bloc
type Coalition struct {
ID string
Members []PlayerID
Target PlayerID // Current consensus target for banishment
Strength float64 // Overall coalition cohesion
}
// CoalitionAnalyser evaluates coalition stability
type CoalitionAnalyser struct {
VoteProbabilities map[PlayerID]map[PlayerID]float64
Suspicions map[PlayerID]map[PlayerID]float64
}
// StabilityResult contains coalition stability metrics
type StabilityResult struct {
StabilityScore float64
WeakestMember PlayerID
WeakestProbability float64
DefectionPressures map[PlayerID]float64
}
// CalculateStabilityScore computes coalition stability
// Stability(C) = min(P(Vote_i→target | i ∈ C)) × size(C)
func (ca *CoalitionAnalyser) CalculateStabilityScore(coalition *Coalition) *StabilityResult {
result := &StabilityResult{
DefectionPressures: make(map[PlayerID]float64),
}
minProbability := 1.0
var weakestMember PlayerID
for _, member := range coalition.Members {
// Get probability that this member votes for coalition target
prob := ca.VoteProbabilities[member][coalition.Target]
if prob < minProbability {
minProbability = prob
weakestMember = member
}
// Calculate defection pressure for this member
defectionPressure := ca.CalculateDefectionPressure(member, coalition)
result.DefectionPressures[member] = defectionPressure
}
result.WeakestMember = weakestMember
result.WeakestProbability = minProbability
// Stability(C) = min(P(Vote_i→target | i ∈ C)) × size(C)
result.StabilityScore = minProbability * float64(len(coalition.Members))
return result
}
// CalculateDefectionPressure calculates the pressure for a member to defect
// Defection_i = max_j(S_i(j) | j ∈ C, j ≠ target)
func (ca *CoalitionAnalyser) CalculateDefectionPressure(
member PlayerID,
coalition *Coalition,
) float64 {
maxSuspicion := 0.0
for _, otherMember := range coalition.Members {
// Skip the target (suspicion of target is expected)
if otherMember == coalition.Target {
continue
}
// Skip self
if otherMember == member {
continue
}
suspicion := ca.Suspicions[member][otherMember]
if suspicion > maxSuspicion {
maxSuspicion = suspicion
}
}
return maxSuspicion
}
// IsCoalitionStable returns true if coalition is likely to vote together
func (ca *CoalitionAnalyser) IsCoalitionStable(coalition *Coalition) bool {
result := ca.CalculateStabilityScore(coalition)
// Coalition is stable if:
// 1. Stability score is above threshold (e.g., 3.0 for a 5-person coalition)
// 2. No member has defection pressure above 0.6
stableThreshold := float64(len(coalition.Members)) * 0.6
defectionThreshold := 0.6
if result.StabilityScore < stableThreshold {
return false
}
for _, pressure := range result.DefectionPressures {
if pressure > defectionThreshold {
return false
}
}
return true
}
// PredictDefectors returns members likely to break from coalition
func (ca *CoalitionAnalyser) PredictDefectors(coalition *Coalition) []PlayerID {
var defectors []PlayerID
result := ca.CalculateStabilityScore(coalition)
// Members with low target vote probability or high internal suspicion
for _, member := range coalition.Members {
targetProb := ca.VoteProbabilities[member][coalition.Target]
defectionPressure := result.DefectionPressures[member]
// Likely to defect if target probability < 0.5 OR defection pressure > 0.5
if targetProb < 0.5 || defectionPressure > 0.5 {
defectors = append(defectors, member)
}
}
return defectors
}
// FindOptimalCoalition finds the most stable possible coalition for a target
func (ca *CoalitionAnalyser) FindOptimalCoalition(
allPlayers []PlayerID,
target PlayerID,
minSize int,
) *Coalition {
// Score each player by their likelihood to vote for target
type playerScore struct {
ID PlayerID
Score float64
}
var scores []playerScore
for _, player := range allPlayers {
if player == target {
continue
}
scores = append(scores, playerScore{
ID: player,
Score: ca.VoteProbabilities[player][target],
})
}
// Sort by score descending
sort.Slice(scores, func(i, j int) bool {
return scores[i].Score > scores[j].Score
})
// Build coalition from highest-scoring players
coalition := &Coalition{
Target: target,
Members: make([]PlayerID, 0, minSize),
}
for i := 0; i < len(scores) && i < minSize; i++ {
coalition.Members = append(coalition.Members, scores[i].ID)
}
// Calculate strength
result := ca.CalculateStabilityScore(coalition)
coalition.Strength = result.StabilityScore
return coalition
}
4.9 Voting as Performance
4.9.1 The Public Vote Reveal
Unlike secret ballot systems, The Traitors reveals votes sequentially:
Effects:
- Early voters set tone
- Late voters face pressure to conform or defy
- Justification expected for each vote
- Social relationships visibly tested
4.9.2 Vote Justification Rhetoric
From transcript analysis, common patterns:
Accusation Justification:
"With regrets, [Name], I've put your name down."
"It honestly is absolutely nothing personal at all."
"I've gone with [Name] because of what we discussed."
Defense of Non-Consensus Vote:
"I know everyone's going for [X], but I think it's [Y]."
"I'm sticking with what I first said."
"I can't shake the feeling about [Name]."
4.9.3 Post-Vote Emotional Dynamics
The vote reveal creates immediate emotional reactions:
For the Accused:
- Each vote is a betrayal by someone trusted
- Defending becomes impossible as votes accumulate
- Emotional display affects how revelation is received
For Voters:
- Guilt if voting for friend
- Anxiety if voting against consensus
- Relief if vote aligns with outcome
For the Group:
- Tension during counting
- Collective reaction to banishment
- Processing of new information (role reveal)
4.10 Conclusion: The Electoral Arena
Voting in The Traitors creates a micro-electoral system where:
- Information is currency: What you know influences how you vote
- Alliances are fragile: Coalition stability determines outcomes
- Signals are strategic: Votes reveal as much as they decide
- Ties create chaos: Edge cases produce maximum drama
- Endgame inverts logic: Continuing becomes the radical choice
The system succeeds because it balances multiple objectives:
- Majority rule enables Faithful victory path
- Plurality voting allows Traitor survival through split opposition
- Sequential revelation creates drama
- Tie-breaking maintains resolution
Understanding voting dynamics is essential for both gameplay success and computational modelling. Chapter 5 explores how these dynamics manifest in distinct player archetypes. For the computational implementation of these models, see the RAG Architecture and Cognitive Memory Architecture chapters.