Upsell
Based on game build 714014 | Last updated: 2026-03-10
Overview
The upsell.lua script handles the lifecycle of the demo version upsell screen. It controls when and how the upsell UI is displayed, monitors for purchase completion (or timeout), and triggers game exit if the demo time limit is reached without a purchase. This module operates globally via singleton functions and state — it is not an Entity Component System component.
Usage example
-- Example: Trigger upsell screen if demo time exceeded
if GetTimePlaying() > TUNING.DEMO_TIME and not IsGamePurchased() then
ShowUpsellScreen(true)
end
-- Example: Handle closure of upsell screen
HandleUpsellClose()
Dependencies & tags
Components used: None identified
Tags: None identified
Properties
| Property | Type | Default Value | Description |
|---|---|---|---|
upsell_status | string or nil | nil | Global state: "SHOWING", "WAITING", or "QUITTING" while upsell UI is active, otherwise nil. |
waitingforpurchasetimeout | number | 0 | Accumulated time (in seconds) spent waiting for a purchase confirmation. |
DEMO_QUITTING | boolean | false | Global flag indicating whether the player is quitting due to demo expiration or failed purchase. |
Main functions
IsGamePurchased()
- Description: Checks whether the full game has been purchased by verifying presence of
"GAME"in the globalPurchasestable. - Parameters: None.
- Returns:
boolean—trueif"GAME"is found inPurchases, otherwisefalse.
UpdateGamePurchasedState(complete_callback)
- Description: Invokes the provided callback with the current purchase status.
- Parameters:
complete_callback(function ornil) — receives one boolean argument (trueif purchased). - Returns: Nothing.
UpsellShowing()
- Description: Returns whether the upsell screen is currently displayed.
- Parameters: None.
- Returns:
boolean—trueifupsell_status == "SHOWING".
WaitingForPurchaseState()
- Description: Returns whether the upsell screen is in the post-close waiting state, awaiting purchase confirmation.
- Parameters: None.
- Returns:
boolean—trueifupsell_status == "WAITING".
ShowUpsellScreen(shouldquit)
- Description: Displays the upsell UI to the user and pauses the game.
- Parameters:
shouldquit(boolean) — iftrue, setsupsellJSON fieldtimedouttotrue. - Returns: Nothing.
- Error states: No-op if
upsell_statusis already set.
CheckForUpsellTimeout(dt)
- Description: Tracks elapsed time while waiting for purchase confirmation; if over 30 seconds, triggers quit.
- Parameters:
dt(number) — delta time since last frame (seconds). - Returns: Nothing.
- Error states: Triggers quit if timeout threshold exceeded while in
"WAITING"state.
CheckDemoTimeout()
- Description: Checks if the demo time limit (
TUNING.DEMO_TIME) has been exceeded and shows the upsell screen if not yet purchased. - Parameters: None.
- Returns: Nothing.
- Error states: Does nothing if upsell is already showing or game is purchased.
HandleUpsellClose()
- Description: Handles post-close logic after user interacts with the upsell UI.
- Parameters: None.
- Returns: Nothing.
- Error states: May trigger quit if demo time expired and no purchase occurred; refreshes active UI screen upon completion.
Events & listeners
- Listens to: None identified
- Pushes:
"quit"— sent toThePlayerwhen demo expires or purchase fails after upsell timeout/closure.