Цю сторінку ще не перекладено — показано англійську версію.
Схема в коді
Оголосіть модель у коді, надішліть її на платформу й отримайте типи назад. Так зі схемою працює розробник: адмін-панель і код описують одну й ту саму модель, а кодогенерація замикає коло для кожного рушія.
Коли це потрібно
- Модель даних має жити в коді й проходити рев’ю як код: оголосили,
schema diff,schema push. - Типи в рушії ніколи не повинні розходитися з розгорнутою моделлю:
schema codegenзаново генерує Unreal C++ і Unity C#. - Несумісну зміну треба прочитати й за потреби скасувати, перш ніж вона виконається: запропонувати → спланувати → застосувати.
- Той самий набір (
Stat,Interactable) потрібен у кількох проєктах: оголосіть його один раз як пресет. - Не потрібно, якщо оператор лише підправляє значення в адмін-панелі. Зміну моделі, зроблену там, diff однаково поверне в код.
Хто що робить
| Актор | Що робить на цій сторінці |
|---|---|
schema-author | оголошує в коді сутності, частини й переліки, порівнює їх із розгорнутою моделлю та надсилає |
operator | переглядає огляд у панелі, пропонує й застосовує міграції |
ci | конвеєр збирання з ключем backend-service: після злиття надсилає схему (schema), а потім заново генерує типи для рушіїв |
Коротко
Item із вбудованою частиною Stats і переліком — усе йде на платформу однією схемою[Entity("item")]
public class Item
{
public string Name = "";
public Rarity Rarity; // an enum declared the same way
public Stats Stats = new(); // a part — embedded, no lifecycle of its own
}
[Part("stats")]
public class Stats { public int Power; public int Weight; }@Entity('item')
export class Item {
name = '';
rarity!: Rarity; // an enum declared the same way
stats = new Stats(); // a part — embedded, no lifecycle of its own
}
@Part('stats')
export class Stats { power = 0; weight = 0; }@entity("item")
class Item:
name: str = ""
rarity: Rarity # an enum declared the same way
stats: Stats = Stats() # a part — embedded, no lifecycle of its own
@part("stats")
class Stats:
power: int = 0
weight: int = 0Як оголошувати через атрибути в Go, поки не вирішено (O-1). Приклади з’являться, коли оберуть спосіб запису.
USTRUCT(PSPart = "stats")
struct FItemStats
{
GENERATED_BODY()
UPROPERTY() int32 Power;
UPROPERTY() int32 Weight;
};
UCLASS(PSEntity = "item")
class UItem : public UObject
{
GENERATED_BODY()
UPROPERTY() FString Name;
UPROPERTY() EPSRarity Rarity; // an enum declared the same way
UPROPERTY() FItemStats Stats; // a part — embedded, no lifecycle of its own
};
// declarations compile into the same pushed model — playserv push from the UE project or CI[Entity("item")]
public class Item
{
public string Name = "";
public Rarity Rarity; // an enum declared the same way
public Stats Stats = new(); // a part — embedded, no lifecycle of its own
}
[Part("stats")]
public class Stats { public int Power; public int Weight; }playserv schema diff # local declarations vs deployed schema
playserv schema push # with a revision precondition — no blind overwrites
playserv schema codegen # regenerate Unreal C++ / Unity C# types
Надсилання — окремий крок
Коли ви зберігаєте файл, нічого не завантажується. Оголошення (declaration) потрапляє в розгорнуту модель, лише коли запускається playserv push (або schema push) — на вашій машині чи в CI. Разом із ним іде ревізія, відносно якої рахували diff. Правка в панелі з’явиться в schema diff як розбіжність. Хоч би в який бік ви переносили зміну, це завжди команда, яку ви запускаєте самі.
Модель
З чого складається оголошення.
| Містить | Що це |
|---|---|
key | стабільне ім’я, за яким до оголошення звертаються. Перейменування в коді так і лишається перейменуванням, а не видаленням із повторним створенням |
kind | сутність (entity), частина або перелік, оголошені в коді |
режим володіння | seed — код створює запис, якщо його немає, а повторне надсилання значень не чіпає, тож далі ними розпоряджається адмін-консоль. Або managed — запис завжди належить коду: кожне надсилання приводить значення до оголошених, а правки з адмін-консолі платформа відхиляє, щоб вони не застосувалися й не зникли під час наступного надсилання |
preset | необов’язково: набір для повторного використання — пресет сутності, наприклад stats або world-objects. Його оголошують один раз і застосовують як тип. Нового виду оголошень він не додає |
Що гарантує надсилання.
| Завжди | Що це |
|---|---|
зіставлення | за ключем, а не за символом: якщо перейменувати символ і надіслати схему знову, запис лишиться один, а не два |
звіт | показує, що саме зміниться, ще до застосування, а після — що було перезаписано |
походження | розрізняється: запис, який створило надсилання з коду, можна відрізнити від створеного іншим шляхом |
ревізія | іде разом із надсиланням, а саме надсилання застосовується повністю або не застосовується зовсім |
Що гарантує кодогенерація.
| Завжди | Що це |
|---|---|
повторна генерація | відбувається після кожного надсилання, а згенеровані типи ніколи не правлять вручну: якщо згенерувати їх наново й порівняти, змін не буде |
імена | ідуть за оголошенням, хоч би де його написали: поле Rarity в Item стає UPSItem::Rarity в Unreal і Item.Rarity в Unity |
два напрямки | не розходяться: усе, що оголошено в коді, з’являється в панелі, а все, що оператор створив у панелі, чисто порівнюється з кодом. Тому schema diff показує кожну відмінність |
Що гарантує міграція.
| Завжди | Що це |
|---|---|
коли вона потрібна | коли змінюється оголошення збережуваних даних і ця зміна переписує наявні значення |
що вона оголошує | версію, попередній перегляд, упорядковане застосування, відкат у разі збою та видимий результат після завершення |
співіснування | поки працюють дві версії даних, операції читання й запису ог олошують, які версії вони приймають. Середовище виконання ніколи не виводить сумісність з імен полів |
Помилки
- Той, хто викликає без потрібної ролі, отримує
forbidden, а розгорнута модель лишається недоторканою: відмова ніколи не буває частковим надсиланням. Це інша відмова, ніж застаріла ревізія: та повертаєprecondition_failedі означає, що diff рахували для схеми, яка відтоді змінилася. Порівняйте ще раз і надішліть знову. - Значення поза оголошеною межею платформа відхиляє під час запису й ніколи не обрізає до межі. Так само з рядком, довшим за оголошену довжину. Обрізання дало б значення, яке коректне, але хибне.
- Недійсну послідовність UTF-8 платформа відхиляє під час запису, а не виправляє.
- Несумісну зміну збережуваних даних без оголошеної міграції опублікувати взагалі неможливо.
Обмеження
Обмеження, що випливають з оголошень, платформа перевіряє ще на етапі оголошення — під час розгортання чи публікації, а не при першому використанні, якщо під час роботи симп том не був би схожий на відмову. Конкретні числа з’являться разом із розділом про ліміти платформи.