ci / release (push) Successful in 5m5s
ci-platforms / build (amd64, windows, windows-2022) (push) Skipped
ci-platforms / build (arm64, darwin, macos-15) (push) Skipped
ci-platforms / build (amd64, darwin, macos-15-intel) (push) Skipped
ci / checks (push) Successful in 4m41s
ci / build (amd64, linux, ubuntu-24.04) (push) Successful in 7m14s
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.
106 lines
5.4 KiB
Markdown
106 lines
5.4 KiB
Markdown
---
|
|
id: data
|
|
title: Ассеты данных
|
|
---
|
|
# Ассеты данных
|
|
|
|
Ассет данных хранит числа и ссылки, которые настраивают игру без кода: характеристики врагов, веса добычи, настройки уровней.
|
|
|
|
## Объявление типа
|
|
|
|
Зарегистрируйте структуру Go как тип данных в нативном модуле:
|
|
|
|
```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
|
|
|
|
```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`, панель «Проблемы» и запуск игры сообщают об ассетах данных, которые не разбираются, называют неизвестный тип, имеют сломанную базу, значения вне диапазона своего поля или ссылки на отсутствующие ассеты.
|