52 lines
3.0 KiB
Markdown
52 lines
3.0 KiB
Markdown
# ADR 0025: Project Root Is a Startup Boundary
|
|
|
|
## Status
|
|
|
|
Accepted
|
|
|
|
## Context
|
|
|
|
Bevy configures `AssetPlugin.file_path` before editor plugins and project settings initialize. The
|
|
asset catalog, scene loader, import pipeline, session state, and runtime game systems must all agree
|
|
on one project root. Changing only editor metadata in a running process leaves `AssetServer` and
|
|
already-created handles attached to the old project, which can silently read or write the wrong
|
|
content.
|
|
|
|
Projects also need stable identity and enough template metadata for a launcher to distinguish a
|
|
game workspace from a disposable sandbox without inspecting arbitrary project contents.
|
|
|
|
## Decision
|
|
|
|
- Select and validate the project root before constructing the Bevy `App`. `--project <root>`, the
|
|
graphical launcher, and recent-project resume all feed the same pre-engine activation function.
|
|
- Do not implement in-process project switching. **Switch Project** exits or relaunches through the
|
|
launcher so the next process creates `AssetPlugin`, settings, catalog, and session state from one
|
|
root.
|
|
- Extend `assets/project.ron` with backward-compatible `project_id`, `project_kind`,
|
|
`template_version`, and capability tags. Legacy manifests receive safe defaults; new projects
|
|
receive a UUID.
|
|
- A valid project has a parseable manifest, a project-relative default level that cannot escape the
|
|
root, and a default level that passes the shared scene validator.
|
|
- The standalone `GamePlugin` materializes that `default_level` through the schema-aware Bevy
|
|
`DynamicWorld` loader. Embedded editor startup explicitly defers this step so `SceneIo` remains
|
|
the sole owner of the active authored document, tabs, composition, and recovery state.
|
|
- Sandbox scaffolding writes only to a missing or empty destination. It creates the standard asset
|
|
directories, a schema-current empty level, and a manifest using transactional writes.
|
|
- Recent-project presentation filters missing, invalid, and duplicate roots before showing them.
|
|
- On Linux, launcher-to-editor and editor-to-launcher handoffs use independent transient user
|
|
services with an explicit working directory and a bounded display/session environment allowlist.
|
|
Closing either source process therefore cannot tear down the process it launched.
|
|
|
|
## Consequences
|
|
|
|
- Project activation cannot leave the editor half-connected to two asset roots.
|
|
- Packaged and workspace game binaries start in the validated authored default level instead of the
|
|
procedural editor fallback arena; the editor cannot race a second runtime-owned scene load.
|
|
- Switching projects requires a process boundary, but startup remains deterministic and testable.
|
|
- Project scaffolding is intentionally conservative and cannot merge into a directory containing
|
|
user data.
|
|
- Template migrations and capability negotiation can evolve independently of the project-settings
|
|
file format version.
|
|
- The service-manager handoff is Linux-specific; other platforms use the local process-spawn
|
|
fallback until native packaging provides a stronger lifecycle boundary.
|