Types

Every public type lives in the Types module inside MotionFX. You rarely write them yourself: MotionFX's functions are already typed, so with --!strict your tracks are checked and names autocomplete as you type. This page covers the types you do write by hand, plus the shapes you'll meet in the editor.

Using the types

Require the Types module next to MotionFX. The most common reason is annotating what a Drive.Map function returns, because strict mode can't work out on its own that a table literal is a VignetteLayer or a ColorValue:

local Types = require(ReplicatedStorage.MotionFX.Types)

Driver = Drive.Map(envelope, function(amount: number): Types.VignetteLayer
	return { Intensity = amount, Color = Color3.fromRGB(120, 0, 0), Inset = 0.3 }
end)

-- Or annotate a whole definition you build ahead of time
local definition: Types.EffectDefinition = { Tracks = {} }

Names

export type PrimitiveName = "FOV" | "Position" | "Rotation" | "Blur" | "Color" | "Vignette" | "Sound" | "Overlay"

export type ImpactName = "Earthquake" | "Explosion" | "Shake" | "Recoil"
export type InjuryName = "Blood" | "Concussion" | "BrainDamage"

-- Custom presets are plain strings, so the union ends with `string`.
export type PresetName = ImpactName | InjuryName | string

export type ViewName = "Default" | "FirstPerson" | "ThirdPerson" | "BackView"

The same names are grouped in MotionFX.Enum, so FX.Impact.Explosion and "Explosion" are interchangeable.

EffectDefinition

export type EffectDefinition = {
	Duration: number?,           -- nil = inferred from the drivers
	FadeIn: number?,
	FadeOut: number?,
	Retrigger: RetriggerPolicy?, -- default "Stack"
	MaxInstances: number?,       -- cap for "Stack", default 8
	Tracks: { Track },
	Build: ((params: { [string]: any }) -> { Track })?,
}

export type RetriggerPolicy = "Stack" | "Refresh" | "Replace" | "Ignore"
FieldDescription
DurationA fixed length in seconds. If it is nil, the length is inferred.
FadeIn / FadeOutEffect-wide ramps. FadeOut covers the tail of a fixed duration, and it is also the default fade for Stop().
RetriggerSee Retrigger policies.
TracksThe fixed track list. It is required, so use {} if every track comes from Build.
BuildRuns on every Play() with PlayOptions.Params and returns additional tracks, for example a push toward Params.Direction.

Track

export type Track = FOVTrack | PositionTrack | RotationTrack | BlurTrack | ColorTrack | VignetteTrack | SoundTrack | OverlayTrack

Each track type is tagged by its Primitive, so once you write Primitive = "Rotation" the editor knows the track is a RotationTrack and checks its Driver. Their fields are listed on Primitives & Tracks, and which drivers each one accepts is in Which drivers fit.

The ready-made tracks return these same track types, and their option tables are ShakeConfig, KickConfig, EdgeConfig and so on, one per builder.

Overlay types

Used by overlays. OverlayConfig is the option table for Track.Overlay.

export type OverlaySheet = {
	Images: { string },   -- asset ids, in order
	Columns: number,
	Rows: number,
	FrameSize: Vector2?,  -- one frame's size in pixels; required when a sheet holds more than one frame
	Frames: number?,      -- total frames, if the last sheet isn't full (default: every cell)
	Fps: number?,         -- the frame rate it was made for; used when the track doesn't set one
}

export type OverlayTrack = {
	Primitive: "Overlay",
	Sheet: OverlaySheet,
	Driver: Driver<number>,                -- opacity, 0..1
	Fps: number?,                          -- default: the sheet's Fps, else 24
	Loop: boolean?,                        -- default true
	Color: Color3?,
	ScaleType: ("Stretch" | "Crop" | "Fit")?,
	Weight: number?,
	Delay: number?,
}

export type OverlayConfig = {
	Fps: number?, Loop: boolean?, Strength: number?, Color: Color3?,
	ScaleType: ("Stretch" | "Crop" | "Fit")?,
	Time: number?, Hold: number?, Release: number?, Delay: number?, Weight: number?,
}

CreateOptions

export type CreateOptions = {
	Overwrite: boolean?, -- default false: Create errors on a duplicate name
}

PlayOptions

export type PlayOptions = {
	Intensity: number?,  -- 0..1+ master scale (default 1)
	Duration: number?,   -- override the definition's duration
	Speed: number?,      -- time scale (default 1)
	FadeIn: number?,
	FadeOut: number?,
	Seed: number?,       -- deterministic noise
	Params: { [string]: any }?,
}

Handle

export type HandleState = "Playing" | "Stopping" | "Finished"

export type Handle = {
	Id: number,
	Name: string,
	State: HandleState,
	Intensity: number, -- read-only

	SetIntensity: (self: Handle, value: number, fadeTime: number?) -> (),
	Stop: (self: Handle, fadeTime: number?) -> (),

	Finished: Signal<>,
}

Finished is a small signal with Connect, Once and Wait, like a Roblox event. Connect and Once return a connection with Disconnect(). See Handle.

Value types

What each primitive's driver must produce. See Primitives & Tracks for what every field does.

-- FOV, Blur: number        Position, Rotation: Vector3        Vignette: number or VignetteLayer

export type VignetteLayer = {
	Intensity: number,
	Color: Color3?,
	Inset: number?,
	Size: number?,
	Image: string?,
}

ColorValue

export type ColorValue = {
	Tint: Color3?,         -- multiplied together across effects
	Saturation: number?,   -- summed
	Contrast: number?,     -- summed
	Brightness: number?,   -- summed
}

Driver

You only need these to write a custom driver. The config tables for Envelope, Noise and Spring are documented with each function on the Drive page.

export type Sampler<T> = (t: number, dt: number) -> T

export type Driver<T> = {
	Start: (context: PlayContext) -> Sampler<T>,
	Duration: number?, -- natural length; nil = runs until stopped
}

PlayContext

A new context is created for every Play(). Stateful drivers get fresh state, and Seed keeps noise deterministic when it is set through PlayOptions.Seed.

export type PlayContext = {
	Seed: number,
	Params: { [string]: any },
}

Easing

export type Easing = {
	Style: Enum.EasingStyle,
	Direction: Enum.EasingDirection,
}

ViewSettings

export type ViewSettings = {
	ShoulderOffset: Vector3,  -- ThirdPerson: camera-space (right, up, back) offset from the head
	BackViewDistance: number, -- BackView: studs in front of the character
	BackViewHeight: number,   -- BackView: studs above the head
	HeadHeight: number,       -- studs above the HumanoidRootPart
	Responsiveness: number,   -- smoothing: higher catches up faster
}