Files

5.6 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" {
  speed=5
}

Запись начинается со значений типа по умолчанию, копирует свою базу, если она есть, и применяет собственные поля. Записываются только поля, которые отличаются от базы. Для наследования добавьте атрибут base с настоящим AssetID другой записи: многоточие или путь к файлу не являются допустимой ссылкой. База должна быть того же типа; цепочка, которая возвращается к самой себе или глубже 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, панель «Проблемы» и запуск игры сообщают об ассетах данных, которые не разбираются, называют неизвестный тип, имеют сломанную базу, значения вне диапазона своего поля или ссылки на отсутствующие ассеты.