Skip to content

Release v1.4.0: Stripe Cascade & Box Roll effects (total 30), project settings page, preview panel refactors - #280

Merged
EmbarrassingMoment merged 41 commits into
masterfrom
v1.4.0-dev
Sep 2, 2026
Merged

Release v1.4.0: Stripe Cascade & Box Roll effects (total 30), project settings page, preview panel refactors#280
EmbarrassingMoment merged 41 commits into
masterfrom
v1.4.0-dev

Conversation

@EmbarrassingMoment

Copy link
Copy Markdown
Owner

Summary

Merges the v1.4.0-dev development branch into master for the v1.4.0 release. Plugin version is bumped to 1.4.0 in TransitionFX.uplugin, and all effect-count references across docs are synced to 30.

Added

  • Stripe Cascade — staggered stripe wipe with adjustable count, 4-way direction, delay, and softness (DA_StripeCascade, M_Transition_StripeCascade, MF_StripePos).
  • Box Roll — boxes roll in from the right edge and stack row by row, with analytic AA (DA_BoxRoll, M_Transition_BoxRoll, MF_Rotate2D/MF_SdBox2D/MF_BoxDist/MF_RowDist).
  • Project Settings page (UTransitionFXSettings) under Project Settings > Plugins > TransitionFX, exposing the previously hardcoded effect pool cap as MaxPoolSizePerEffectClass.

Changed

  • Preview panel refactors: batch capture extracted into FTransitionPreviewBatchCaptureDriver, GIF capture into FTransitionPreviewGifCapture, sequence playback into UTransitionSequencePlayer. Editor-only, no behavior change.
  • Sample project build settings updated for UE 5.8 (BuildSettingsVersion.V7, Unreal5_8 include order, EngineAssociation 5.8). The plugin itself still targets UE 5.5+.
  • L_ShowCase preset list sorted alphabetically; showcases 29 of the 30 effects (DA_LinearWipe remains unreferenced).

Fixed

  • AspectRaitoAspectRatio output rename on MF_CorrectAspectRatio / MF_GetMaxScreenRadius (pin-connected consumers unaffected).
  • MaxResoluutionMaxResolution scalar parameter rename on M_Transition_Pixelate (built-in assets unaffected; projects overriding it by name must update).
  • Freeze / stack overflow when looping a sequence whose entries all have null presets — skipping is now iterative and an unplayable sequence completes immediately with a warning.

Reviewer notes

  • The full change list is in the [Unreleased] section of CHANGELOG.md (it should be re-titled to [1.4.0] with a date before tagging the release).
  • The local-only DevMaterialTools plugin (Python material/Blueprint authoring helpers) is included in the repo but excluded from the release ZIP by the release workflow.
  • No automated test suite; verified manually via the L_ShowCase level and the Transition Preview Panel.

🤖 Generated with Claude Code

EmbarrassingMoment and others added 30 commits July 19, 2026 10:05
…fect pool size

Introduce a UDeveloperSettings-based settings class (Project Settings >
Plugins > TransitionFX, saved to DefaultGame.ini) as the home for
plugin-wide configuration. The per-effect-class pool cap, previously
hardcoded at 3 in ReturnEffectToPool(), is now exposed as
MaxPoolSizePerEffectClass (0 disables pooling).

Update README roadmap (EN/JA), API reference, FAQ, performance
rationale, and CLAUDE.md to document the new setting.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…EffectClass

Document how to change the new plugin settings, both via
Project Settings > Plugins > TransitionFX and by editing
Config/DefaultGame.ini directly. Added to both EN and JA READMEs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tings

feat: add UTransitionFXSettings project settings with configurable effect pool size
The Pixelate effect has no preview GIF due to a limitation of the GIF
capture tool. Use an em dash in the Preview column of both English and
Japanese READMEs to make the omission intentional rather than looking
like a missing image.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VqaikZhu1fYC891QpZZBBC
Resolves the UBT [Upgrade] notices for both targets by accepting the
new defaults rather than staying on backward-compatible settings:

  - WindowsPlatform.bStrictInlineConformance = true
  - UndefinedIdentifierWarningLevel = Error
  - FPSemantics = Precise (Editor/Program targets)
  - ReturnTypeWarningLevel = Error
  - DanglingWarningLevel = Error
  - UnreachableCodeWarningLevel = Error

No overrides are needed - a full rebuild of TransitionFX and
TransitionFXEditor under the new defaults produces no warnings.

IncludeOrderVersion is pinned to Unreal5_8 rather than Latest;
Unreal5_5 is now below UBT's Oldest (Unreal5_6) in 5.8.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds `* text=auto` so text files are stored as LF in the repository and
checked out with the platform-native ending. Without it, editors writing
CRLF on Windows produced whole-file phantom diffs (core.autocrlf is false),
which repeatedly obscured real changes and caused stash/rebase conflicts.

Placement matters: the rule sits above the existing LFS entries because
later matching lines win, so `-text` on *.uasset, *.umap, *.png and friends
still overrides it and binary content is untouched. Verified with
`git check-attr` — those paths report `text: unset` and keep `filter: lfs`.

The 44 *.gif files under docs/images are binary but stored as regular blobs
rather than LFS, so they are marked `-text` explicitly rather than relying
on text=auto content sniffing.

Also runs `git add --renormalize .`, which rewrites release.yml and
TransitionFX.uplugin from CRLF to LF. Both are line-ending-only changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ttings-v7

build: adopt UE 5.8 build settings (V7) and include order
…ext-auto

chore: normalize line endings via .gitattributes
Completes the Phase 2 extraction planned since v1.2.0. Sequence step,
loop, and DelayAfter timer state moves out of UTransitionManagerSubsystem
into a dedicated UObject created lazily on the first PlaySequence call and
outered to the subsystem.

The subsystem keeps the Blueprint-facing API: it still validates sequences
(null / empty / level transition pending) and forwards PlaySequence and
StopSequence to the player, which drives StartTransition per entry and
broadcasts the subsystem's sequence delegates. The internal-dispatch guard
that keeps external StartTransition calls from interrupting a sequence is
now queried via SequencePlayer->IsDispatchingStep().

Hot-swap behaviour between steps and the ForceClear / Deinitialize teardown
order are unchanged. No public API or Blueprint-visible change.

Also extends DA_SequenceSamples with a DA_Hexagon entry so the sample
demonstrates a multi-effect sequence.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
EngineAssociation was still 5.5, so right-click project file generation
and Visual Studio builds resolved to UE 5.5's UnrealBuildTool, which cannot
parse the V7 target settings adopted in 6ec59b2:

  error CS0117: 'BuildSettingsVersion' does not contain a definition for 'V7'
  error CS0117: 'EngineIncludeOrderVersion' does not contain a definition for 'Unreal5_8'

Bumping the association to 5.8 lines the project up with those settings and
resolves the mismatched BuildRules assemblies the two toolchains were
fighting over.

UE 5.8 also emits .slnx solution files alongside .sln; ignore them the same
way, since they are generated output.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…classes

refactor: extract sequence playback into UTransitionSequencePlayer
Step 1 of splitting STransitionPreviewPanel (1,159 LOC): the single-GIF
capture pipeline (fixed-step frame grabbing, stabilize/wait-frame pacing,
save-path resolution, GIF89a encoding, notifications) moves into a
dedicated non-Slate engine owned by the panel via TUniquePtr.

The dependency direction is inverted at the capture boundary:

- The panel now resolves the destination at Start() time. Batch modes pass
  an explicit SavePath (and suppress the per-file success notification);
  interactive capture leaves it unset and gets the save dialog.
- Batch advancement hooks the engine's OnWriteFinished delegate instead of
  being called from inside the capture finalizer, so the engine knows
  nothing about batch mode. This is the seam the Step 2 batch-driver
  extraction will attach to.
- The viewport is held weakly and the easing curve is injected as a
  TFunction, keeping the engine free of panel state.

Behaviour intentionally preserved: batches still advance on write failure,
and OnWriteFinished does not fire on early aborts (pixel read failure,
dimension mismatch, dialog cancel) - matching the old finalizer's control
flow exactly.

The panel constructor is defined out-of-line because the TUniquePtr member
would otherwise instantiate its deleter in TUs that only see the forward
declaration (C4150).

STransitionPreviewPanel.cpp: 1,159 -> 1,023 lines. The batch drivers
(~330 lines, TRANSITIONFX_DEV_TOOLS) stay in the panel until Step 2.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…aptureDriver

Step 2 of splitting STransitionPreviewPanel: the dev-tools batch GIF
workflows (~330 lines under TRANSITIONFX_DEV_TOOLS) move into a dedicated
driver - the all-effects batch, the per-easing Iris batch, the
MISSING_IMAGES.md filename mappings, the output-folder dialog, and the
start/complete notifications.

The driver never touches Slate or the capture engine directly: it steers
the panel through an FPanelHooks callback struct (effect/easing selection,
capture kick-off, state queries) and advances on the capture engine's
OnWriteFinished, which the panel forwards. Both new files are wrapped
whole in #if TRANSITIONFX_DEV_TOOLS, so the default build compiles them
to nothing.

With the batch branches gone, StartGifCapture now takes an optional
SavePath (batch passes an explicit destination and suppresses the per-file
success toast; interactive capture gets the save dialog) - completing the
decoupling started in the Step 1 capture-engine extraction. The panel no
longer holds any batch state, and the notification/desktop-platform
includes move out with the code.

Verified against UE 5.8 in all three configurations: default
(TRANSITIONFX_DEV_TOOLS=0), with the flag flipped to 1 (the config that
actually compiles the batch code), and again after restoring 0.

STransitionPreviewPanel.cpp: 1,023 -> 725 lines (1,159 before Step 1).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…classes

refactor: split preview panel GIF capture into engine and batch driver
Also correct CLAUDE.md which documented the color parameter constant as
TransitionColor; the actual value in TransitionFXConfig.cpp is FadeColor.
The renamed parameter is not overridden by MI_Transition_Pixelate or any
preset, so the rename is safe.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…po-docs

fix: rename Pixelate material parameter MaxResoluution to MaxResolution
Critical fixes (docs contradicted the actual code/content):
- Replace all references to nonexistent M_Transition_Master with
  M_Transition_Fade (README EN/JA, Quick Start EN/JP, Preview Tool
  Manual, Performance Rationale)
- Preview Tool Manual: correct Mode pin values to the actual
  ETransitionMode enum (Forward / Reverse); TransitionIn/Out/InOut
  never existed
- FAQ EN/JP: replace nonexistent material parameter names with the
  real ones (TileCount -> GridSize / SplitCount, PetalCount -> Points,
  Seed -> RandomDelay, WaveFrequency -> Frequency)
- Fix 20 broken image links (docs/images/ prefix inside docs/,
  effect_diamondband.gif -> effect_diamond_wipe.gif, missing
  docs/images/ prefix in README effect table)
- API Reference EN/JP: document the previously missing Sequence API
  (PlaySequence, StopSequence, IsSequencePlaying,
  GetCurrentSequenceStep, Play Sequence And Wait, OnSequenceCompleted,
  OnSequenceStepChanged) and InvertTransition

Effect count updates (22/23/26 -> actual 28):
- README EN/JA, .uplugin description, Preview Tool Manual (incl. 6
  missing rows in the MI reference table), SHOWCASE_LEVEL.md preset
  list (now matches L_ShowCase's actual 28 referenced presets),
  CLAUDE.md
- Note in SHOWCASE_LEVEL.md / CLAUDE.md: DA_LinearWipe is the only
  effect not referenced by the current ShowCase level

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STuKbquer8chCBLyuJtSvP
Adds Model Context Protocol support and local MCP server config. Introduces .mcp.json (unreal-mcp HTTP endpoint) and Config/DefaultEditorPerProjectUserSettings.ini to autostart the ModelContextProtocol server on port 8000 (/mcp). Enables ModelContextProtocol, EditorToolset, and AllToolsets in the .uproject and updates .claude/settings.local.json to include the unreal-mcp server for local tooling. This enables editor integrations that rely on MCP.
Rename the function output pin on MF_CorrectAspectRatio and
MF_GetMaxScreenRadius from AspectRaito to AspectRatio. The 15
master materials consuming this output connect by pin index/GUID, so
their wiring is unaffected; only the pin label in the material editor
changes. Verified in-editor after recompile: all 15 consumers read the
renamed output, zero stale references.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…pectratio

fix: rename misspelled MF output AspectRaito to AspectRatio
…matches

docs: fix code/documentation mismatches (material names, params, counts, links)
…tries

UTransitionSequencePlayer::StartSequenceStep advanced past null-preset
entries by calling itself, and the loop wrap-around path never deferred
to a timer. A looping sequence whose entries all have a null preset
(e.g. a freshly created UTransitionSequence with bLoop enabled and
presets not yet assigned) therefore recursed without bound until the
game thread overflowed the stack.

- Skip null-preset entries iteratively, bounded at NumEntries + 1 slot
  visits so every entry is checked at most one full cycle
- A cycle with no playable entry now finishes the sequence with a
  warning (OnSequenceCompleted still fires, so PlaySequenceAndWait
  latent nodes do not hang)
- Guard against the Blueprint-writable Entries array being emptied at
  runtime while a step delay timer is pending, which would have hit an
  out-of-range Entries[0] access after the wrap

Loop-count semantics are unchanged: finite LoopCount still plays the
sequence (LoopCount + 1) times.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…set-recursion

fix: prevent infinite recursion when skipping null-preset sequence entries
Port of the sandbox Shadertoy StripeTransition builder, reworked for the
TransitionFX runtime contract: Progress-driven instead of Time-cycled,
Invert via MF_ApplyInvert, BGColor replaced by FadeColor, and analytic
1px AA replaced by a Smoothness-based asymmetric smoothstep window that
guarantees exact 0/1 coverage at Progress 0/1.

New assets (built via Unreal MCP, graph verified by readback):
- MF_StripePos material function (per-stripe local pos + index * delay)
- M_Transition_StripeCascade master (Direction/SplitCount/StripeDelay/
  Smoothness + the Progress/Invert/FadeColor triad)
- MI_Transition_StripeCascade instance
- DA_StripeCascade preset (PostProcessTransitionEffect, 1.0s, Linear)

Docs: CHANGELOG entry, README EN/JA Built-in Effects rows (GIF pending),
CLAUDE.md counts updated to 29 effects / 10 material functions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Usage to Python

Named Reroute Usage nodes created via create_material_expression stay
unlinked because Declaration/DeclarationGuid are plain UPROPERTY() and
invisible to Python. This editor-only plugin links them on the C++ side
(unreal.DevMaterialTools.create_named_reroute_usage[_in_function]).

Workspace tooling only: excluded from the release ZIP via release.yml
and kept out of the TransitionFX plugin.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…terialTools

CreateCommentInMaterial/InFunction + ClearComments* cover the second
Python-invisible surface (SizeX/SizeY plain UPROPERTY, EditorComments
array). Tools/ holds the asset dump script and the two builders that
rebuild MF_StripePos and M_Transition_StripeCascade in place.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nalytic AA

MF_StripePos and M_Transition_StripeCascade regenerated in place by the
DevMaterialTools python builders (ported from the sandbox StripeTransition
builders):

- GLSL-style locals documented as Named Reroute Declarations
  (targetPos/threshold/remainder/count in the MF; uv/R/pos/accel/fix/px/
  alpha/col in the master), reuses as linked Usages
- Smoothness constant replaced by analytic 1px AA along the transition
  axis (1/ViewSize.axis); fwidth would spike at stripe seams
- getFixTransition inlined (single call site): accel guarantees the last
  stripe closes exactly at Progress=1
- Parameter names (Direction/SplitCount/StripeDelay) and the
  Progress/Invert/FadeColor triad unchanged; MI/DA references intact

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
EmbarrassingMoment and others added 11 commits August 29, 2026 09:17
…tools

Rebuild Stripe Cascade via python builders with Named Reroute annotations
Port the sandbox rolling-box builders to the TransitionFX conventions:
MF_Rotate2D / MF_SdBox2D / MF_BoxDist (fp32-safe branchless select and
div-by-zero guard) / MF_RowDist, the M_Transition_BoxRoll master builder,
and build_boxroll_assets.py which creates the MI + DA preset and registers
the preset into L_ShowCase's level-BP preset array (CDO write + compile).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rolling boxes tumble in from the right edge and stack up row by row until
they cover the screen (Shadertoy-style port, built headlessly via the
DevMaterialTools builders).

- M_Transition_BoxRoll follows the shared master-material contract:
  PostProcess domain / SceneColorAfterTonemapping, lerp(scene, FadeColor,
  alpha) -> EmissiveColor, SmoothStep -> MF_ApplyInvert, and the
  Progress / Invert / FadeColor parameter triad. The sandbox Time+Hold
  loop is replaced by t = Progress * lastLand so the C++ runtime drives it.
- New SDF helper functions: MF_Rotate2D, MF_SdBox2D, MF_BoxDist (branchless
  select sd*valid + 1e9*(1-valid) to avoid fp32 cancellation, flight
  duration clamped to avoid NaN), MF_RowDist. mod() uses the existing
  MF_GLSLMod (A/B, Vector2) with a component mask restoring the scalar.
- Effect parameters: Rows, Speed, DTCol, DTRow; analytic 1.5 px AA.
- MI_Transition_BoxRoll + DA_BoxRoll (PostProcessTransitionEffect,
  EaseInOutSine, 3.0 s) and L_ShowCase registration as the 30th preset.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- README.md / README.ja.md: Box Roll row in the Built-in Effects table
  (after Tiles) with the new preview GIF; effect counts updated to 30
  (the Japanese README was still saying 28 since Stripe Cascade landed).
- CHANGELOG: Box Roll entry under Unreleased, header bumped to
  'Built-in Effects (+2, total 30)'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat: add Box Roll transition effect (30th built-in effect)
DA_StripeCascade was already added to the showcase in 5c76d84; this
reorders the level Blueprint's PostProcess soft-preset array so all 29
entries are in alphabetical order (DA_DiamondWipe/DA_Dissolve were
swapped), and updates the stale CLAUDE.md note.

Adds DevBlueprintTools to the local-only DevMaterialTools plugin:
Python-callable helpers to dump Blueprint graphs/pins and write
soft-object array properties that set_editor_property rejects
(non-instance-editable BP variables).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Resolved the L_ShowCase.umap conflict by taking the parent version
(which registers the new DA_BoxRoll as the 30th preset) and re-applying
the alphabetical sort, so all 30 entries are ordered A-Z. Updated the
CLAUDE.md effect counts for Box Roll (30 effects, 31 presets).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…cascade

showcase: sort L_ShowCase preset list alphabetically
Bump TransitionFX.uplugin VersionName from 1.3.0 to 1.4.0 (the numeric
Version code stays at 1, per the existing convention).

Also fix the documentation that never followed the Stripe Cascade
addition (28 -> 29 effects):

- .uplugin description: "Play 28" -> "Play 29" (this string is shown on
  Fab and in the editor plugin browser)
- Preview Tool manual: 28 -> 29 types, and add the missing
  MI_Transition_StripeCascade row to the reference list
- docs/SHOWCASE_LEVEL.md: 28 -> 29 presets and add StripeCascade to the
  preset list; L_ShowCase does reference DA_StripeCascade, so the note
  about DA_LinearWipe being the only omitted effect is now correct
- README.md / README.ja.md: the showcase level covers 28 of the 29
  built-in effects (DA_LinearWipe is still not in the level); the JA
  README was also stale at "28 effects" overall
- CLAUDE.md: L_ShowCase covers 28 of 29, only DA_LinearWipe is missing
- CHANGELOG.md: record the version bump and the doc updates under the
  existing Stripe Cascade entry

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… 30 effects

Box Roll landed on v1.4.0-dev after this branch synced counts to 29.
Resolved conflicts by taking the 30-effect totals and updated the
.uplugin description, Preview Tool manual, and SHOWCASE_LEVEL.md
(count + BoxRoll entries) to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nd-effect-count-docs

chore: bump plugin version to 1.4.0 and sync effect count to 29
@EmbarrassingMoment
EmbarrassingMoment merged commit e4cf0b1 into master Sep 2, 2026
@EmbarrassingMoment
EmbarrassingMoment deleted the v1.4.0-dev branch September 2, 2026 05:12
@EmbarrassingMoment
EmbarrassingMoment restored the v1.4.0-dev branch September 2, 2026 05:12
39-misaka-mikoto pushed a commit to Orlandry/TransitionFX_Dev that referenced this pull request Sep 2, 2026
v1.4.0 has been merged to master (PR EmbarrassingMoment#280), and the docs were synced as
part of that release, so the "documentation is behind the latest code
changes" note in README.md / README.ja.md no longer applies.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Js26XFn4jF1Cbnd6dnixSx
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