Цю сторінку ще не перекладено — показано англійську версію.
Inventory
Один набір рядків із власником, яким користуються постріли, випадання, здібності й переміщення. Стоси змінюються інкрементом, а ліміт на власника поводиться на межі так, як оберете ви.
Коли це потрібно
- Гравці володіють речами, і кожна така річ — рядок інвентарю (inventory) з власником. Його читають за власником, кількість рядків обмежено для кожного власника, а поведінку при переповненні оголошують явно, а не беруть за замовчуванням.
- Кількість накопичується: стос (stack) змінюється інкрементом. Інкремент несе ключ ідемпотентності, тож повторне списання не спише двічі.
- Інші модулі витрачають з одного набору: постріли списують набої, випадання дає здобич, а покупки з’являються рядками, прив’язаними до права володіння (entitlement).
- Не знадобиться, якщо цим числом не можна володіти. HP, XP і перезаряджання належать до характеристик (stat).
Хто що робить
| Актор | Що робить на цій сторінці |
|---|---|
player | читає власні запаси й витрачає з них |
backend-service | видає, збільшує й відкликає від імені гравця, указуючи, за якого гравця діє |
Коротко
fn: видати набої, перемістити предмет у слот спорядження primary і перед витратою перевірити, чи вистачає ресурсу// fn authority — a cloud function, or a dedicated server holding a host key
var bag = await player.Inventory.Container("bag");
var equipment = await player.Inventory.Container("equipment");
await player.Inventory.Grant("ammo.shell", count: 20);
await bag.Move(itemId, to: equipment, slot: "primary");
if (await player.Inventory.CanAfford("ammo.shell", 1))
await player.Inventory.Consume("ammo.shell", 1);// fn authority — a cloud function, or a dedicated server holding a host key
const bag = await player.inventory.container('bag');
const equipment = await player.inventory.container('equipment');
await player.inventory.grant('ammo.shell', { count: 20 });
await bag.move(itemId, { to: equipment, slot: 'primary' });
if (await player.inventory.canAfford('ammo.shell', 1))
await player.inventory.consume('ammo.shell', 1);# fn authority — a cloud function, or a dedicated server holding a host key
bag = await player.inventory.container("bag")
equipment = await player.inventory.container("equipment")
await player.inventory.grant("ammo.shell", count=20)
await bag.move(item_id, to=equipment, slot="primary")
if await player.inventory.can_afford("ammo.shell", 1):
await player.inventory.consume("ammo.shell", 1)Як оголошувати через атрибути в Go, поки не вирішено (O-1). Приклади з’являться, коли оберуть спосіб запису.
// fn authority — a cloud function, or a dedicated server holding a host key
Client->Commerce->Entitlements->Grant(FPSIdempotencyKey(GrantId), PlayerId, PSKeys::Item::AmmoShell);
// spending is an instance act on the entitlement you hold
Entitlement->Spend(FPSIdempotencyKey(SpendId), /*Amount*/ 1,
TPSOnResult<void>::CreateLambda([](const TPSResult<void>& Result)
{
// short on the item is a declared refusal, not a silent no-op
if (Result.IsRefused()) { DeclineReload(Result.Refusal()); }
}));
// co_await support ships later: a built-in SDK coroutine wrapper that respects Unreal's GC and threading.// fn authority — a cloud function, or a dedicated server holding a host key
var bag = await player.Inventory.Container("bag");
var equipment = await player.Inventory.Container("equipment");
await player.Inventory.Grant("ammo.shell", count: 20);
await bag.Move(itemId, to: equipment, slot: "primary");
if (await player.Inventory.CanAfford("ammo.shell", 1))
await player.Inventory.Consume("ammo.shell", 1);Сесія гравця виконує читання, переміщення й перевірку ресурсу тими самими викликами. А от видавати, витрачати й знищувати вона не може: платформа відхиляє такі виклики як заборонені й називає право, якого бракує викликачеві, — незалежно від того, з якого біндингу надійшов виклик.
Модель
Власних понять інвентар не вводить. Це пресет — форма, зібрана з того, що вже дає сутність. Тому все, що описано нижче, — оголошення сутності, а не механізми цієї сторінки.
| Оголошення | Що це |
|---|---|
| тип із власником | запис про володіння належить власникові, а вибірка за власником — це власна операція сутності (entity) |
ref на предмет каталогу | посилання зберігає id предмета, а не його key, тож ключ можна безпечно перейменувати. Саме визначення предмета живе в модулі Catalog & Commerce |
| аспект стосу з інкрементом | стос змінюється на дельту, а не перезаписом прочитаного значення (див. нижче) |
| ліміт на власника з поведінкою на межі | один із трьох варіантів, і типового немає: refuse · redirect в оголошений кошик власника · discard with event |
Передавайте ключ ідемпотентності з кожним інкрементом
Інкремент не ідемпотентний: два інкременти — це два інкременти. Без ключа ідемпотентності повторне списання спише двічі. Щоб дізнатися результат, прочитайте потрібний запис за його адресою.
Що справджується для кожного запису про володіння.
| Завжди | Що це |
|---|---|
у ліміту немає типового значення | три відповіді на повну сумку — це три різні гри. Відмова лишає здобич лежати перед гравцем. Перенаправлення — це пошта або переповнений склад. Відкидання — тиха втрата, прийнятна лише тому, що її оголошено і її видно. Жоден варіант не підходить усім трьом іграм, тому вибір робить оголошення |
власник незмінний | правкою поля нічого з рук у руки не переходить: запис переходить як відкликання плюс нова видача з оголошеним джерелом, і обидва факти лишаються в історії |
передача між двома гравцями | — це інша обіцянка: вона потребує ескроу й захисту від шахрайства і в цю версію не входить |
рядок | відображає право володіння, а не є його другим джерелом: куплене живе в модулі Catalog & Commerce, а рядок тут лише його представляє |
Помилки
- Екземпляра не існує або його приховує предикат: в обох випадках відповідь not found, тож відмова ніколи не видає, що щось існує, але належить не вам.
- Поле, не оголошене в аспекті (зокрема вкладене), і обов’язкове поле без значення — це відмови валідації, у яких названо поле.
- Версія не збіглася — це невиконана передумова; перечитайте запис і повторіть.
- Запис від імені гравця, у якому гравця не вказано, — це відмова валідації, а не тихий запис від чужого імені.
- Немає дозволу на читання чи запис — відповідь forbidden, причому читання й запис розрізняються.
Обмеження
Конкретні числа з’являться в розділі про ліміти платформи, а що відбувається на кожній межі, визначено вже зараз.
- Екземпляри на власника: за оголошеним вище правилом; типового варіанта немає.
- Розмір збереженого екземпляра: запис відхиляють як конфлікт, і у відмові названо поле-порушника та виміряний розмір. До межі доходять поступово, накопиченням, тож наближення до неї видно ще до запису, який не пройде.
- Частота змін одного екземпляра: відмова через обмеження частоти з указаним терміном.
- Розмір сторінки вибірки (selection): сторінку обрізають до ліміту, а прапорець „є ще“ лишається піднятим. Повертати менше без цього прапорця заборонено.