> For the complete documentation index, see [llms.txt](https://wiki.playgama.com/playgama/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.playgama.com/playgama/bridge-sdk/api/cross-promo.md).

# Cross-Promo

{% hint style="info" %}
You are reading the documentation for Bridge SDK **v2**. If you need the obsolete v1 documentation, see [Documentation (v1)](https://wiki.playgama.com/playgama/bridge-sdk-v1).
{% endhint %}

Cross-promotion: show the player more games — either a static list you configure, or the platform's own catalog. Bridge ships a ready-made promo modal (`show()` / `hide()`) and a data API (`getGames()`) if you prefer to render your own UI.

## Configuration

Configure the module in the [config](/playgama/bridge-sdk/config.md) under the `crossPromo` key:

```json
{
    "crossPromo": {
        "title": "More games",   // optional modal title
        "source": "config",      // 'config' = static list below (default), 'platform' = platform SDK catalog
        "games": [               // used when source = 'config'
            { "url": "https://...", "icon": "https://...", "name": "Game A" }
        ]
    }
}
```

With `source: "platform"` the list comes from the platform SDK catalog on platforms that expose one (currently `yandex`); elsewhere it resolves to an empty list.

## Get Games

Returns the full games list from the configured source, normalized to a single shape. Resolves to an empty array when the source has no games or errors.

{% tabs %}
{% tab title="Plain JS" %}

```javascript
bridge.crossPromo.getGames()
    .then(games => {
        games.forEach(game => {
            console.log(game.name, game.url)
        })
    })
```

{% endtab %}

{% tab title="Unity" %}

```csharp
private void Start()
{
    Bridge.crossPromo.GetGames(OnGetGamesCompleted);
}

private void OnGetGamesCompleted(bool success, List<Dictionary<string, string>> games)
{
    if (success)
    {
        foreach (var game in games)
        {
            Debug.Log($"{game["name"]}: {game["url"]}");
        }
    }
}
```

{% endtab %}

{% tab title="Construct 3" %}
Call the `Cross Promo Get Games List` action, then handle the `On Cross Promo Get Games List Completed` trigger. Read the result with the `CrossPromoGamesCount` and `CrossPromoGamesPropertyValue(gameIndex, property)` expressions (`property` is a field name like `"name"`, `"url"`, `"iconUrl"`, `"coverUrl"`), or take everything at once with `CrossPromoGamesAsJSON`.

<details>

<summary>Copy This Example</summary>

```
{"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-clicked","objectClass":"Button"}],"actions":[{"id":"cross-promo-get-games-list","objectClass":"PlaygamaBridge"}]},{"eventType":"block","conditions":[{"id":"on-cross-promo-get-games-list-completed","objectClass":"PlaygamaBridge"}],"actions":[],"children":[{"eventType":"block","conditions":[{"id":"for","objectClass":"System","parameters":{"name":"\"games\"","start-index":"0","end-index":"PlaygamaBridge.CrossPromoGamesCount - 1"}}],"actions":[{"id":"log","objectClass":"Browser","parameters":{"type":"log","message":"PlaygamaBridge.CrossPromoGamesPropertyValue(loopindex(\"games\"), \"name\") & \": \" & PlaygamaBridge.CrossPromoGamesPropertyValue(loopindex(\"games\"), \"url\")"}}]}]}]}
```

</details>
{% endtab %}

{% tab title="GDevelop" %}
Call the `Cross Promo Get Games List` action, then handle the `On Get Games List Completed` condition. Read the result with the `PlaygamaBridge::CrossPromoGamesCount()` and `PlaygamaBridge::CrossPromoGamesPropertyValue(gameIndex, property)` expressions (`property` is a field name like `"name"`, `"url"`, `"iconUrl"`, `"coverUrl"`).

<details>

<summary>Copy This Example</summary>

```
{"000kind":"GDEVELOP_EventsAndInstructions_CLIPBOARD_KIND-jsBdHbLy912y8Rc","content":{"eventsList":[{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PanelSpriteButton::PanelSpriteButton::IsClicked"},"parameters":["Button",""]}],"actions":[{"type":{"value":"PlaygamaBridge::CrossPromoGetGamesList"},"parameters":["",""]}]},{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PlaygamaBridge::OnGetGamesListCompleted"},"parameters":["",""]}],"actions":[{"type":{"value":"SetNumberVariable"},"parameters":["CurrentIndex","=","0"]}],"events":[{"type":"BuiltinCommonInstructions::Repeat","repeatExpression":"PlaygamaBridge::CrossPromoGamesCount()","conditions":[],"actions":[],"events":[{"type":"BuiltinCommonInstructions::Standard","conditions":[],"actions":[{"type":{"value":"DebuggerTools::ConsoleLog"},"parameters":["PlaygamaBridge::CrossPromoGamesPropertyValue(CurrentIndex, \"name\") + \": \" + PlaygamaBridge::CrossPromoGamesPropertyValue(CurrentIndex, \"url\")","\"info\"",""]},{"type":{"value":"SetNumberVariable"},"parameters":["CurrentIndex","+","1"]}]}]}]}],"eventsCount":2,"actionsList":[],"actionsCount":0,"conditionsList":[],"conditionsCount":0}}
```

</details>
{% endtab %}

{% tab title="Godot" %}
{% tabs %}
{% tab title="Godot 3.x" %}

```gdscript
Bridge.cross_promo.get_games(funcref(self, "_on_get_games_completed"))

func _on_get_games_completed(success, games):
    if success:
        for game in games:
            print(game.name, " ", game.url)
```

{% endtab %}

{% tab title="Godot 4.x" %}

```gdscript
Bridge.cross_promo.get_games(Callable(self, "_on_get_games_completed"))

func _on_get_games_completed(success, games):
    if success:
        for game in games:
            print(game.name, " ", game.url)
```

{% endtab %}
{% endtabs %}
{% endtab %}

{% tab title="GameMaker" %}

```javascript
playgama_bridge_cross_promo_get_games()

// callback via Async Social Event
if async_load[? "type"] == "playgama_bridge_cross_promo_get_games_callback" {
    if async_load[? "success"] {
        var games = json_parse(async_load[? "data"])
        for (var i = 0; i < array_length(games); i += 1) {
            var game = games[i]
            // game.name, game.url
        }
    }
}
```

{% endtab %}

{% tab title="Defold" %}

```lua
local bridge = require("bridge.bridge")

function init(self)
    bridge.cross_promo.get_games(function (_, games)
        for _, game in ipairs(games) do
            print(game.name, game.url)
        end
    end)
end
```

{% endtab %}

{% tab title="Cocos Creator" %}

```javascript
bridge.crossPromo.getGames()
    .then(games => {
        games.forEach(game => {
            console.log(game.name, game.url)
        })
    })
```

{% endtab %}
{% endtabs %}

Each `Game` is normalized to:

```javascript
{
    id: '...',        // optional
    name: '...',      // optional
    url: 'https://...',
    iconUrl: '...',   // optional
    coverUrl: '...',  // optional
    payload: { ... }  // raw source object (platform SDK game / config entry)
}
```

## Show / Hide

Shows the built-in promo modal with a random selection of games (up to 4). The modal closes on the close button, on a click outside, and automatically when an interstitial or rewarded ad starts.

{% tabs %}
{% tab title="Plain JS" %}

```javascript
await bridge.crossPromo.show()   // opens the modal (no-op when there are no games)

bridge.crossPromo.isVisible      // boolean — is the modal currently open

bridge.crossPromo.hide()         // closes the modal
```

{% endtab %}

{% tab title="Unity" %}

```csharp
Bridge.crossPromo.Show();       // opens the modal (no-op when there are no games)

Bridge.crossPromo.isVisible;    // bool — is the modal currently open

Bridge.crossPromo.Hide();       // closes the modal
```

{% endtab %}

{% tab title="Construct 3" %}
Use the `Cross Promo Show` / `Cross Promo Hide` actions and the `Is Cross Promo Visible` condition.

<details>

<summary>Copy This Example</summary>

```
{"is-c3-clipboard-data":true,"type":"events","items":[{"eventType":"block","conditions":[{"id":"on-clicked","objectClass":"Button"}],"actions":[{"id":"cross-promo-show","objectClass":"PlaygamaBridge"}]},{"eventType":"block","conditions":[{"id":"is-cross-promo-visible","objectClass":"PlaygamaBridge"}],"actions":[{"type":"comment","text":"the modal is currently open"}]}]}
```

</details>
{% endtab %}

{% tab title="GDevelop" %}
Use the `Cross Promo Show` / `Cross Promo Hide` actions and the `Cross Promo Is Visible` condition.

<details>

<summary>Copy This Example</summary>

```
{"000kind":"GDEVELOP_EventsAndInstructions_CLIPBOARD_KIND-jsBdHbLy912y8Rc","content":{"eventsList":[{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PanelSpriteButton::PanelSpriteButton::IsClicked"},"parameters":["Button",""]}],"actions":[{"type":{"value":"PlaygamaBridge::CrossPromoShow"},"parameters":["",""]}]},{"type":"BuiltinCommonInstructions::Standard","conditions":[{"type":{"value":"PlaygamaBridge::CrossPromoIsVisible"},"parameters":["",""]}],"actions":[{"type":{"value":"DebuggerTools::ConsoleLog"},"parameters":["\"the modal is currently open\"","\"info\"",""]}]}],"eventsCount":2,"actionsList":[],"actionsCount":0,"conditionsList":[],"conditionsCount":0}}
```

</details>
{% endtab %}

{% tab title="Godot" %}

```gdscript
Bridge.cross_promo.show()        # opens the modal (no-op when there are no games)

Bridge.cross_promo.is_visible    # bool — is the modal currently open

Bridge.cross_promo.hide()        # closes the modal
```

{% endtab %}

{% tab title="GameMaker" %}

```javascript
playgama_bridge_cross_promo_show()       // opens the modal (no-op when there are no games)

playgama_bridge_cross_promo_is_visible() // 1 or 0 — is the modal currently open

playgama_bridge_cross_promo_hide()       // closes the modal
```

{% endtab %}

{% tab title="Defold" %}

```lua
local bridge = require("bridge.bridge")

bridge.cross_promo.show()        -- opens the modal (no-op when there are no games)

bridge.cross_promo.is_visible()  -- boolean — is the modal currently open

bridge.cross_promo.hide()        -- closes the modal
```

{% endtab %}

{% tab title="Cocos Creator" %}

```javascript
await bridge.crossPromo.show()   // opens the modal (no-op when there are no games)

bridge.crossPromo.isVisible      // boolean — is the modal currently open

bridge.crossPromo.hide()         // closes the modal
```

{% endtab %}
{% endtabs %}
