Turn Manager

Runs a two player game that you send to a friend. You take a turn, then your friend opens the Lens and takes the next one.

Games & Interactivity

Game engines, physics, quizzes, leaderboards, and the UI controls that tie it together.

Made with this block

Events

onTurnStart

Fired once after the component initializes and loads prior turn data, for WHOEVER opens (including the receiver of a sent snap). The callback receives an object with: currentUserIndex (0 or 1), tappedKey (string, key of tappable the receiver pre-tapped or empty), turnCount (number, this turn's index starting at 0), promptDataVariables (object, all variables sent by the previous user). Restore state and render from the OPENER'S perspective so they never sit on the previous player's screen. Subscribe inside OnStartEvent (the only init event EasyLens controllers support; there is NO OnAwakeEvent). The component defers the first onTurnStart until after every OnStartEvent, so an OnStartEvent handler reliably receives it.

onTurnEnd

Fired after endTurn() succeeds and the turn is NOT final. The next user opens the snap and starts their turn.

onGameOver

Fired after endTurn() succeeds and the turn IS final (setIsFinalTurn(true) was called OR the turn limit was reached) - but ONLY on the device that OPENS the final snap, NOT for the player who MADE the final move (they already sent it and will not open again). So the player whose move ends the game must show the result on their OWN screen BEFORE endTurn; onGameOver then renders the same result for the opener. Both players must end on a correct, perspective-appropriate result (otherwise the winner never learns they won).

onError

Fired if turn data was sent or received incomplete. Callback receives {code: 'INCOMPLETE_TURN_DATA_SENT' | 'INCOMPLETE_TURN_DATA_RECEIVED', description: string}. Surface this to the user so they know to retry.

Functions

getCurrentUserIndexint

Returns a Promise<number> resolving to the index of the current user (0 or 1). ASYNC — must be awaited or chained with .then. Use to decide whose turn it is. Even turn counts = user 0; odd = user 1. Example: script.turn_manager.getCurrentUserIndex().then(function(idx){ /* 0 or 1 */ })

getOtherUserIndexint

Returns a Promise<number> for the OTHER user's index. Pairs with setOtherUserVariable / getOtherUserVariable for asymmetric games. Example: script.turn_manager.getOtherUserIndex().then(function(idx){ /* 0 or 1 */ })

getTurnCountint

Returns a Promise<number> for the current turn count, starting at 0. ASYNC — must be awaited. Example: script.turn_manager.getTurnCount().then(function(n){ /* 0, 1, 2, ... */ })

setCurrentTurnVariablevoid

SYNCHRONOUS. Set a variable that will be sent to the next user with the snap. THIS IS THE MAIN PERSISTENCE CALL. Use for game state (board, score, last-move, etc.) that BOTH users see on subsequent turns. Value must be JSON-serializable. NOTE: this OVERWRITES the key; for accumulating state (like a story), read-modify-write the previous value. Example: script.turn_manager.setCurrentTurnVariable('board', [0,1,0,2,0,0,0,0,0])

getCurrentTurnVariableObject

SYNCHRONOUS. Read back a variable previously written this turn via setCurrentTurnVariable. Use for read-modify-write inside the same turn (e.g. accumulating list updates). Example: var board = script.turn_manager.getCurrentTurnVariable('board')

getPreviousTurnVariableObject

Returns a Promise<value | undefined> for a variable from the PREVIOUS user's turn data. ASYNC — must be awaited. Use to load opponent state at the start of your turn. Returns undefined on the very first turn. Example: script.turn_manager.getPreviousTurnVariable('board').then(function(board){ ... })

getPreviousTurnVariablesObject

Returns a Promise<{[key]: value}> for ALL variables sent by the previous user. Empty object {} on the first turn. ASYNC — must be awaited. Example: script.turn_manager.getPreviousTurnVariables().then(function(vars){ ... })

setUserVariablevoid

Returns a Promise<void>. Set a PER-USER variable (scoped to one player, persists across that player's future turns). Use for secret roles, individual scores, per-user UI state. The other user CANNOT read this unless you call setOtherUserVariable. Critical for hidden-information games (Werewolf, Battleship hidden grid, Tarot secret cards). Example: script.turn_manager.setUserVariable(0, 'role', 'werewolf')

getUserVariableObject

Returns a Promise<value | undefined>. Read a PER-USER variable for a given player. Use for retrieving a secret role on a re-open. Example: script.turn_manager.getUserVariable(0, 'role').then(function(role){ ... })

setCurrentUserVariablevoid

Returns a Promise<void>. Shorthand for setUserVariable(currentUserIndex, key, value). Sets a variable scoped to the user taking THIS turn. Example: script.turn_manager.setCurrentUserVariable('role', 'werewolf')

setOtherUserVariablevoid

Returns a Promise<void>. Sets a variable scoped to the OTHER user. Use for sending a private message visible only to your opponent (e.g. revealing your role to them). Example: script.turn_manager.setOtherUserVariable('hint', 'look north')

setGlobalVariablevoid

Returns a Promise<void>. Sets a GLOBAL variable shared across all turns and users. Use for game-wide config (theme, difficulty, target score) that doesn't change per-turn. Example: script.turn_manager.setGlobalVariable('targetScore', 50)

getGlobalVariableObject

Returns a Promise<value | undefined>. Read a global variable. Example: script.turn_manager.getGlobalVariable('targetScore').then(function(t){ ... })

setScorevoid

SYNCHRONOUS. Set a numeric score for this turn. The component includes it in the snap metadata automatically — no need to also put it in turn variables. Pass null to clear. Example: script.turn_manager.setScore(42)

getScoreint

SYNCHRONOUS. Returns the currently set score or null. Example: var s = script.turn_manager.getScore()

getTappedKeystring

SYNCHRONOUS. Returns the key of the tappable area the current user pre-tapped from the snap preview before opening. Empty string if no pre-tap or first turn. Example: var key = script.turn_manager.getTappedKey()

addTappableAreavoid

SYNCHRONOUS. Register a tappable area for the receiver to pre-tap in the snap preview. The friend's lens gets this key in onTurnStart.tappedKey on their open. Pass a ScreenTransform Component that defines the on-screen rect. OPTIONAL — skip entirely if your game uses normal TapEvent instead. Example: script.turn_manager.addTappableArea('cell_3', cellScreenTransform)

clearTappableAreasvoid

SYNCHRONOUS. Remove all registered tappable areas. Use before re-registering with new state. Example: script.turn_manager.clearTappableAreas()

setIsFinalTurnvoid

SYNCHRONOUS. Mark the current turn as FINAL. When endTurn() fires next, onGameOver fires (not onTurnEnd) and the lens becomes immutable. Compute the final-turn condition fresh each move (e.g. win/draw for grids, list.length >= N for accumulators, day-count for time-based). Example: script.turn_manager.setIsFinalTurn(winner !== null)

endTurnvoid

SYNCHRONOUS. Mark the current turn complete; the next user then receives the snap. IMPORTANT: endTurn() CAPTURES THE CURRENT SCREEN as the snap your friend opens, so the frame on screen at this moment is your friend's FIRST view. Frame it for the OPENER (e.g. 'Your move - tap to play', or the board ready for them; a neutral cover for hidden-info), NEVER a sender-only message like 'Turn sent' / 'Sending...'. After this, turn variables cannot be changed. REQUIRED when the component's requireTurnSubmission is true (the default for TurnBased.v.1.2.2.lsc). Fires onTurnEnd (or onGameOver if setIsFinalTurn(true) was called). Example: script.turn_manager.endTurn()

isFinalTurnboolean

Returns a Promise<boolean> indicating whether this turn is final (turn limit reached or setIsFinalTurn(true) was called). Example: script.turn_manager.isFinalTurn().then(function(done){ ... })

getCurrentUserDisplayNamestring

Returns a Promise<string> for the current user's Snapchat display name. Example: script.turn_manager.getCurrentUserDisplayName().then(function(name){ ... })

getOtherUserDisplayNamestring

Returns a Promise<string> for the other user's Snapchat display name. Example: script.turn_manager.getOtherUserDisplayName().then(function(name){ ... })

removeTappableAreavoid

SYNCHRONOUS. Remove a single previously-registered tappable area by key. Use when a specific snap-preview pre-tap slot should be retired (e.g. a cell was just played) without rebuilding the entire tappable list via clearTappableAreas(). Example: script.turn_manager.removeTappableArea('cell_3')

getTurnHistoryObject

Returns a Promise<Array<TurnHistoryEntry>>. Reads the saved turn history when useTurnHistory is enabled on the component. Each entry contains the prior turn's variables and isTurnComplete flag. Use for replay UIs, undo, or show-all-previous-moves visualizations. Empty array if useTurnHistory is false or no history exists. Example: script.turn_manager.getTurnHistory().then(function(history){ ... })

getPreviousTurnObject

Returns a Promise<TurnHistoryEntry | null> for the immediately-previous turn from turn history. Convenience wrapper around getTurnHistory()[length-1]. Returns null if no prior turn exists or useTurnHistory is disabled. Example: script.turn_manager.getPreviousTurn().then(function(turn){ ... })

getUserObject

Returns a Promise<SnapchatUser | null> for the SnapchatUser object at the given index. Provides displayName, userId hash, and Bitmoji-related fields. Use when you need richer user identity than getCurrentUserDisplayName / getOtherUserDisplayName (e.g. Bitmoji rendering, per-user persistence keys). Example: script.turn_manager.getUser(0).then(function(user){ ... })