Skip to content

Implement Transition Tree plugin - #1

Merged
ZombieHDGaming merged 2 commits into
masterfrom
claude/transition-tree-obs-plugin-mvxy98
Aug 18, 2026
Merged

Implement Transition Tree plugin#1
ZombieHDGaming merged 2 commits into
masterfrom
claude/transition-tree-obs-plugin-mvxy98

Conversation

@ZombieHDGaming

Copy link
Copy Markdown
Contributor

Turns the plugin template into the full Transition Tree plugin: ~4,400 lines across a model, resolution engine, Qt editor, and obs-websocket vendor.

How it applies transitions

Same mechanism Exeldro's Transition Table uses, because it's the only one OBS supports: the plugin never performs a transition itself. Before each switch it writes OBS's own per-scene override (transition / transition_duration private settings) onto every scene that could be the next destination, and OBS's GetOverrideTransition() picks it up. Overrides are recomputed on transition_start, channel_change and SCENE_CHANGED, for every canvas.

One improvement over the reference: the plugin tracks which scenes it wrote to, and only clears those. A transition override you set in OBS yourself survives unless a mark actually targets that scene.

What's implemented

Presets — each is local (scene collection blob) or global (global-presets.json in the plugin config dir), switchable per preset. Every scene collection remembers its own active preset. Global presets whose scenes are missing from the current collection are kept, shown in red, and skipped at runtime.

Multiple transitions per mark — sequential, random, random-no-immediate-repeat, and weighted, with per-candidate duration and weight.

The selection timing is the subtle part: picks are armed on arrival at a scene and held until departure, so each switch consumes exactly one random roll rather than re-rolling on every incidental signal. Sequential positions advance only for the mark that actually fired, detected by comparing the program scene against the armed pick.

Scene matching — explicit scene lists (multi-scene), Any, and Any except … on both sides. Resolution is most-specific-first, from-side dominant (A → not-C beats Any → D, loses to A → D), ties going to the first-listed mark.

Editor — a tree grouped by from-scene with a detail panel. This is the fix for the reported Transition Table UX problem: there, fromCombo/toCombo are simultaneously the add-row inputs and the table filter, so picking a scene to add a mark hides every unrelated row. Here the search box only filters the view and "Add Mark" is a separate button, so narrowing the list can never hide the controls needed to create one.

Hotkeys — per-preset activation (registered dynamically, bindings survive renames by matching on hotkey id), next/previous preset, and a global enable/disable pair.

obs-websocket — vendor transition-tree with preset and mark control plus a preset_changed event, and Transition Table's get_transition / set_transition / get_table under the same names for script compatibility. Requests are marshalled onto the Qt main thread so they stay race-free while still answering synchronously.

Import/export — versioned JSON, accepting our format, a bare preset, and Transition Table exports. If a scene collection has Transition Table data and no Transition Tree data, the plugin offers once to migrate it.

Creating transitions — OBS exposes no API for adding a transition to its list (obs_frontend_get_transitions only reads it; OBS resolves names against the main window's transitions combo, and only what's in that combo persists). The "New Transition…" button therefore drives OBS's own transitionAdd button, so the transition is initialised, named and saved exactly as if added from the transitions dock. Injecting a private source into the combo directly was rejected — it skips OBS's private InitTransition(), which wires the transition_stop signals that re-enable the transition widgets.

Verification

  • All five translation units compile clean (-Wall -Wextra) against the real OBS 31.1.1 headers and Qt6, including the generated moc output.
  • CMakeLists.txt configures correctly (fails only at find_package(libobs), expected without OBS installed).
  • clang-format-19 and gersemi both clean, matching what CI runs.

Not verified: runtime behaviour. There's no OBS instance here, so this proves it compiles, not that transitions fire correctly. Worth a local smoke test of a scene switch, a preset hotkey, and the sequential/weighted picking before merging.

Notes

  • Requires OBS 31.1+ (the canvas API).
  • Running Transition Table alongside is not supported — both write the same per-scene settings. Detected at load, logged, and surfaced once in the window.
  • Metadata set to transition-tree / Voidscape Development / https://voidscape.dev / dev.voidscape.transition-tree, version 0.1.0. GPL-2.0, crediting Transition Table as prior art.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MBcrZqvWJy32tBVg5i9VD9


Generated by Claude Code

claude added 2 commits August 18, 2026 20:21
Adds a full OBS Studio plugin for per-switch transition rules, covering the
feature set of Exeldro's Transition Table and extending it.

Marks are applied the same way Transition Table does it: OBS's own per-scene
transition override is written on every possible destination scene before a
switch, and OBS picks it up. Only scenes the plugin itself wrote to are ever
cleared again, so overrides set in OBS directly are left alone.

Features:

- Presets, each stored either locally in the scene collection or globally in
  the plugin config dir. Every scene collection remembers its own active preset.
- Several transitions per mark, chosen sequentially, at random, at random
  without immediate repeat, or by weighted random. The pick is made on arrival
  at a scene and held until departure, so each switch consumes one roll;
  sequential positions advance only for the mark that actually fired.
- Scene matching by explicit list, "any", or "any except", on both sides.
  Resolution prefers the most specific match, from-side first.
- Per-mark enable/disable, falling through to the next matching rule.
- Editor grouped as a tree by from-scene with a detail panel. The search box
  only filters the view; adding a mark is a separate button, so narrowing the
  list cannot hide the controls needed to create one.
- Hotkeys for per-preset activation, next/previous preset, and a global
  enable/disable pair.
- obs-websocket vendor "transition-tree" for preset and mark control, plus
  Transition Table's request names for compatibility, and a proc handler.
- JSON import/export, accepting Transition Table exports, and a one-time offer
  to migrate Transition Table data found in a scene collection.
- Creating transitions from the window by driving OBS's own add-transition
  flow, since no public API exists for registering one.

Warns when Transition Table is loaded alongside, as both write the same
per-scene settings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MBcrZqvWJy32tBVg5i9VD9
All three platform builds failed with "QDialog: No such file or directory".
The `template` preset that every other preset inherits from pins
ENABLE_FRONTEND_API and ENABLE_QT to false, and a preset cache variable
overrides the option() default in CMakeLists.txt, so flipping the defaults
there had no effect on preset-driven builds.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MBcrZqvWJy32tBVg5i9VD9
@ZombieHDGaming
ZombieHDGaming merged commit 7d6e07a into master Aug 18, 2026
6 checks passed
@ZombieHDGaming
ZombieHDGaming deleted the claude/transition-tree-obs-plugin-mvxy98 branch August 18, 2026 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants