C#: сборка, свойства и объекты движка
Настройте проект C#, выберите правильный класс и различайте память .NET и жизнь Entity.
Требования к проекту
Поставка Reckfell включает .NET 10 и Reckfell.NET.Sdk/1.0.0. Создавайте C# solution средствами редактора; в каталоге проекта появится .csproj. Для ручной сборки запускайте поставляемый dotnet.exe build из этого каталога с настроенным локальным NuGet-источником. Случайный системный SDK или другой пакет не заменяет SDK движка.
После изменения кода выполняйте сборку; сохранение .cs не гарантирует, что игра использует новый код. Ошибки смотрите в панели сборки, затем в Output и отладчике. Не запускайте старую успешную сборку как доказательство работы новых изменений.
Скрипт и базовый класс
Имя прикрепляемого класса совпадает с файлом. Класс объявляется partial, наследует Entity или подходящий специализированный класс. Для CharacterBody3D выбирайте наследование от CharacterBody3D, если нужны Velocity и MoveAndSlide(). У скрипта Entity3D этих методов нет.
Для конструктора, используемого движком, не требуйте собственных аргументов. Дочерние Entity ищите в _Ready(), а не в инициализаторе поля или конструкторе. Для соединений, которые должны переживать удаление и повторное добавление в дерево, используйте согласованную пару _EnterTree() / _ExitTree().
Имена C# API
В примерах используются точные идентификаторы C#: GetEntity<T>(), AddChild(), QueueFree(), _PhysicsProcess(double delta) и ReckfellApi.Print(). В справочнике ищите эти имена, включая тип и перегрузку. Строки путей и имена Input Map чувствительны к написанию.
[Export] открывает поддерживаемое поле или свойство в инспекторе. Сохранённые значения документа могут перекрывать значения по умолчанию в коде. Статическое или доступное только для чтения свойство не становится обычным редактируемым полем от одного атрибута.
Удаление и ссылки
Entity имеет нативный объект и C#-обёртку. entity != null не доказывает, что нативный объект ещё существует. Для ссылки, которая могла пережить удаление, проверяйте ReckfellObject.IsInstanceValid(entity); перед повторной запланированной операцией учитывайте IsQueuedForDeletion().
QueueFree() удаляет Entity вместе с детьми отложенно. RemoveChild() только отсоединяет объект: ответственность за его дальнейшую жизнь остаётся у вашего кода. Сборщик мусора .NET не заменяет удаление неиспользуемой Entity. Ресурсы RefCounted имеют другую модель времени жизни; не переносите на них правила дерева автоматически.
После await и в потоках
После await уровень или объект может быть уже удалён. Проверяйте, актуальна ли операция и действительны ли её получатели. Не меняйте дерево игры из фоновой задачи: верните результат на главный поток и проверьте, что он ещё нужен.
Для столкновений используйте _PhysicsProcess(), для обычного кадрового поведения — _Process(). delta передаётся в секундах. Сигнатура с double не означает, что все векторы используют double: обычные Vector2 и Vector3 этой сборки используют float.
Рабочие примеры: вращение, персонаж, сигналы, сохранение.