Campaign Comics
Comic/cutscene playback system for campaign narrative sequences. Displays Spine-animated comic panels with background audio between campaign scenarios.
Comic/cutscene playback system for campaign narrative sequences. Displays Spine-animated comic panels with background audio between campaign scenarios.
Overview
Plays sequential comic panels with optional per-panel sound effects. Manages audio channel volumes during playback (muting gameplay audio, keeping GUI/Master/Other). Provides a callback mechanism for scenario flow integration.
Public API
| Function | Args | Returns | Description |
|---|---|---|---|
M.playComic | comicData, [comicFinishedCallback] | - | Starts comic panel sequence with optional completion callback |
M.onSpineAnimationFinished | - | - | Called when Spine animation completes; triggers callback and restores audio |
M.onScenarioChange | sc | - | Resets audio volumes on scenario pre-start |
Comic Data Structure
comicData = {
path = "path/to/comics",
backgroundSound = "sound_asset",
order = {
"panel1", -- Simple: just folder name
{ comic = "panel2", sound = "sfx_asset" }, -- With per-panel sound
"panel3"
}
}Playback Flow
playComic()is called with comic data and a callback- Audio channels are muted (except GUI, Master, Other)
AudioChannelGuistarts playing- Panel list is assembled and sent to UI via
ChangeState → 'comic' - UI plays Spine animations for each panel
- When animation finishes,
onSpineAnimationFinished()fires - Callback executes, audio volumes restore, GUI audio stops
Audio Management
-- During comic playback:
-- - All audio channels except GUI, Master, and Other are muted
-- - Original volumes are saved in lastVolumes table
-- - Volumes restore on comic finish or scenario change
forEachAudioChannel(function(name, audio)
lastVolumes[name] = audio:getVolume()
if name ~= 'AudioChannelGui' and name ~= 'AudioChannelMaster' and name ~= 'AudioChannelOther' then
audio:setVolume(0)
end
end)Integration with Campaign
Comics are triggered via scenario onEvent data:
-- In campaign_campaigns.processScenarioOnEvent():
if onEventData.comic then
campaign_comics.playComic(onEventData.comic, comicFinishedCallback)
end
-- The callback decrements displayEndUIRefs/displayStartUIRefs counters
-- to synchronize with other async UI elementsNotes
- Uses Spine runtime for panel animations (not standard image slideshow)
- The
onSpineAnimationFinishedcallback is a one-shot (set tofalseafter firing) nopis used as default callback if none provided- Audio restore happens both on comic finish and on scenario pre-start reset
- The
reset()function is idempotent (safe to call multiple times)
See Also
- Campaign System - Triggers comics during scenario events
- Campaign Exploration - Free-roam between comic sequences
Campaign Loader
Campaign file loading, validation, save management, and campaign start orchestration. Handles the full lifecycle from JSON file to running campaign.
Campaign Dealer
Vehicle and item stock management for campaign dealer/vendor locations. Tracks purchasable inventory with add/remove/buy operations and campaign save/resume support.