Commit Graph

34 Commits

Author SHA1 Message Date
a603833d7e fix: handle loop seek in video ended callback, prevent duplicate end events 2026-06-12 22:58:59 +08:00
8655e01c23 refactor: unify video mode detection into getVideoMode() 2026-06-12 19:10:51 +08:00
32f7e34130 fix: preload candidate URLs now use resolveVideoUrl in Web mode 2026-06-12 18:56:29 +08:00
503496ea0e fix: only switch quality during active playback, not after video ended 2026-06-12 17:51:01 +08:00
d46a2194f4 fix: switchQuality reset currentTime=0 to unset ended flag 2026-06-12 17:42:43 +08:00
a465009086 fix: switchQuality add load() to reset HLS state after video ended 2026-06-12 17:39:58 +08:00
b6231e4efd feat: adaptive bitrate support, engine improvements, demo updates, and electron preload 2026-06-12 17:15:30 +08:00
0379548a29 feat: full-screen StoryGallery with flow layout, startAtScene engine method, clickable flow nodes 2026-06-12 11:37:14 +08:00
9297117544 feat: P15 ending gallery, chapter recap, visited tracking, save system v6 2026-06-09 17:49:07 +08:00
451c6ea025 chore: sync latest changes 2026-06-09 17:21:54 +08:00
0a6d26ecb0 fix: suppress videoEnd during QTE, clear QTE UI on game end and chapter restart 2026-06-09 14:55:13 +08:00
660fa9347c feat: playback bar component, save system improvements, demo and roadmap updates 2026-06-09 14:21:41 +08:00
652162f565 fix: restore opacity when replaying same video after image scene 2026-06-09 12:32:48 +08:00
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
ace5ed1fb3 feat: chapter select system, multi-chapter support, scene manager refactor, and docs update 2026-06-09 11:35:11 +08:00
4bfdfbc27d feat: audio system, demo scene updates, docs, and engine improvements 2026-06-08 23:18:33 +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
6b67989007 feat: engine improvements, new scenes, videos, subtitles, hotspot component and docs update 2026-06-08 14:01:58 +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
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
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
2de9f99a81 feat: add StateManager.dump() and expose window.__sm for debugging
- StateManager.dump(): console.table formatted dump of variables, flags, history
- window.__sm: exposes engine.stateManager in dev mode for console inspection
2026-06-07 17:27:52 +08:00
b96a12a2f3 docs: add comment explaining waitReady logic 2026-06-07 17:05:59 +08:00
937e45c203 feat: P1 core - seamless video switching, conditional branches, save/load
- VideoManager: A/B dual-buffered video with crossfade transitions and candidate preloading
- Engine: condition-based choice filtering, ChoiceSystem timer, resumeScene for save/load
- SceneManager: getCandidateUrls for preloading next scenes
- SaveSystem: Dexie.js IndexedDB multi-slot save/load
- ChoiceSystem: timed choices with countdown and auto-default on timeout
- GamePlayer: dual video elements with crossfade CSS
- ChoicePanel: timer progress bar and countdown text
- SaveLoadMenu: save/load UI component
- App.vue: menu trigger, dual video refs, save/load integration
- gameStore: timer state, saves list
- demo.json: conditional choice example (secret ending, requires trust >= 80)
- ROADMAP: mark P1 as completed
2026-06-07 16:48:52 +08:00
192ecbbce2 fix: wait for video metadata before playing and set onEnd before play
- Reorder onEnd callback before play() in Engine.goToScene to prevent
  missed ended event if video ends synchronously
- Wait for loadedmetadata event in VideoManager.play() before seeking
  to ensure currentTime reset works correctly on new video sources
2026-06-07 14:34:15 +08:00
aeb6dc46a4 init 2026-06-07 13:50:05 +08:00