Skip to content

Timeline Commands Reference

SuitIThub edited this page Jun 27, 2026 · 4 revisions

Timeline commands reference

Command type IDs are defined in TimelineCommandFactory.Create(). Each command serializes to JSON in timeline.json with a "type" field matching these IDs.

Table of contents

  1. Input simulation
  2. Flow control
  3. CopyScript
  4. Screenshots
  5. Studio / scene
  6. Pose
  7. Variables & logic
  8. VNGE
  9. Other
  10. Adding new commands

Input simulation

Type ID Command Purpose
simulate_key SimulateKeyCommand Send key combo (Ctrl+A, F5, etc.)
simulate_mouse SimulateMouseCommand Mouse button click
move_mouse MoveMouseCommand Move cursor to position
scroll ScrollCommand Mouse wheel scroll

Flow control

Type ID Command Purpose
pause PauseCommand Wait for duration
loop LoopCommand Repeat section
checkpoint CheckpointCommand Mark checkpoint
jump JumpToCheckpointCommand Jump to checkpoint
confirm ConfirmCommand Wait for user confirm
resolve_on_issue ResolveOnIssueCommand Branch on issue flag
resolve_on_count ResolveOnCountCommand Branch on counter
sub_timeline SubTimelineCommand Run nested timeline
sub_timeline_param SubTimelineParamCommand Sub-timeline with params
sub_if SubBlockIfCommand Start of a block-if (main timeline or sub-timeline)
sub_elseif SubBlockElseIfCommand Additional conditional branch
sub_else SubBlockElseCommand Default branch
sub_endif SubBlockEndIfCommand End of the block-if
return ReturnCommand Return from sub-timeline
label LabelCommand Label marker

Block-if (sub_if / sub_elseif / sub_else / sub_endif)

A structural if / else if* / else / end construct that works on the main timeline and inside sub-timelines (the add buttons live in the Subtimeline category). Blocks may be repeated and nested freely. Unlike the checkpoint-based while, these branch by position in the list rather than by jumping to a named checkpoint.

Rules

  • Every sub_if must be balanced by a matching sub_endif (End If is mandatory). Between them: any number of sub_elseif, then at most one sub_else. Order within a block must be IfElse If* → ElseEnd If. Nested blocks are matched by depth like brackets.
  • Violations are shown on the offending row and block Start.
  • The conditions in sub_if / sub_elseif behave exactly like the while command (same operands, operators, Not).
  • sub_else and sub_endif have no condition.

Execution

  • If true → run the commands directly below it; when the block reaches the next same-level marker (Else If / Else), jump to its matching End If.
  • If false → evaluate each Else If in turn; the first true one runs its block. If none match, the Else block runs.
  • After a taken branch finishes, execution continues after End If.

Example "CheckMood" (works the same on the main timeline or in a sub-timeline)

1. Set        mood = "happy"     (normal command)
2. If         mood == "happy"
3.   Pose Apply "smile"
4. Else If    mood == "sad"
5.   Pose Apply "cry"
6. Else
7.   Pose Apply "neutral"
8. End If
9. Screenshot                    (runs after the block)
  • mood = "happy" → 1 → 2 (true) → 3 → jump to 8 → 9
  • mood = "sad" → 1 → 2 (false) → 4 (true) → 5 → jump to 8 → 9
  • mood = "angry" → 1 → 2 (false) → 4 (false) → 6 (else) → 7 → 8 → 9

CopyScript

Type ID Command Purpose
start_tracking StartTrackingCommand Start file tracking
stop_tracking StopTrackingCommand Stop tracking
copy_rename CopyRenameCommand Copy/rename tracked files
clear_tracked ClearTrackedFilesCommand Clear tracked list
set_source_path SetSourcePathCommand Set source path
set_destination_path SetDestinationPathCommand Set destination
set_name_pattern SetNamePatternCommand Set rename pattern
set_rule_counter SetCounterRuleCommand Counter rule
set_rule_list SetListRuleCommand List rule
set_rule_batch SetBatchRuleCommand Batch rule

Screenshots

Type ID Command Purpose
screenshot ScreenshotCommand Take screenshot
wait_screenshot WaitForScreenshotCommand Wait for screenshot plugin
wait_empty_screenshots WaitForEmptyScreenshotsCommand Wait until queue empty
screenshot_alpha ScreenshotAlphaModeCommand Alpha mode
screenshot_resolution ScreenshotResolutionCommand Resolution
screenshot_save_path ScreenshotSavePathCommand Save path
screenshot_alt_path_var ScreenshotAltPathVarCommand Alt path variable

Studio / scene

Type ID Command Purpose
clothing_state ClothingStateCommand Clothing on/off states
accessory_state AccessoryStateCommand Accessory states
gdc_wardrobe_state GdcWardrobeStateCommand Enable/disable all GDC Wardrobe layers
outfit_rotate OutfitRotateCommand Rotate outfit
outfit_by_name OutfitByNameCommand Select outfit by name
set_camera_by_name SetCameraByNameCommand Select camera
select_object_by_name SelectObjectByNameCommand Select workspace object
set_object_visible_by_name SetObjectVisibleByNameCommand Toggle visibility
replace_chara_card ReplaceCharaCardCommand Load chara from UserData/chara/
load_coordinate_card LoadCoordinateCardCommand Load coordinate card
pose_library PoseLibraryCommand Pose library interaction
sound SoundCommand Play sound

clothing_state / accessory_state apply the chosen state directly to the currently selected character(s) via OCIChar (clothing: SetClothesStateAll/SetClothesState; accessory: ShowAccessory). The Anim/Attitude manipulate panel does not need to be open, and the state is applied to every selected character. If no character is selected, the command does nothing and logs a warning.

gdc_wardrobe_state enables (On) or disables (Off) all layers of the GDC Wardrobe plugin at once. Each GDC layer is a GameObject on the character named GDCLayer_*; the plugin's per-layer toggle just calls SetActive on it, so the command does the same directly on every such GameObject (across all characters, including currently inactive ones). The GDC window does not need to be open, but it also won't refresh its own checkboxes when toggled this way.

Pose

Type ID Command Purpose
pose_apply PoseApplyCommand Apply a Pose Browser pose by path (interpolatable). Optionally target a single character by name
pose_apply_group PoseApplyGroupCommand Apply a Pose Browser pose group by path. Optionally target a set of characters by name

Path for pose_apply is the pose file's path relative to studio/pose (e.g. MyFolder/cool pose.png); an absolute path also works. Path for pose_apply_group is the group name (the group id also works). Both are obtained via the Copy path button in the Pose Browser (on a pose or on a group). Requires the Pose Browser plugin to be installed.

  • pose_apply: with Character off it applies to the workspace selection; with Character on it looks up the single scene character with the given (interpolatable) name and applies the pose to that character.
  • pose_apply_group: with Characters off it applies to the workspace selection; with Characters on the character set comes either from a list variable (whose items are character names) or from an inline list edited in the command. Names are resolved to scene characters. The Pose Browser priority list is applied in all cases.

Variables & logic

Type ID Command Purpose
set SetVariableCommand Set variable
set_string SetStringCommand Set string variable
set_integer SetIntegerCommand Set integer
get GetVariableCommand Read variable
calc CalcCommand Arithmetic
if WhileCommand Conditional jump to checkpoint (do-while loop)
str_replace StrReplaceCommand String replace
str_split StrSplitCommand Split a string into a list variable
list ListCommand List operations
range RangeCommand Cycle a variable through a set of numbers/ranges

Condition operators (used by while and the block-if commands): ==, , <, , >, , plus three membership operators where the right field is a variable name (a list, a dict, or a string holding a range expression):

  • ∈F — left equals the first element (list) / first number (range).
  • ∈L — left equals the last element (list) / last number (range).
  • in — left is contained in the right: any element of a list, any number of a range, or a key or value of a dict. | set_list | SetListCommand | Set list variable | | list_insert | ListInsertCommand | Insert list item | | list_remove | ListRemoveCommand | Remove list item | | list_apply_dict | ListApplyDictCommand | Apply dict to list | | dict_set | DictSetCommand | Dictionary set | | dict_get | DictGetCommand | Dictionary get |

list drives a string variable from a list of values (an inline list or a list variable). A mode button selects the behaviour: next (default, advance through the values cycling), rev (advance from last to first), first (always the first value), last (always the last value), get (read the value at a specific index), length (store the number of items as a number). In get mode the source is always a list variable (the inline-list option is hidden); an extra Idx field gives the index (interpolatable) and a 1-based toggle switches between 0-based (default) and 1-based indexing; an out-of-range index is skipped with a warning. length works on an empty list too (stores 0).

range drives a variable from a sequence of numbers each time it runs. The sequence comes from an interpolatable text field of comma-separated single numbers and/or inclusive ranges: 1-10, 1,2,3,5, 1-3,6, 1-10,12,14-20. A descending range like 5-1 counts down. A mode button selects the behaviour:

  • next (default) — write the next value, cycling. 1-51, 2, 3, 4, 5, 1, … (stored as int).
  • rev — like next but from the last value to the first. 1-55, 4, 3, 2, 1, 5, … (int).
  • first — always the first value of the whole range (int).
  • last — always the last value of the whole range (int).
  • list — write the whole expanded range into a list variable, e.g. 1-3,6[1, 2, 3, 6].

The target variable is created if it doesn't exist yet (an int for next/rev/first/last, a list for list mode).

str_split splits a Source string by a Separator and writes the parts into a List var (created if absent). Source and separator both support interpolation (e.g. {myVar}). An empty separator yields a single-element list containing the whole source. Pairs naturally with list in get mode to read individual parts.

VNGE (requires modified VNGE)

Type ID Command Purpose
vnge_scene_next VngeSceneNextCommand Next scene
vnge_scene_prev VngeScenePrevCommand Previous scene
vnge_next_scene VngeNextSceneCommand Next scene alt
vnge_prev_scene VngePrevSceneCommand Prev scene alt
vnge_load_scene VngeLoadSceneByIndexCommand Load scene by index

Other

Type ID Command Purpose
video_record VideoRecordCommand Video recording
get_fashion GetFashionCommand FashionLine data
display DisplayCommand Open/close a floating window showing a variable's live value

display takes a variable name (type string, int, or bool) and a mode button: open (default) or close. In open mode it opens a movable, resizable window with the variable name (top) and its current value (large, below); the value updates live while the timeline runs. Each window has a close button and a pin button (top-right) — pinning persists that window's position/size for the variable across runs and sessions. Opening a window for a variable that already has one is a no-op. In close mode it closes the window for that variable. All Display windows also close automatically when the timeline ends.

Instead of a variable name you can enter an override token. Currently supported:

  • %TIME — elapsed run time of the timeline, formatted HH:MM:SS.

Overrides are defined in DisplayOverrides.cs; add an entry there to extend the set.

Adding new commands (developers)

See .cursor/skills/create-timeline-command/ in the repository:

  1. Create src/Timeline/YourCommand.cs extending TimelineCommand
  2. Register type ID in TimelineCommandFactory.cs
  3. Add UI in ActionTimelineWindow if needed

Navigation: ← Timeline · Timeline commands · Next: SearchBarManager →

Clone this wiki locally