Godot 4 · GDScript
Валюта и покупки
Gamdato поставляется с экономикой: виртуальные валюты, которые игрок покупает за реальные деньги (через Stripe), и предметы, которые он приобретает, тратя эти валюты. Всё определяется в панели и используется из аддона.
Настройка панели
В панели вы определяете три вещи: валюты вашей игры (например, "gems"), паки пополнения (SKU с ценой в USD, который выдаёт X валюты через Stripe) и предметы для покупки (SKU с его стоимостью в валюте и правилами выдачи).
Сохраните SKU каждого пака и предмета: это идентификаторы, которые вы передаёте в buy_pack() и purchase().
Чтение балансов
Запросите балансы игрока и каталог валют. Результат приходит через сигнал balances_loaded.
Gamdato.balances_loaded.connect(_on_balances)
Gamdato.get_balances()
func _on_balances(balances: Array, currencies: Array) -> void:
for b in balances:
print("%s: %d" % [b.currency_id, b.balance])# balances: Array, each:
{
"currency_id": String,
"balance": int
}
# currencies: Array, the catalog you defined in the panel:
{
"id": String,
"code": String,
"display_name": String,
"icon_url": String,
"is_active": bool
}
# "code" is the currency code you pass to get_currency_leaderboard().Покупка валюты (Stripe)
Начните покупку пака пополнения. Аддон открывает Stripe Checkout в системном браузере; по возвращении балансы обновляются на стороне сервера. Сигнал topup_started подтверждает, что URL был открыт.
Gamdato.topup_started.connect(_on_topup)
Gamdato.buy_pack("premium_pack")
func _on_topup(ok: bool, url: String, error_code: String) -> void:
if ok: print("Checkout opened: %s" % url)
else: print("Error: %s" % error_code)Трата валюты
Потратьте валюту игрока на предмет. Сервер проверяет баланс и применяет правила выдачи атомарно. Результат приходит через purchase_completed.
Gamdato.purchase_completed.connect(_on_purchase)
Gamdato.purchase("sword_skin")
func _on_purchase(ok: bool, sku: String, result: Dictionary, error_code: String) -> void:
if ok: print("Bought %s. Balances: %s" % [sku, result.balances])
else: print("Failed: %s" % error_code)error_code может быть insufficient_funds, already_owned или item_not_found. Передайте idempotency_key, чтобы избежать двойного списания при повторе.
Инвентарь игрока
Список предметов, которыми владеет игрок. Полезно для разблокировки контента при запуске игры. Приходит через inventory_loaded.
Gamdato.inventory_loaded.connect(_on_inventory)
Gamdato.get_inventory()
func _on_inventory(items: Array) -> void:
for it in items:
print("Owns: %s (%s)" % [it.item_id, it.source])# items: Array, each owned item:
{
"item_id": String,
"source": String,
"acquired_at": String,
"metadata": Dictionary
}
# Rows also include internal ids (id, player_id, game_id).История транзакций
Список последних движений валюты игрока (начисления, покупки, пополнения), сначала самые новые. Приходит через ledger_loaded.
Gamdato.ledger_loaded.connect(_on_ledger)
Gamdato.get_ledger() # or get_ledger(50, 0)
func _on_ledger(entries: Array) -> void:
for e in entries:
print("%s %+d -> %d" % [e.op_type, e.delta, e.balance_after])# entries: Array, newest first:
{
"id": String,
"currency_id": String,
"delta": int,
"balance_after": int,
"op_type": String,
"created_at": String
}
# Rows also include internal ids/metadata (player_id, game_id, ref_kind, ref_value, idempotency_key, metadata).Таблица лидеров по валюте
Рейтинг игроков по балансу валюты (должен быть включён для этой валюты в панели). Передайте код валюты. Приходит через currency_leaderboard_loaded.
Gamdato.currency_leaderboard_loaded.connect(_on_currency_lb)
Gamdato.get_currency_leaderboard("gems")
func _on_currency_lb(code: String, entries: Array) -> void:
for row in entries:
print("#%d %s %d" % [row.rank, row.player_name, row.balance])# entries: Array, ordered by balance, highest first:
{
"rank": int,
"player_id": String,
"player_name": String,
"balance": int
}Начисление валюты (награды в коде)
Выдайте игроку валюту по причине, которую вы определили в панели (выплата за квест, бонус за повышение уровня...). Передайте ключ причины. Приходит через grant_completed.
Gamdato.grant_completed.connect(_on_grant)
Gamdato.grant_currency("quest_reward")
func _on_grant(ok: bool, reason_key: String, result: Dictionary, error_code: String) -> void:
if ok: print("Granted! Balances: %s" % result.get("balances"))
else: print("Failed: %s" % error_code)Начисления определяются в панели по ключу причины и могут иметь задержки (cooldown) или лимиты. Это для внутриигровых наград, а не для покупок за реальные деньги (для них используйте buy_pack).