WIP checkpoint: Plan: Creator Studio — Extended Authoring Tools
This commit is contained in:
@@ -32,26 +32,26 @@ _As a creator, I can see how many plays and average session length my experience
|
|||||||
|
|
||||||
### US-1: Asset Import Pipeline
|
### US-1: Asset Import Pipeline
|
||||||
|
|
||||||
#### T1.1: Backend — glTF Asset Model & Upload Endpoint
|
#### T1.1: Backend — glTF Asset Upload with Metadata Extraction
|
||||||
- **Type:** implementation
|
- **Type:** implementation
|
||||||
- **Files:** `backend/app/models/asset.py` (add glTF fields), `backend/app/routers/assets.py` (new endpoint)
|
- **Files:** `backend/app/routers/assets.py` (extend upload endpoint), `backend/app/models/asset.py` (add glTF-specific metadata fields)
|
||||||
- **Scope:** Extend Asset model with glTF-specific metadata fields (mesh_count, vertex_count, has_animation, texture_refs) stored in `metadata_json`. Add upload endpoint that accepts `.glb`/`.gltf` files and stores them in the upload directory with metadata extraction (parse glTF JSON for mesh/texture counts).
|
- **Scope:** Extend the existing `upload_asset_file` endpoint in `assets.py` to detect `.glb`/`.gltf` files and extract glTF metadata (mesh_count, vertex_count, has_animation, texture_refs, bounding_box) from the embedded JSON. Store extracted metadata in `metadata_json`. Add a `has_gltf_metadata` computed property. The Asset model already has `asset_type = MODEL_3D` and `metadata_json` — this task adds the extraction logic.
|
||||||
- **Acceptance:** POST `/api/assets/{id}/upload` with glTF file returns asset with extracted metadata; GET lists glTF assets; file stored on disk.
|
- **Acceptance:** POST `/api/assets/{id}/upload` with a `.glb` file returns asset with `metadata_json` containing `mesh_count`, `vertex_count`, `has_animation`, `texture_refs`. GET lists include these fields. File stored on disk. Non-glTF files are unaffected.
|
||||||
- **Dependencies:** None (builds on existing asset infrastructure)
|
- **Dependencies:** None (builds on existing asset infrastructure)
|
||||||
|
|
||||||
#### T1.2: Backend — Asset Catalog API for Client Lookup
|
#### T1.2: Backend — Public Asset Catalog Endpoint
|
||||||
- **Type:** implementation
|
- **Type:** implementation
|
||||||
- **Files:** `backend/app/routers/assets.py` (new endpoints), `backend/app/models/asset.py` (minor additions)
|
- **Files:** `backend/app/routers/assets.py` (new endpoint)
|
||||||
- **Scope:** Add `GET /api/assets/catalog` endpoint that returns all public glTF assets with their metadata (name, thumbnail_url, mesh_count, vertex_count, tags). Add filtering by tags and pagination. This is what the editor's asset palette queries.
|
- **Scope:** Add `GET /api/assets/catalog` endpoint that returns all public glTF assets with their metadata (name, thumbnail_url, mesh_count, vertex_count, tags). Add filtering by tags and pagination. This is what the editor's asset palette queries. Uses the existing `Asset.is_public` field.
|
||||||
- **Acceptance:** Catalog endpoint returns paginated list of public assets; filtering by tag works; pagination params respected.
|
- **Acceptance:** Catalog endpoint returns paginated list of public assets; filtering by tag works; pagination params respected; returns 401 without auth.
|
||||||
- **Dependencies:** T1.1
|
- **Dependencies:** T1.1
|
||||||
|
|
||||||
#### T1.3: Godot — glTF Import Utility (Editor-Side)
|
#### T1.3: Godot — glTF Import Utility (Editor-Side)
|
||||||
- **Type:** implementation
|
- **Type:** implementation
|
||||||
- **Files:** `scripts/gltf_importer.gd` (new), `scripts/asset_catalog.gd` (new)
|
- **Files:** `scripts/gltf_importer.gd` (new), `scripts/asset_catalog.gd` (new)
|
||||||
- **Scope:** Godot-side utility that connects to the catalog API, downloads glTF files, and converts them to Godot-compatible resources (`.res` files with embedded mesh data). Provides `import_gltf(url: String) -> Resource` function. Handles texture extraction and mesh merging.
|
- **Scope:** Godot-side utility that connects to the catalog API, downloads glTF files, and converts them to Godot-compatible resources (`.res` files with embedded mesh data). Provides `import_gltf(url: String) -> Resource` function. Handles texture extraction and mesh merging. Uses the ApiClient autoload (from client-server-wiring plan) for HTTP.
|
||||||
- **Acceptance:** `import_gltf()` downloads a glTF from the catalog, converts mesh to `Mesh` resource, returns a ready-to-use Godot resource. Texture files stored in `user://assets/`.
|
- **Acceptance:** `import_gltf()` downloads a glTF from the catalog, converts mesh to `Mesh` resource, returns a ready-to-use Godot resource. Texture files stored in `user://assets/`.
|
||||||
- **Dependencies:** T1.2
|
- **Dependencies:** T1.2, client-server-wiring ApiClient (task 1 from that plan)
|
||||||
|
|
||||||
### US-2: Script Editor with Sandboxed API
|
### US-2: Script Editor with Sandboxed API
|
||||||
|
|
||||||
@@ -60,15 +60,15 @@ _As a creator, I can see how many plays and average session length my experience
|
|||||||
#### T2.1: Backend — Script Model & CRUD Endpoints
|
#### T2.1: Backend — Script Model & CRUD Endpoints
|
||||||
- **Type:** architecture
|
- **Type:** architecture
|
||||||
- **Files:** `backend/app/models/script.py` (new), `backend/app/routers/scripts.py` (new), `backend/app/main.py` (register router), `backend/app/models/__init__.py` (export)
|
- **Files:** `backend/app/models/script.py` (new), `backend/app/routers/scripts.py` (new), `backend/app/main.py` (register router), `backend/app/models/__init__.py` (export)
|
||||||
- **Scope:** Create `Script` model (id, name, world_id, owner_id, source_code, version, created_at, updated_at). Add full CRUD endpoints: `POST /api/scripts/` (create), `GET /api/scripts/` (list), `GET /api/scripts/{id}` (get), `PUT /api/scripts/{id}` (update), `DELETE /api/scripts/{id}` (delete). Scripts are owned by users and associated with a world.
|
- **Scope:** Create `Script` model (id, name, world_id, owner_id, source_code TEXT, version INT, script_type ENUM[gdscript, dsl], dsl_payload JSON, created_at, updated_at). Add full CRUD endpoints: `POST /api/scripts/` (create), `GET /api/scripts/` (list), `GET /api/scripts/{id}` (get), `PUT /api/scripts/{id}` (update), `DELETE /api/scripts/{id}` (delete). Scripts are owned by users and associated with a world. `dsl_payload` stores the JSON/Resource data for the DSL approach; `source_code` stores raw GDScript if used.
|
||||||
- **Acceptance:** All CRUD endpoints work; scripts are owned by creator; list endpoint filters by owner/world; update increments version.
|
- **Acceptance:** All CRUD endpoints work; scripts are owned by creator; list endpoint filters by owner/world; update increments version; DSL and gdscript types supported.
|
||||||
- **Dependencies:** None (new model + router)
|
- **Dependencies:** None (new model + router)
|
||||||
|
|
||||||
#### T2.2: Godot — Script API Surface Definition
|
#### T2.2: Godot — Script API Surface Definition
|
||||||
- **Type:** architecture
|
- **Type:** architecture
|
||||||
- **Files:** `scripts/editor_script_api.gd` (new), `docs/architecture/scripting_sandbox.md` (update)
|
- **Files:** `scripts/editor_script_api.gd` (new)
|
||||||
- **Scope:** Define the public API surface available to creator scripts. This is a `RefCounted` class that wraps the Godot engine's capabilities into a safe, documented interface. Includes: `WorldAPI` (get_tile, get_object, set_property), `PlayerAPI` (get_position, get_health), `AudioAPI` (play_sound, play_music), `NetworkAPI` (send_event, broadcast). Each method has documented parameters and return types.
|
- **Scope:** Define the public API surface available to creator scripts. This is a `RefCounted` class that wraps the Godot engine's capabilities into a safe, documented interface. Includes: `WorldAPI` (get_tile, get_object, set_property), `PlayerAPI` (get_position, get_health), `AudioAPI` (play_sound, play_music), `NetworkAPI` (send_event, broadcast). Each method has documented parameters and return types. Self-documenting via `##` doc comments for autocomplete.
|
||||||
- **Acceptance:** `EditorScriptAPI` class exposes all documented methods; methods are callable from user scripts; API surface is self-documenting (each method has `##` doc comments).
|
- **Acceptance:** `EditorScriptAPI` class exposes all documented methods; methods are callable from user scripts; API surface is self-documenting.
|
||||||
- **Dependencies:** None (standalone definition)
|
- **Dependencies:** None (standalone definition)
|
||||||
|
|
||||||
#### T2.3: Godot — In-Game Script Editor UI
|
#### T2.3: Godot — In-Game Script Editor UI
|
||||||
@@ -83,13 +83,13 @@ _As a creator, I can see how many plays and average session length my experience
|
|||||||
#### T3.1: Backend — Experience Model & Status Transitions
|
#### T3.1: Backend — Experience Model & Status Transitions
|
||||||
- **Type:** architecture
|
- **Type:** architecture
|
||||||
- **Files:** `backend/app/models/experience.py` (new), `backend/app/routers/experiences.py` (new), `backend/app/main.py` (register router), `backend/app/models/__init__.py` (export)
|
- **Files:** `backend/app/models/experience.py` (new), `backend/app/routers/experiences.py` (new), `backend/app/main.py` (register router), `backend/app/models/__init__.py` (export)
|
||||||
- **Scope:** Create `Experience` model (id, world_id, title, description, status, published_at, review_notes, reviewer_id). Status enum: `DRAFT`, `SUBMITTED`, `IN_REVIEW`, `APPROVED`, `REJECTED`, `LIVE`. Add endpoints: `POST /api/experiences/` (create draft), `POST /api/experiences/{id}/submit` (submit for review), `POST /api/experiences/{id}/approve` (approve), `POST /api/experiences/{id}/reject` (reject), `GET /api/experiences/` (list with status filter).
|
- **Scope:** Create `Experience` model (id, world_id FK→worlds, title, description, status ENUM[DRAFT,SUBMITTED,IN_REVIEW,APPROVED,REJECTED,LIVE], published_at, review_notes, reviewer_id FK→users). Status transitions enforced: DRAFT→SUBMITTED→IN_REVIEW→APPROVED→LIVE; REJECTED→DRAFT (resubmit). Add endpoints: `POST /api/experiences/` (create draft), `POST /api/experiences/{id}/submit` (submit for review), `POST /api/experiences/{id}/approve` (approve), `POST /api/experiences/{id}/reject` (reject), `GET /api/experiences/` (list with status filter). An experience is a **publishing wrapper** around a World — the world's visibility is set to PUBLIC when experience goes LIVE.
|
||||||
- **Acceptance:** All CRUD + transition endpoints work; status transitions enforced (DRAFT→SUBMITTED→IN_REVIEW→APPROVED→LIVE); rejected can be resubmitted; list filters by status.
|
- **Acceptance:** All CRUD + transition endpoints work; status transitions enforced; rejected can be resubmitted; list filters by status; approve sets world visibility to PUBLIC; only world owner can submit; only moderators can approve/reject.
|
||||||
- **Dependencies:** None (new model + router)
|
- **Dependencies:** None (new model + router)
|
||||||
|
|
||||||
#### T3.2: Backend — Review Queue & Moderation Integration
|
#### T3.2: Backend — Review Queue & Moderation Integration
|
||||||
- **Type:** implementation
|
- **Type:** implementation
|
||||||
- **Files:** `backend/app/routers/experiences.py` (add endpoints), `backend/app/models/experience.py` (add fields)
|
- **Files:** `backend/app/routers/experiences.py` (add endpoints)
|
||||||
- **Scope:** Add review queue endpoint `GET /api/experiences/review-queue` (returns experiences in IN_REVIEW status). Add `POST /api/experiences/{id}/review` endpoint for moderators to add review notes and change status. Integrates with content moderation: when an experience is submitted, its world's content flags are computed and attached to the review.
|
- **Scope:** Add review queue endpoint `GET /api/experiences/review-queue` (returns experiences in IN_REVIEW status). Add `POST /api/experiences/{id}/review` endpoint for moderators to add review notes and change status. Integrates with content moderation: when an experience is submitted, its world's content flags are computed and attached to the review.
|
||||||
- **Acceptance:** Review queue returns IN_REVIEW experiences; review endpoint accepts notes and status change; content flags attached on submit; only moderators can review.
|
- **Acceptance:** Review queue returns IN_REVIEW experiences; review endpoint accepts notes and status change; content flags attached on submit; only moderators can review.
|
||||||
- **Dependencies:** T3.1
|
- **Dependencies:** T3.1
|
||||||
@@ -110,10 +110,10 @@ _As a creator, I can see how many plays and average session length my experience
|
|||||||
|
|
||||||
### US-4: Creator Analytics
|
### US-4: Creator Analytics
|
||||||
|
|
||||||
#### T4.1: Backend — Session & Play Tracking Model
|
#### T4.1: Backend — Session & Play Tracking Models
|
||||||
- **Type:** architecture
|
- **Type:** architecture
|
||||||
- **Files:** `backend/app/models/analytics.py` (new), `backend/app/routers/analytics.py` (new), `backend/app/main.py` (register router), `backend/app/models/__init__.py` (export)
|
- **Files:** `backend/app/models/analytics.py` (new), `backend/app/routers/analytics.py` (new), `backend/app/main.py` (register router), `backend/app/models/__init__.py` (export)
|
||||||
- **Scope:** Create `PlaySession` model for analytics (id, experience_id, player_id, started_at, ended_at, duration_seconds, chunk_loads, interactions_count). Create `PlayEvent` model for granular events (id, experience_id, player_id, event_type, payload, created_at). Add endpoints: `POST /api/analytics/session/start` (start session), `POST /api/analytics/session/end` (end session), `POST /api/analytics/event` (log event).
|
- **Scope:** Create `PlaySession` model (id, experience_id FK→experiences, player_id FK→users, started_at, ended_at, duration_seconds, chunk_loads INT, interactions_count INT). Create `PlayEvent` model (id, experience_id FK→experiences, player_id FK→users, event_type, payload JSON, created_at). Add endpoints: `POST /api/analytics/session/start` (start session), `POST /api/analytics/session/end` (end session), `POST /api/analytics/event` (log event). Note: `sessions` table is taken by auth tokens; this uses `play_sessions` table name.
|
||||||
- **Acceptance:** Session start/end endpoints work; events logged; duration calculated correctly; endpoints accept valid experience/player IDs.
|
- **Acceptance:** Session start/end endpoints work; events logged; duration calculated correctly; endpoints accept valid experience/player IDs.
|
||||||
- **Dependencies:** None (new models + routers)
|
- **Dependencies:** None (new models + routers)
|
||||||
|
|
||||||
@@ -144,9 +144,9 @@ _As a creator, I can see how many plays and average session length my experience
|
|||||||
|
|
||||||
New tables needed (in order):
|
New tables needed (in order):
|
||||||
1. `scripts` — script storage
|
1. `scripts` — script storage
|
||||||
2. `experiences` — publishing state
|
2. `experiences` — publishing state (wraps worlds)
|
||||||
3. `analytics_sessions` — session tracking (note: `sessions` table already exists for auth tokens)
|
3. `play_sessions` — session tracking (note: `sessions` table already exists for auth tokens)
|
||||||
4. `analytics_events` — granular events
|
4. `play_events` — granular events
|
||||||
|
|
||||||
Migration file: `backend/alembic/versions/0003_creator_studio.py`
|
Migration file: `backend/alembic/versions/0003_creator_studio.py`
|
||||||
|
|
||||||
@@ -156,25 +156,26 @@ Migration file: `backend/alembic/versions/0003_creator_studio.py`
|
|||||||
|
|
||||||
```
|
```
|
||||||
T1.1 (glTF upload) ──→ T1.2 (catalog API) ──→ T1.3 (Godot importer)
|
T1.1 (glTF upload) ──→ T1.2 (catalog API) ──→ T1.3 (Godot importer)
|
||||||
T2.1 (script model) ──→ T2.3 (API surface) ──→ T2.4 (editor UI)
|
T2.1 (script model) ──→ T2.3 (editor UI)
|
||||||
|
T2.2 (API surface) ──→ T2.3 (editor UI)
|
||||||
T3.1 (experience model) ──→ T3.2 (review queue) ──→ T3.3 (publish UI)
|
T3.1 (experience model) ──→ T3.2 (review queue) ──→ T3.3 (publish UI)
|
||||||
T3.1 ──→ T3.4 (discovery list)
|
T3.1 ──→ T3.4 (discovery list)
|
||||||
T4.1 (tracking model) ──→ T4.2 (dashboard endpoint) ──→ T4.4 (analytics UI)
|
T4.1 (tracking model) ──→ T4.2 (dashboard endpoint) ──→ T4.4 (analytics UI)
|
||||||
T4.1 ──→ T4.3 (game tracker) ──→ T4.4 ──┘
|
T4.1 ──→ T4.3 (game tracker) ──→ T4.4 (analytics UI)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation Order Recommendation
|
## Implementation Order Recommendation
|
||||||
|
|
||||||
1. **T1.1** — Foundation: asset upload with glTF support
|
1. **T1.1** — Foundation: asset upload with glTF metadata extraction
|
||||||
2. **T2.1** — Foundation: script model + CRUD
|
2. **T2.1** — Foundation: script model + CRUD
|
||||||
3. **T3.1** — Foundation: experience model + status transitions
|
3. **T3.1** — Foundation: experience model + status transitions
|
||||||
4. **T4.1** — Foundation: analytics tracking model
|
4. **T4.1** — Foundation: analytics tracking model
|
||||||
5. **T1.2** — Asset catalog for editor
|
5. **T1.2** — Asset catalog for editor
|
||||||
6. **T2.3** — Script API surface definition
|
6. **T2.2** — Script API surface definition
|
||||||
7. **T3.2** — Review queue integration
|
7. **T3.2** — Review queue integration
|
||||||
8. **T4.2** — Analytics dashboard endpoint
|
8. **T4.2** — Analytics dashboard endpoint
|
||||||
9. **T1.3** — Godot glTF importer
|
9. **T1.3** — Godot glTF importer (depends on ApiClient from client-server-wiring)
|
||||||
10. **T2.4** — Script editor UI
|
10. **T2.3** — Script editor UI
|
||||||
11. **T3.3** — Publishing UI panel
|
11. **T3.3** — Publishing UI panel
|
||||||
12. **T3.4** — Experience discovery list
|
12. **T3.4** — Experience discovery list
|
||||||
13. **T4.3** — Analytics tracker in game
|
13. **T4.3** — Analytics tracker in game
|
||||||
|
|||||||
Reference in New Issue
Block a user