Files
open-wc/docs/GODOT_BEST_PRACTICES.md
T

9.0 KiB
Raw Blame History

Godot Best Practices for OpenWC

Статус

Это нормативные правила применения Godot в OpenWC. Они дополняют общую архитектуру и основаны на официальных Godot practices с учётом большого streaming world, native parsers и встроенного Editor tooling.

Nodes только на границах

  • Domain, packet codecs, validators, coordinate math, build graph и canonical content не должны быть Nodes.
  • Node/Control используются для lifecycle, scene composition, input, rendering/audio presentation и Editor UI.
  • Большой объём однородных данных хранится в typed objects/packed arrays/resources, а не в тысячах служебных Nodes.
  • Scene не ищет глобально dependency по имени; parent composition передаёт contract/reference явно.

Scene organization

  • Каждая scene имеет одну ответственность и может запускаться в isolation с test doubles.
  • Parent-child означает ownership: удаление parent логично удаляет child. Иначе системы являются siblings/services.
  • Scene наружу публикует небольшой API/signals, а внутренние NodePaths не становятся публичным контрактом.
  • Runtime, render sandbox, preview и capture scenes собираются из общих presenters/services.
  • Generated world preview не сохраняется как authoring source.

Dependency injection и signals

  • Dependencies передаются composition root, initializer или exported interface reference.
  • Signals используются для notification; commands/intents вызываются через явные методы/bus contracts.
  • Signal connections снимаются симметрично при unload/plugin disable.
  • Не использовать SceneTree groups как скрытый service locator для core architecture.

Autoload policy

Autoload разрешён только для действительно process-wide lifecycle:

  • composition/bootstrap coordinator;
  • глобальная immutable build/version information;
  • crash/diagnostic sink, если ему нужен process lifetime.

Gameplay state, network session, renderer world, editor session, caches конкретного проекта и audio emitters не должны становиться неявными глобальными managers. Они создаются/освобождаются владельцем режима.

Resources and data

  • Resource подходит для immutable/imported descriptors и editor-inspectable configuration.
  • Runtime mutable authoritative state не хранится в shared Resource, который может быть случайно разделён сценами.
  • Resource schema имеет version и migration, если сохраняется пользователем.
  • Original extracted corpus и bulk caches не следует заставлять Godot массово импортировать без необходимости; применять .gdignore, custom import staging или native repository.
  • Importer проверяет malformed input и записывает dependency/profile metadata.

Background work

  • Blocking load() не используется в frame-critical streaming path; применяются threaded load/jobs.
  • Worker выполняет file I/O, parsing, decompression, grouping и pure data generation.
  • SceneTree mutation, Node attach и большинство GPU/RID finalization выполняются main thread budget.
  • Один Resource не модифицируется несколькими workers.
  • GDScript container resize/mutation между threads защищается mutex или заменяется message passing.
  • Все worker tasks ожидаются/очищаются; session cancellation не оставляет orphan work.

Rendering performance

  • Сначала измерять SceneTree/CPU/GPU bottleneck, затем переходить к RenderingServer.
  • Repeated static M2 группировать spatial MultiMesh cells; один MultiMesh на весь мир ухудшает culling.
  • Large transform buffers готовить линейно/в native code и отправлять батчем.
  • Visibility ranges/HLOD, occlusion и automatic mesh LOD использовать совместно по профилю.
  • Unique materials/textures минимизировать; descriptor/resource counts являются budget metric.
  • RenderingServer RIDs имеют явного владельца и освобождаются в deterministic shutdown test.
  • Shader/material profiles разделяют Blizzlike и Enhanced; runtime не компилирует тяжёлые варианты при пересечении ADT boundary.

EditorPlugin lifecycle

  • Любая регистрация в _enter_tree() имеет соответствующее удаление в _exit_tree().
  • Docks, inspectors, importers, gizmos, debugger plugins, signals и jobs снимаются при disable/reload.
  • Editor UI не пишет файлы/SQL напрямую — только создаёт application commands.
  • Mutation интегрирована с EditorUndoRedoManager или общей command history.
  • Preview nodes считаются disposable; stable content IDs не равны instance IDs.
  • Долгая операция имеет progress, cancellation и staging output.

Editor imports and inspectors

  • Custom import plugin применяется для формата, которому действительно нужен first-class Godot Resource lifecycle.
  • Один extension/type имеет стабильный importer name и version.
  • Platform/profile variants фиксируются явно.
  • Custom inspectors редактируют canonical data через commands и показывают field-level validation.
  • Gizmos не владеют сущностью и создают одну undoable logical operation на drag/stroke.

UI

  • Control tree не читает network packets и не ищет world nodes.
  • View models immutable на frame/update boundary.
  • Layout использует anchors/containers/theme tokens, а не hardcoded pixel positions вне fidelity backend.
  • FrameXML compatibility layout изолирован от modern Godot-native screens.
  • Input consumption и focus/modal context тестируются сценами.

Profiling and diagnostics

  • Использовать Godot profiler для script/physics и Visual Profiler для render CPU/GPU.
  • Headless/CLI runs сохраняют JSON metrics; GPU runs фиксируют backend/device/driver/resolution.
  • Performance changes сравниваются cold/warm и p50/p95/p99, а не одним FPS.
  • GPU validation, memory tracking и RenderDoc workflow документируются для shader/backend defects.
  • Custom monitors публикуют streaming queues, cache hits, entities, materials, RIDs и job latency.

Tests

  • Pure logic тестируется без SceneTree.
  • Scene runner используется только для lifecycle/input/signals/layout/presentation.
  • EditorPlugin имеет enable/disable/reload и undo/save/reload tests.
  • Headless является обязательным CI path; visual tests запускаются отдельно на GPU runner.
  • GdUnit4 рассматривается как кандидат для GDScript/scene tests; native tests остаются отдельным target.

Official references