ed435f790f
refactor: extract enterScene as single source of truth for scene transitions
2026-06-09 12:26:38 +08:00
bdf62bf0a6
fix: set currentScene before image branch in resumeScene so hotspots are clickable
2026-06-09 12:18:42 +08:00
9e339c7c16
refactor: inline event registration at setup level, remove registerEvents duplication across entry points
2026-06-09 12:06:40 +08:00
ace5ed1fb3
feat: chapter select system, multi-chapter support, scene manager refactor, and docs update
2026-06-09 11:35:11 +08:00
655b9a23d0
feat: fullscreen composable, roadmap update, and future plans doc
2026-06-09 10:47:14 +08:00
4bfdfbc27d
feat: audio system, demo scene updates, docs, and engine improvements
2026-06-08 23:18:33 +08:00
514c8f5207
fix: shorten stay subtitle cue to avoid overlap with loop segment
2026-06-08 22:02:19 +08:00
0dbe1b097d
feat: video loop support for hotspot scenes, demo updates, docs, and engine fixes
2026-06-08 21:48:47 +08:00
5b40781d0a
fix: hide old video frame before crossfade when coming from image scene
2026-06-08 21:24:28 +08:00
972738572f
fix: filter stale timeupdate events by tracking sceneVideo element
2026-06-08 21:09:10 +08:00
6c0deea0e2
fix: pause old video before switching to prevent stale timeupdate triggering wrong hotspot states
2026-06-08 15:29:28 +08:00
17c479525d
fix: emit initial hotspot state immediately after sceneChange to prevent flash
2026-06-08 15:17:43 +08:00
077de2a64e
fix: emit sceneChange before video start to avoid hotspot flash, prevent game end for hotspot-only scenes
2026-06-08 15:02:38 +08:00
d81042174a
fix: skip crossfade when switching to same video, replay from start
2026-06-08 14:32:34 +08:00
fa7c333214
fix: use v-show instead of v-if for GamePlayer to prevent video element detach during image scenes
2026-06-08 14:26:21 +08:00
6b67989007
feat: engine improvements, new scenes, videos, subtitles, hotspot component and docs update
2026-06-08 14:01:58 +08:00
e68ed9c962
fix: await nextTick before setting video src on first preview
2026-06-08 13:48:50 +08:00
a0749261bf
feat: highlight upstream/downstream edges when node selected
2026-06-08 13:09:47 +08:00
a16f34acd9
docs: add graph layout optimization record to editor README
2026-06-08 13:07:18 +08:00
b542660095
feat: replace BFS layout with dagre for professional graph layout
2026-06-08 13:01:17 +08:00
e323f7973a
fix: pass SmoothStepEdge component instead of string to default-edge-type
2026-06-08 12:49:42 +08:00
a008c927a5
feat: use smoothstep edge type for orthogonal lines
2026-06-08 12:24:42 +08:00
419bfab1f4
fix: remove animated edges
2026-06-08 12:22:41 +08:00
23f8fb97a6
feat: BFS-based left-to-right tree layout for scene graph
2026-06-08 12:21:05 +08:00
f439f7784e
fix: add immediate:true to watcher so initial data renders on first mount
2026-06-08 12:14:57 +08:00
b48a760a1e
fix: use local refs for nodes/edges, only useVueFlow for events and fitView
2026-06-08 12:10:18 +08:00
518c451a59
fix: remove redundant :nodes/:edges props from VueFlow, useVueFlow already provides them via inject
2026-06-08 12:05:54 +08:00
4d48463164
refactor: rewrite editor with immutable state, async-safe Vue Flow, and loading guard
2026-06-07 23:18:43 +08:00
45461b4ed7
fix: prevent Vue Flow edge render crash by clearing edges before structural node changes
2026-06-07 23:01:52 +08:00
dad5e9b8c3
docs: add editor README with usage guide
2026-06-07 22:51:56 +08:00
a22dd8497e
fix: move critical layout CSS to index.html, revert broken absolute positioning
2026-06-07 22:50:20 +08:00
469fc1ff33
fix: ensure Vue Flow parent container has explicit dimensions
2026-06-07 22:41:51 +08:00
f9ee24197a
chore: update roadmap and session log
2026-06-07 22:00:30 +08:00
3b4c6d7024
feat: P3 - visual scenario editor with Vue Flow
...
- editor/: stand-alone Vite multi-page app for visual scenario editing
- editor/components/SceneGraph.vue: Vue Flow graph with scene nodes, branch/default/QTE edges
- editor/components/NodeEditor.vue: right panel editing video/subtitle paths, choices, QTE params
- editor/components/PreviewPanel.vue: embedded video player previewing selected scene
- editor/composables/useGraphEditor.ts: bidirectional graph<->JSON sync
- editor/App.vue: toolbar (new scene, import/export JSON, load demo, start scene selector)
- @vue-flow/core|background|controls: graph visualization dependencies
- vite.config.ts: multi-page build (main + editor)
- ROADMAP: mark P3 as completed
2026-06-07 21:38:08 +08:00
65c26e0972
fix: clear old subtitle cues when switching to scene without subtitles
...
Previously when subtitleUrl became null, the old cues array was retained
and would replay from the beginning on the next scene.
2026-06-07 21:22:45 +08:00
a34d787336
fix: register checkQTE once in constructor instead of per-scene
...
Previously goToScene added a new checkQTE closure to onTimeUpdate on
every scene transition, accumulating stale closures that re-triggered
old QTE. Now checkQTE is an arrow property registered once in the
constructor, reading this.currentScene directly — no closure, no stale
references, no guard condition needed.
2026-06-07 21:16:31 +08:00
4da4d65d5e
fix: checkQTE guard against stale scene closures
...
Since onTimeUpdate callbacks are now additive (Set), goToScene closures
for old scenes persist. Add currentScene?.id !== scene.id check to
prevent QTE from re-triggering for past scenes after scene transitions.
2026-06-07 21:14:40 +08:00
bb657b3547
fix: capture save thumbnail on videoEnd instead of sceneChange
...
Previously thumbnail was captured during sceneChange (before video starts
playing), so readyState was low and capture was skipped. Now capture on
videoEnd when frame is guaranteed visible, store in lastThumbnail, and
reuse for both auto-save (slot 0) and manual save.
2026-06-07 21:11:18 +08:00
b6eb3c3959
fix: QTE false race condition + restore auto-save slot in menu
...
- QTESystem: add if (!this.active) return guard in setInterval/setTimeout
callbacks to prevent false result from firing after successful key press
- SaveLoadMenu: restore auto-save slot 0 row with blue styling, thumbnail,
scene label, and read-only load button
2026-06-07 21:07:21 +08:00
e2670c50d4
refactor: rename Subtitles prop videoUrl to subtitleUrl
2026-06-07 20:48:39 +08:00
b3bbe7b39d
fix: support multiple onTimeUpdate callbacks in VideoManager
...
Previously onTimeCallback was a single nullable function pointer, so
registerEvents()'s store.setVideoTime callback was overwritten by
goToScene()'s checkQTE callback, causing videoTime to stay at 0.
Changed to a Set to support multiple concurrent listeners.
2026-06-07 20:38:24 +08:00
ef00babdb7
feat: add dump() method to GameStore for debugging
2026-06-07 20:30:39 +08:00
64a474a741
feat: expose store as window.__store for debugging
2026-06-07 20:29:14 +08:00
12d30cc128
docs: add QTE explanation comment in QTESystem
2026-06-07 19:50:45 +08:00
319a379921
feat: P2 - QTE system, subtitles, save thumbnails
...
- QTESystem: trigger detection via timeupdate, multi-key matching, timeout handling
- QTEOverlay: SVG countdown ring + key prompts + success/fail animation
- Engine: integrate QTE (timeupdate check, conditional branching, effect application)
- Subtitles: WebVTT parsing + synchronized subtitle rendering
- GamePlayer: overlay QTE and subtitle components
- SaveSystem: DB v2 with thumbnail field, canvas snapshot at 320x180 JPEG
- SaveLoadMenu: thumbnail preview for save slots
- VideoManager: getActiveVideoElement() for canvas capture
- App.vue: QTE/subtitle integration, thumbnail capture on save
- stores: QTE state management, save list with thumbnails
- demo.json: QTE scene (right_door), subtitles, new event types
- ROADMAP: mark P2 as completed
2026-06-07 19:35:14 +08:00
c168e30e52
tweak: reduce intro timeLimit from 15s to 5s for faster testing
2026-06-07 19:00:16 +08:00
fa84ed909a
test: add timeLimit to intro scene for timer feature testing
...
First intro choice has 15s limit, times out to left_door if user doesn't act
2026-06-07 18:59:37 +08:00
7826d789a7
docs: add unit comment for Choice.timeLimit
2026-06-07 18:57:16 +08:00
c7d035bd8f
fix: interpret Choice.timeLimit as seconds, convert to ms internally
...
Previously maxLimit was passed directly to setTimeout/setInterval (ms),
so a JSON value of 10 meant 10ms instead of the intended 10 seconds.
Now timeLimit in JSON represents seconds, engine multiplies by 1000.
2026-06-07 18:56:30 +08:00
25ea9ce9fd
fix: consistent timer unit (seconds) in ChoiceSystem first onUpdate
...
The first onUpdate call used raw milliseconds (e.g. total: 10000),
while subsequent ticks used seconds (total: 10). This caused the
progress bar to jump on the first interval tick.
2026-06-07 18:53:05 +08:00