The remaining editor strings and undo step names; component, field, enum, setting, diagnostic and Script API texts under schema.*, enum.*, setting.*, diag.* and api.*; the launcher, the in-game Settings View with a Language setting, the CLI and aego schema show --lang. Every documentation page has a .ru.md translation; the site has a full Russian tree with hreflang, a language switch and ru/llms.txt; aego docs check --lang ru. New doc.tutorial and doc.recipe icons. Fix: an animator restored by a rewind prepares its controller before the replayed step.
5.4 KiB
id, title
| id | title |
|---|---|
| data | Ассеты данных |
Ассеты данных
Ассет данных хранит числа и ссылки, которые настраивают игру без кода: характеристики врагов, веса добычи, настройки уровней.
Объявление типа
Зарегистрируйте структуру Go как тип данных в нативном модуле:
package native
import (
"aego/core/mathx"
"aego/sdk"
)
type EnemyStats struct {
Speed float32 `aego:"speed,min=0,max=10"`
Cooldown float32 `aego:"cooldown,min=0,max=5"`
Damage int64 `aego:"damage,min=0"`
Tint mathx.Color `aego:"tint"`
}
func registerData(r *sdk.Registry) {
sdk.DataType[EnemyStats](r, sdk.Name("mygame.EnemyStats"))
sdk.Live[EnemyStats](r, "speed")
}
Поля используют те же теги и подсказки, что и поля компонентов. Короткие имена типов (EnemyStats) должны быть уникальны во всех модулях, потому что скрипты называют типы данных по ним.
Ассеты и базы
.aedata хранит одну запись:
data version=1 type="mygame.EnemyStats" base=asset("…") {
speed=5
}
Запись начинается со значений типа по умолчанию, копирует свою базу, если она есть, и применяет собственные поля. Записываются только поля, которые отличаются от базы. База должна быть того же типа; цепочка, которая возвращается к самой себе или глубже 16, — ошибка.
В редакторе выберите ассет .aedata, чтобы редактировать его в Инспекторе. Поля, которые задаёт ассет, отмечены слева; щёлкните такое поле правой кнопкой, чтобы вернуть его к базе. «Сохранить» записывает файл и заново импортирует его.
Таблицы
.aetable хранит строки одного типа, у каждой уникальный id. Дважды щёлкните таблицу, чтобы открыть редактор таблиц. Он сортирует по столбцу (щёлкните его заголовок), фильтрует строки, редактирует ячейки на месте и применяет правку ко всем выбранным строкам, если редактируемая строка тоже выбрана. «Экспорт CSV» записывает <table>.csv рядом с таблицей; «Импорт CSV» читает его обратно. Столбцы — это id и каждое поле типа bool, число, строка, перечисление и ассет.
Скрипты
@export
var Stats AssetRef<EnemyStats>
@export
var Loot TableRef<LootEntry>
speed := Stats.Speed
copy := Stats.Copy()
if Loot.Has("goblin") {
entry := Loot.Row("goblin")
}
n := Loot.Len()
Поля читаются через ссылку, присваивать им нельзя. Copy() возвращает структуру, которой владеет скрипт. Пустая ссылка или отсутствующая строка останавливает скрипт с AES6004. Поля, у типа Go которых нет формы в скриптах, например строки и списки, скриптам не видны.
Go
package native
import "aego/sdk"
type EnemyStats struct {
Speed float32 `aego:"speed,min=0,max=10"`
}
type Enemy struct {
Stats sdk.DataRef[EnemyStats] `aego:"stats"`
}
func speedOf(ctx *sdk.Context, e *Enemy) float32 {
stats, err := sdk.Data(ctx, e.Stats)
if err != nil {
return 0
}
return stats.Speed
}
Поля sdk.DataRef[T] и sdk.TableRef[T] в компонентах показываются в Инспекторе как выбор ассета, и их можно передавать в скрипты и получать из них.
Настройка на лету
Пока игра идёт, поля неизменяемы, кроме отмеченных sdk.Live. Во время игры Инспектор позволяет менять живые поля ассета данных; изменение сразу применяется к идущей игре и к каждому ассету, основанному на этом, который сам не задаёт это поле. Когда игра останавливается, редактор спрашивает, сохранить ли изменения в ассетах. Таблицы и неживые поля во время игры доступны только для чтения.
Проверка
aego check, панель «Проблемы» и запуск игры сообщают об ассетах данных, которые не разбираются, называют неизвестный тип, имеют сломанную базу, значения вне диапазона своего поля или ссылки на отсутствующие ассеты.