Video
Animated frame sequences with optional audio. Loaded via
Asset.GetVideo(path), which always returns
two values, the Video userdata and a companion
SoundData (or nil for sources that don't carry
audio). Hand the SoundData to SFX.LoadSound if you
want it to play; the Video drives texture updates on linked
BaseParts.
local Asset = import("Asset")
local SFX = import("SFX")
local Renderable = import("Renderable")
local video, audio = Asset.GetVideo("cutscenes.intro")
-- Show the video on a flat panel in the world.
local screen = Renderable.BasePart("Cube")
screen.Size = Vector.new(4, 2.25, 0.05)
video:LinkPart(screen)
video.Looped = true
video:Play()
-- Audio is non-nil for any source that carries an audio track.
-- GIF doesn't, MP4/MOV typically do.
if audio then
local snd = SFX.LoadSound(audio)
snd.Looped = true
snd:Play()
end
Supported formats
| Extension | Audio | Decoder |
|---|---|---|
.gif |
none | Pure-Rust via the image crate. Always available, no system deps. |
.mp4 |
extracted as 16-bit PCM WAV -> SoundData | Delegated to ffmpeg on PATH. Whatever codec ffmpeg reads (H.264, H.265, AV1, etc.). |
.mov |
same | Same ffmpeg path; QuickTime container. |
ffmpeg on PATH.
Real video codecs (H.264 / HEVC / AV1) are not bundled with the
runtime — adding them would balloon the binary by tens of MB and
introduces real licensing complications. Instead, the engine
shells out to a system-installed
ffmpeg
at Asset.GetVideo time and reads back raw RGBA
frames + WAV audio.
Loading is therefore O(file length): a 30-second 720p clip can
take a couple of seconds the first time. Cache the resulting
VideoAsset in a Lua local if you need to play it
repeatedly.
ffmpeg
next to the launcher EXE (Windows) or document it as a runtime
dependency. If you can't ship ffmpeg with your game, pre-convert
the source MP4 / MOV to an animated GIF at build time — the
GIF path needs no system deps and works everywhere.
Video API
When true, advances back to frame 0 at the end. Toggle live, setting false mid-play lets the current playthrough finish then stops.
Frame index currently being shown. Reading is free; writing seeks the playhead immediately and resets the elapsed-ms accumulator.
Total length in seconds (FrameCount × FrameDelayMs ÷ 1000).
Pause and reset to frame 0.
Build an ImageAsset from the current frame. Cached per frame index, repeated calls during the same displayed frame return the same cheap asset. Useful if you want to feed a still snapshot into a GUI image or a part Texture without LinkPart.
Bind a BasePart so its Texture auto-updates each tick
the video advances. The engine swaps the part's Texture
with fresh frame pixels every video tick. Each BasePart
can only be linked to one Video at a time, calling
LinkPart again on a different video
transparently re-routes the binding.
Stop driving the part's Texture; the part keeps the last frame that was uploaded.