> ## Documentation Index
> Fetch the complete documentation index at: https://doc.playsmart.api.dolly.gg/llms.txt
> Use this file to discover all available pages before exploring further.

# Game catalog and app-level configuration in PlaySmart

> Learn how PlaySmart organizes games, what configuration fields control each game's behavior, and how app-level settings affect all players.

PlaySmart uses two levels of configuration: **app-level settings** that apply globally to every player and game, and **per-game settings** that control individual game behavior. Understanding both levels helps you know which knobs to turn when you want to change monetization, maintenance windows, or gameplay reward rules.

## App-level settings

PlaySmart's global app settings act as a control panel for the entire platform. These fields are returned by `GET /v1/app-settings` and affect all players and games:

| Field     | Type    | Description                                                                                                                                      |
| --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `is_live` | Boolean | Global kill-switch. When `false`, all games return a maintenance state and economic actions (coin awards, conversions, withdrawals) are blocked. |

<Warning>
  Setting `is_live` to `false` affects every player and every game simultaneously. Use this for platform-wide maintenance only.
</Warning>

Additional settings are managed by your deployment configuration and the active conversion setting, including:

* `minimum_withdrawal_amount` — minimum USD balance required to request a withdrawal
* `withdraw_cooldown_hours` — hours a player must wait between withdrawal requests
* `conversion_interval_hours` — how often the coin-to-USD conversion job runs per user
* `ads_enabled` — global flag to enable or disable ad serving across all games

## Per-game configuration

Each game has its own configuration controlling reward behaviour and availability.

### Game fields

| Field            | Type    | Description                                                                                               |
| ---------------- | ------- | --------------------------------------------------------------------------------------------------------- |
| `name`           | String  | Display name shown in the parent app's game list.                                                         |
| `package_name`   | String  | Android package name (e.g. `com.example.knifeking`). Unique across all games; used for install detection. |
| `play_store_url` | String  | Full Play Store URL shown when the game is not installed.                                                 |
| `thumbnail_url`  | String  | Image URL shown in the parent app game list.                                                              |
| `game_mode`      | String  | One of `level_based`, `endless`, or `hybrid`. See [Game modes](#game-modes) below.                        |
| `coins_enabled`  | Boolean | When `false`, the game is playable but earns no coins. Useful for discovery or testing.                   |
| `ads_enabled`    | Boolean | When `false`, no ads are served in this game, independent of the global flag.                             |
| `is_active`      | Boolean | When `false`, the game is hidden client-side and stops earning coins.                                     |

### Reward configuration fields (`games_configs`)

Each game has exactly one linked config document:

| Field                         | Type    | Description                                                                         |
| ----------------------------- | ------- | ----------------------------------------------------------------------------------- |
| `reward_mode`                 | String  | `fixed` (constant coin amount) or `random_range` (random draw between min and max). |
| `reward_fixed_amount`         | Number  | Coins awarded per event when `reward_mode` is `fixed`.                              |
| `reward_min_amount`           | Number  | Lower bound of the random draw when `reward_mode` is `random_range`.                |
| `reward_max_amount`           | Number  | Upper bound of the random draw when `reward_mode` is `random_range`.                |
| `level_completion_enabled`    | Boolean | Enables coin rewards on `level_complete` trigger.                                   |
| `event_trigger_enabled`       | Boolean | Enables coin rewards on `event_trigger` trigger. Disabled by default.               |
| `event_trigger_threshold`     | Number  | Number of custom events required to fire an `event_trigger` reward. Minimum 1.      |
| `level_completion_multiplier` | Number  | Multiplier on `level_complete` rewards. Default `1.0`.                              |
| `event_trigger_multiplier`    | Number  | Multiplier on `event_trigger` rewards. Default `0.5`.                               |

## Game modes

The `game_mode` field accepts one of three values that describe the gameplay structure:

<CardGroup cols={3}>
  <Card title="level_based" icon="layer-group">
    Players progress through discrete levels. Coin rewards are most naturally tied to `LevelCompleted` events.
  </Card>

  <Card title="endless" icon="infinity">
    There are no distinct levels — play continues until the player fails. The `event_trigger` path suits this mode.
  </Card>

  <Card title="hybrid" icon="shuffle">
    The game has both level progression and endless/score-based elements. Both trigger paths can be enabled simultaneously.
  </Card>
</CardGroup>

## Maintenance mode

A game can enter maintenance state from two independent sources:

1. **App-level**: `is_live` is `false` on the app settings document — every game returns `maintenance: true`.
2. **Game-level**: `is_active` is `false` on the game document — only that specific game returns `maintenance: true`.

When a game is in maintenance state, the client should display a maintenance screen and prevent the player from interacting with economy features for that game.

## User game progress

PlaySmart automatically tracks per-player, per-game statistics server-side. You do not need to manage these fields yourself — they are updated as events are ingested.

| Field                   | Description                                                                 |
| ----------------------- | --------------------------------------------------------------------------- |
| `is_installed`          | Whether the player has the game installed.                                  |
| `first_played_at`       | Timestamp of the player's first session.                                    |
| `last_played_at`        | Timestamp of the player's most recent session.                              |
| `total_sessions`        | Cumulative session count.                                                   |
| `current_level`         | The player's current level (relevant for `level_based` and `hybrid` games). |
| `total_games_played`    | Total number of individual game rounds played.                              |
| `total_games_completed` | Total number of game rounds completed (not just started).                   |
| `total_coins_earned`    | Lifetime coins earned in this game.                                         |
| `daily_coins_earned`    | Coins earned today (resets daily).                                          |
| `high_score`            | The player's best score.                                                    |
| `last_score`            | The player's score in their most recent round.                              |

<Info>
  Each `user_game_progress` document is unique per `(user_id, game_id)` pair. PlaySmart creates it automatically on the player's first interaction with a game.
</Info>
