Scope
Ourin currently implements SERIKO in two layers:
- Legacy runtime path in
AnimationEngine.swift - New parser/executor path in:
Ourin/Animation/SerikoParser.swiftOurin/Animation/SerikoExecutor.swiftOurin/Ghost/GhostManager+Animation.swiftintegration
Parser (SerikoParser)
SerikoParser.parseSurfaces(_:) reads surfaces.txt and extracts:
surfaceN { ... }scope blocksanimation<ID>.interval,<value>animation<ID>.option,<value>animation<ID>.pattern<idx>,...
Core model types:
SerikoInterval(always,sometimes,rarely,random,runonce,yen-e,talk,bind,never)SerikoMethod(overlay,overlayfast,base,move,reduce,replace,start,alternativestart,stop,asis)SerikoPatternAnimationDefinition
Notes:
- Legacy numeric pattern format is treated as
overlay. - Unknown values are preserved via
.unknown(...).
Executor (SerikoExecutor)
SerikoExecutor is a stateful animation scheduler:
register(animations:)stores definitionsexecuteAnimation(id:)starts an animation immediatelystartLoop()advances active animations based on elapsed time and interval rulespauseAnimation,resumeAnimation,offsetAnimation,stopAnimation,stopAllAnimations
Interval triggers:
- Probabilistic:
sometimes,rarely,random - One-shot:
runonce - Event-driven:
yenE,talk,bindvia trigger APIs
Callbacks:
onMethodInvokedonPatternExecutedonAnimationFinished
Ghost integration
GhostManager+Animation.swift wires executor callbacks into rendering actions:
overlay/overlayFast->handleSurfaceOverlaybase->handleAnimAddBasemove->handleAnimAddMovereplace->handleSurfaceOverlay(..., .replace)start/alternativeStart-> nested executor startstop-> executor stop
Runtime flow:
loadAnimationsForCurrentSurface()loadssurfaces.txt- Parsed animations are registered to
SerikoExecutor playAnimation(...)tries executor first- Falls back to legacy
AnimationEngineif executor has no matching definition
The loop is driven by a timer in GhostManager+Animation calling serikoExecutor.startLoop().
SakuraScript linkage
Current linkage is command-level through GhostManager handlers:
\i[ID]/\i[ID,wait]\![anim,clear|pause|resume|offset|add|stop,...]
waitForAnimation(id:) exists for synchronized behavior and is used in animation flow.
Test coverage
OurinTests/SerikoParserTests.swift- parser correctness
- real shell
surfaces.txtparsing OurinTests/SerikoExecutorTests.swift- startup/advance/offset
- runonce completion
- interval trigger behavior
Current Status
Status: Parser Complete, Executor Integrated / updated 2026-06-15
Implemented Components
✅ SerikoParser.swift (Complete)
Complete SERIKO/2.0 parser with: - All interval types (always, sometimes, rarely, random, runonce, yen-e, talk, bind, never) - All method types (overlay, overlayfast, base, move, isReducing, replace, start, alternativestart, stop, asis) - Pattern parsing and surface definitions - surfaces.txt parsing
✅ SerikoExecutor.swift (Connected)
Fully functional animation execution engine with:
- Animation state management
- executeAnimation(), startLoop() methods
- All execute methods (overlay, base, move, reduce, replace, start, stop, etc.)
- Pause/resume/offset capabilities
- Callback system (onMethodInvoked, onPatternExecuted, onAnimationFinished)
- ✅ Callbacks wired to GhostManager (GhostManager+Animation.swift)
✅ GhostManager+Animation.swift (Integrated)
- SerikoExecutor callbacks connected
- Timer-driven loop (
serikoExecutor.startLoop()) and\![anim,*]routing in place
Integration Gaps
- ✅ SerikoExecutor callbacks connected - wired via GhostManager animation handlers
- ✅ SakuraScript animation commands routed - ![anim,*] path controls animation handling
- ⚠️ Advanced dressup behavior coverage - functional path exists, but broader ghost-matrix validation is ongoing
Blocking Issues
- No active SERIKO blockers in current tracker.
Integration Required
See archive/INTEGRATION_ROADMAP.md Phase 3 for detailed integration steps:
-
Wire SerikoExecutor to GhostManager (Task 3.1): - In GhostManager+Animation.swift: ```swift serikoExecutor.onMethodInvoked = { [weak self] method in self?.handleSerikoMethod(method) }
serikoExecutor.onPatternExecuted = { [weak self] pattern in self?.handleSerikoPattern(pattern) }
serikoExecutor.onAnimationFinished = { [weak self] animationId in self?.handleAnimationFinished(animationId) } ``` - Implement handler methods to update surface/rendering
-
Implement SakuraScript animation commands (Task 3.2): - In SakuraScriptEngine.swift:
swift private func handleAnimCommand(arguments: [String]) { let command = arguments[0] switch command { case "clear": serikoExecutor.stopAnimation(id: animId) case "pause": serikoExecutor.pauseAnimation(id: animId) // ... etc } }- Implement wait handler for __w[animation,ID] -
Testing (Task 3.3): - Load ghost with animations - Trigger via SakuraScript - Verify playback works - Test pause/resume/offset
Success Criteria
- [x] GhostManager callbacks connected
- [x] Animation commands execute
- [x] Pause/resume/offset work
- [x] Critical SERIKO blockers resolved
- [ ] Full multi-ghost on-screen matrix validation
Current limitations
- Advanced option compatibility varies by ghost data shape.
- Not all SERIKO options in
animation<ID>.optionare applied at runtime yet. - Integration with advanced SakuraScript animation wait patterns remains partial.
- Legacy and new paths coexist for compatibility; behavior may differ by command/data shape.
出典と編集について
Ourin / Furin Lab・contributors。文書はCC BY-SA 4.0(第三者の個別表記を除く)。Web版は見出し・リンクの整備とローカルパスの一般化を行っています。更新基準日: 2026-10-30。
元資料: docs/SERIKO_IMPLEMENTATION_en-us.md
ソース SHA-256: 7c21283ea1f338cd5037f9ea703e148a4ae8c4fe3b3066120ff082f71d3ce3ad