Statements

Creating and managing statements

Statements are the core content items – the questions, prompts, and challenges that users see in the apps. Each statement follows a schema that defines its text structure.

Text parts

A statement’s text is broken into named parts defined by its schema type. For example, a “Would You Rather” statement might have:

  • title – “Would you rather”
  • text1 – “eat a spider”
  • text2 – “drink spoiled milk”

Each part is localized – it has text for every language. The parts get combined with the schema’s join string (usually a space) to form the full displayed text.

Modes

Statements have a mode field that categorizes the gameplay type. Common modes include:

  • classic – Standard gameplay
  • adult – 18+ content
  • truth – Truth-type prompts (for Truth or Dare)
  • dare – Dare-type challenges

Modes are free-form strings – the available values depend on what your app needs.

Tags

Tags are free-form labels you can attach to any statement. They’re useful for organizing content beyond what modes and categories provide. Multiple tags per statement are supported.

Visibility flags

Each statement has three visibility controls:

  • Active/Inactive – Inactive statements are excluded from snapshots entirely
  • Hidden on iOS – Statement won’t appear in iOS app categories
  • Hidden on Android – Statement won’t appear in Android app categories

Metadata

Statements carry three optional JSON metadata blocks:

  • Designer metadata – Notes, design references, or visual instructions
  • Content metadata – Editorial notes, content source, review status
  • Game metadata – Game-specific config like point values, difficulty, timing

The JSON structure for each metadata block is defined per-app in the app’s metadata schema settings.

Filtering and searching

The Statements tab has two search modes:

Quick filters – Use the filter bar at the top to narrow by schema type, mode, tags, active status, or AI-generated flag. Combine multiple filters with AND logic.

Text search – Search across full text content. The search checks the pre-rendered fullText field which combines all parts.

Semantic search – Enter a natural language query to find conceptually similar statements using vector embeddings. Adjust the similarity threshold (default 0.3) to control how strict the matching is.

Bulk selection and export

Select multiple statements using the checkboxes on each row. With statements selected, you can:

  • Export to Google Sheets – Send selected statements to a new Google Sheet for collaborative editing
  • Translate selected – Jump to the Translations tab with the selected statement IDs pre-filled
  • Bulk actions – Change visibility, mode, or other properties across multiple statements at once

How it works under the hood

Statements belong to a schema type, not to an app. Multiple apps that share the same schema type access the same pool of statements. For example, “Truth or Dare” and “Truth or Dare Lite” can both use statements from the same schema – categories determine which subset each app includes.

Vector embeddings are generated for each statement and stored via pgvector. These power semantic search in the admin UI and semantic filter conditions on categories.

Statements don’t appear in apps until they’re included in a published snapshot. The chain is: statement exists → category filter matches it → snapshot captures it → version mapping makes it available. Editing a statement after a snapshot is published does not affect that snapshot – snapshots are immutable.