Skip to content

Changelog

All notable changes to this package will be documented in this file.

[Unreleased]

Changed (single-process slots)

  • Host process slots are single IProcess fields: every List<IProcess> body slot (reactor-target reactions Bool/Int/Float/Double/String/Vector3/GameObject/Event/Exclusive, ProcessReaction onBegin/whileRunning/onEnd, GameObjectCycleReaction onBegin/onEnd, BoolCycleReaction, ValueReference.onValueChanged) is now a single [SerializeReference] IProcess (process where it was processes). Run several processes by picking a Process List (sequential/parallel) in the slot. The List<IProcess> extension surface on ProcessRuns and ReactionProcessExtensions.Stop is removed; ReactionTargetAutoWire binds a single process. Example prefabs/scenes were rewritten in place (multi-entry lists wrapped in a parallel ProcessList); no migration path — dev-only change.

Added (graph-mandatory types)

  • [GraphMandatory] (Jungle.Attributes, inherited): marks types whose editing context is always the Execution Graph — the inspector shows the type row plus a full-width "☷ Open Graph" row, at any nesting depth. Applied only to structures that read as a graph: multi-process containers (ProcessList, SelectiveParallelProcess) and the PipelineOperation<T,TTarget> family (transform/float/color/… pipelines — complex operations over time). Simple commands (transform, rigidbody, …) always render their full inline inspector; the field's small ☷ icon button remains the optional way into the graph.
  • Graph-only inspector row keeps the type visible: the compact view no longer replaces the row with a lone button — the field keeps its swappable type pill (and count badge), and the Open Graph button spans a full row beneath it (TypeSelectableField + ContainerProcessDrawer via the new GraphOnlyFieldUI, which defers the compact decision to attach time so graph-window nodes stay inline).

Removed (graph-first mode)

  • "Graph-First Inspectors" toggle (Jungle.GraphFirstInspectors EditorPref, the Window/Jungle menu item, and the Project Settings toggle): graph-only inspectors are now purely type-driven via [GraphMandatory] — there is no mode that compacts single commands.

Added

  • Subject-scoped retrigger (RetriggerScope): non-Parallel retrigger strategies now apply only to live runs whose captured subject matches the incoming trigger's subject by default (RetriggerScope.SameSubject) — re-triggering a process for object A never disturbs object B's run. Opt back into the old behavior per call or per process with RetriggerScope.AllRuns. IRetriggerable gains an optional RetriggerScope member.
  • ProcessRetriggerStrategy.Buffer: queues the trigger and begins automatically when the in-scope live runs finish (coalesced per subject; dropped by explicit CompleteAll/Complete). Replaces the ProcessComponent/ProcessList-local buffering.
  • Execution Graph — transparent containers: a bare ProcessList no longer draws a card; its children splice into the parent flow as a chain (sequential) or bracketed lanes (parallel). Right-click the group for element actions.
  • Execution Graph — single-operation command collapse: a command holding exactly one operation renders as that operation's card, titled with the command's name (dimmed, as context) ahead of the operation pill, the command itself reduced to a target chip; a header "+" grows it back into the multi-operation view.
  • Execution Graph — structural drops: dragging a step BETWEEN cards moves it (also across lists when types allow); dropping it ONTO a card groups the two in a cross-axis ProcessList (parallel in a sequence, sequential in a lane), matching the add-chip semantics. Same-mode bare lists absorb drops instead of nesting; single-child wrappers keep auto-dissolving.
  • Context targets name their context: a value set to Context now repeats the description from the nearest enclosing [ProcessContext] slot. SmartX targets show it in the status pill — ⊙ the attaching object Context — replacing the duplicated "Context Context" the pill pair used to read; bare [SerializeReference] value fields read "Context (the attaching object)". Stays the plain type name outside a contextual slot, and the full context explanation is on the pill's tooltip.
  • Execution Graph — pipelines keep their zones inline: a pipeline nested in another graph now draws the same titled zone chain as the full view (Target ⟹ Modifiers ⟹ …), so its modifiers stay grouped in one "Modifiers" zone instead of scattering as loose cards into the surrounding flow. In vertical flow a single-card zone (Target) now stretches across its zone like the modifier chain does, instead of hugging the left edge.
  • Execution Graph — instant honesty: a command whose operations are all instant (Instant*Operation bases) draws them as a sequential chain — they run in list order, so parallel lanes were misleading.

Removed

  • "List Style" project setting (JungleListStyle, JungleSettings.ListStyle): Jungle lists now always use the collapsible foldout layout. Lists marked JungleListLayout.Flat or drawn inline keep their plain header, as before.
  • RetriggerBehavior enum and its fields on ProcessComponent and ProcessList: retrigger policy now lives at the run entry point only (BeginRun / ProcessComponent.RetriggerStrategy, both ProcessRetriggerStrategy). The legacy RetriggerBehaviorRetriggerStrategy migration shim (legacyRetriggerBehavior field + MigrateLegacyRetrigger) is gone; pre-consolidation example scenes were re-baked in place (all held Ignore, the field default — no behavior change) and no runtime remap remains. The ProcessList field is dropped (nested retrigger was a no-op by construction — a nested list's Begin is only ever called once per run by its parent). ProcessList re-begin now mirrors Command: ignored while running, complete-then-restart from paused.
  • Class-selection popup ordering (JungleClassInfoAttribute.Order): new optional Order named property (default int.MaxValue = unordered). Lower numbers appear first in the type picker; entries sharing an order fall back to alphabetical. A category's position floats up to its lowest-ordered member, so numbering one obvious entry pulls its whole category to the top. Sorting is centralized in TypePickerModel so the AdvancedDropdown, detailed window, and toggle-set list order identically. The obvious entries across the value, condition, filter, process, reaction, event, data, modifier, transform-target/applier/modifier, operation, constraint, and per-component action families are now numbered so the common picks surface first.
  • ProcessReaction.whileRunning slot (Jungle.Data, cycle reactions): the renamed EventCycleReaction (now ProcessReaction) gains a third process list that starts on cycle begin and is force-stopped on cycle end. Use for tweens, looping sounds, follow effects, or any process that should last exactly as long as the cycle.
  • Scene value type: SceneReference (build-safe scene link — drag a scene asset in the inspector), ISceneValue/ISettableSceneValue, inline SceneValue, and the generated SmartScene smart-value struct. Editor drawer SceneReferenceDrawer provides the scene drag field plus a Build Settings warning.
  • Scene commands/operations: SceneCommand hosting a list of ISceneOperation, with LoadSceneOperation (sync), LoadSceneAsyncOperation (background, optional activation gating), UnloadSceneOperation (async, optional wait), and SetActiveSceneOperation. Operations target an ISceneSource, so one op set covers every delivery mechanism.
  • Scene delivery modes: SceneReference gains a Delivery setting (SceneDeliveryMode.BuildSettings / Addressable) and the load/unload API the operations drive. Keeping this on the one concrete type — rather than a hierarchy of scene-source classes — is what lets SmartScene hold it inline and still offer a dynamic source. Addressable delivery goes through the ISceneDelivery hook that the optional Jungle.Addressables assembly registers, keyed by the asset GUID that SceneReference already stores (and which is a valid Addressables runtime key), so no Addressables types reach Jungle.Core. ISceneOperationHandle normalises Unity's AsyncOperation and Addressables' AsyncOperationHandle, including the activation gate both express differently. SceneLoadRegistry refcounts shared loads and holds the provider handle an Addressable unload needs.
  • Load Scene refuses non-blocking delivery: Addressables has no synchronous load, and faking one with WaitForCompletion blocks the main thread on the download for remote content. The operation now errors and points at Load Scene (Async) instead.
  • Scene object references: SceneObjectReference / SceneObjectReference<T> — a serializable link from an asset to an object in a scene, which Unity cannot serialize natively. Stores a SceneReference plus the target's SceneObjectId, and resolves through SceneObjectRegistry once the scene is loaded. Resolve() answers "is it here now"; Request() loads the owning scene on demand and calls back, paired with Release(). SceneObjectReferenceDrawer drives DragAndDrop directly (an ObjectField cannot accept a scene object on an asset) and stamps the marker component onto the drop target automatically.
  • Optional Addressables module (Jungle.Addressables asmdef, compiles only when com.unity.addressables is installed): AddressableSceneDelivery and AddressableSceneHandle, plugging Addressable scenes into the shared SceneCommand op set. New Jungle.Addressables.Editor asmdef contributes the inspector warning for a scene set to Addressable delivery that is not in an Addressables group, via SceneDeliveryWarnings. Zero impact when the package is absent.
  • ITraversableShape shape capability (Jungle.Spatial): opt-in interface (TraversalLength + DistanceToU) for shapes with a single measurable travel path. Implemented by LineShape, ArcShape, CircleShape, and CurveShape (delegates to the wrapped ICurve3D). PlaneShape/MeshUVShape deliberately do not implement it. Lets consumers walk any such shape at a constant world-units/sec speed regardless of how it parametrises U.

Changed

  • Execution Graph — scroll instead of squash: the vertical content column caps at 1100px instead of 640px, so wide windows are actually used. Cards now publish an explicit width floor while building — header chips at full size (including the hover-revealed "?"/"❖" actions and the floating edge chip), plus whatever their body needs — and side-by-side lanes publish the sum of theirs. The column adopts the deepest floor, which outranks the max-width cap: content that no longer fits widens the column and brings in the horizontal scrollbar rather than compressing the lanes. Header chips also opt out of flex-shrink; width pressure lands on the title and class pill, which ellipsize.
  • Execution Graph — one add per flow: the atomic-command header "+" now only shows while the card is collapsed. Expanded cards already carry the add at the end of their steps, so the same action no longer appears twice (title and end of sequence).
  • Attachment filter checks consolidated (Octoputs): the duplicate "Object Filter" pair (AttachableGameObjectFilterCheck, AttachmentPointGameObjectFilterCheck) was a strict superset of the "Filter" pair — same filter evaluation plus an IComponentLookupStrategy hop. The lookup field moved onto GameObjectFilterAttachableCheck / GameObjectFilterAttachmentPointCheck and the redundant pair was deleted, leaving one "Filter" entry per domain in the picker. Existing serialized references are redirected by two RenameTypeRule entries in the Jungle.Core migration manifest; the filter and lookup field data carries over verbatim. Assets using the kept checks are unaffected — a missing lookup resolves to Self, which is the previous behaviour.
  • EventCycleReactionProcessReaction (Jungle.Data): renamed to better reflect its new role as the no-autowire cycle reaction that hosts begin/while/end process slots. Class label is now "Process". Auto-migrated via [MovedFrom] — existing serialized references update on next inspector touch.
  • CurveTransformTargetShapeTraversalTransformTarget (breaking, Octoputs): the curve-only "Curve Transform" target is now a shape-agnostic "Walk Along Shape" target driven by ITraversableShape. Type rename is auto-migrated via [MovedFrom]. Field migration is NOT automatic: the old alignToTangent (bool) + tangentUp (Vector3) were replaced by the shared ShapeRotationMode enum (Preserve/AlignToShapeNormal/AlignToTangent/Override). Existing serialized data loads with rotationMode = Preserve — re-select the rotation mode on affected targets. Rotation now uses the shared shape normal as the tangent "up" instead of a per-target up vector (defaults are unchanged).
  • Editor chrome spacing harmonized (Jungle Core editor): one shared --jungle-foldout-indent (15px, = Unity's native nested-foldout margin-left) now drives section, subsection, list-nested-foldout and TypeSelectableField child indents — previously 4 divergent values (8/12/18/0px). New --jungle-section-gap token is the single knob a field-style variant may use to widen inter-section spacing (Pill's 6px moved off a raw .jungle-section-foldable rule onto the token). Inline / smart-value child rows no longer get a taller min-height:24 / looser padding:3px treatment — they use the same row metrics as every other TSF row. Pill min-height and .tsf__button size are unified across all four field styles, so row height no longer changes with the selected style. An expanded TSF keeps its list-box visual but no longer adds margin/padding, so opening a foldout no longer reflows siblings. The TSF label column is now stable: assigning or clearing a type no longer shifts the label. The drawInline branch also reserves the toggle slot (reserveSpace: true) so non-expandable TSF rows (smart-value / DrawInline) land their leading content/label in the same column as expandable TSF rows. Pill field style only: the header row's vertical padding is raised (_Pill.uss .tsf-row 5px top/bottom vs base 2px) so the Pill header isn't cramped; horizontal padding unchanged so the label column holds. Managed-ref types with [Subsection] but no top-level [Section] (e.g. SphereCastHitProvider) no longer render flush-left inside their TSF: in SectionedPropertyDrawer.CreateSectionElement the ungrouped branch tags each DIRECT property field with .jungle-section-ungrouped-property and indents it to the foldout- content column via .tsf__details .jungle-section-ungrouped-property (TSF-scoped — top-level inspectors unaffected). The indent lives on the property, not on the wrapping container, so a subsection-only ungrouped section (e.g. TransformTargetValue with only [Subsection] attributes) isn't double-indented — its subsections keep their natural position and contribute only their own content padding.

Fixed

  • TSF row hover no longer reads as "selected": a TypeSelectableField row used Unity's --unity-colors-highlight-background-hover — the selection blue — so hovering a row whose value is an ObjectField washed the whole field blue. It now uses the same neutral grey the expanded title strip and list headers already use (#3d3d3d / #b5b5b5 light).
  • Execution Graph — inline TSF child indent: the graph restates the 15px TSF child indent at a higher specificity than the base sheet's inline reset, so DrawInline values (e.g. a [SerializeReference] IGameObjectValue rendering as an ObjectField) sat 15px right of the plain fields beside them. The reset is restated for the graph too.
  • Execution Graph — field label column: fields in the graph now use the inspector's label metrics (45% of the row, floor 123px, ellipsis past that) so values line up in a column. Unity only applies those metrics inside an InspectorElement, which the graph window has none of, so labels used to size to their own text and every value started at a different x. Composite sub-fields (Vector3 x/y/z) keep their compact labels.
  • Execution Graph — add chip placement: a pipeline zone's "+" (Modifiers, target steps) now rides at the trailing edge of the zone's title row, like a card header's add button, instead of floating under the chain — in an empty zone it was the only thing on its line. The "+" that appends to a flow column moved to the trailing (right) edge too, instead of hugging the left flow line.
  • Empty [Section] foldouts: a section whose every field is hidden or claimed elsewhere (shown as a graph zone, for instance) is no longer drawn — "Targeting" and "Modifier Chain" stopped appearing as empty foldouts above the pipeline zones that hold their fields. Sections carrying a description keep their header.
  • SceneCommand / LoadSceneOperation preferred path over build index (Jungle Core): LoadSceneOperation and LoadSceneAsyncOperation now try BuildIndex first and fall back to ScenePath only when the index is unavailable. Prevents broken loads when scenes are renamed but their build index stays stable. SceneCommand also guards against null/unassigned SceneReference more defensively.
  • JungleTagFilter null-tag resilience (Jungle Core): JungleTagFilter no longer throws when a Tagger contains null tag entries or when the filter's own required tags list has nulls. Null entries are silently skipped during matching.
  • GameObjectFilter / Tagger null-safety (Jungle Core): GameObjectFilter base class and Tagger.HasTag handle destroyed or null GameObjects gracefully instead of throwing. GameObjectFilterAttachableCheck and GameObjectFilterAttachmentPointCheck (Octoputs) guard against null filter fields consistently with the "null = all allowed" convention.
  • ShapeProjectionTransformTarget ignored AlignToTangent (Octoputs): selecting the Align To Tangent rotation mode silently fell through to a no-op (only Preserve/AlignToShapeNormal/Override were handled). Rotation resolution for all shape-driven targets/modifiers is now a single shared ShapeRotation.Resolve so the four modes behave identically everywhere.
  • Inspector "Tools" section: the lone bottom-of-inspector "Open in Debug Window" button is now a regular Jungle-styled button inside a foldable "Tools" section (ComponentLevel importance, collapsed by default, state persisted), next to a new Open in Graph button. The graph button appears only when the component has graphable execution — one graphable property opens it directly, several open the component's graph browser. The section is omitted entirely when neither tool applies. The per-field "Open in Debug Window" link keeps its inline style.
  • Section model — one structure, importance only (breaking, editor API): every [Section] now renders as the same always-foldable Unity component-header bar that bleeds edge-to-edge across the inspector. The foldable-vs-static distinction and the five visual FoldoutStyle variants are gone. FoldoutStyle (Highlight/Normal/Discrete/Underline/TitleBar) and SectionFoldability (Inherit/Never/Always) and SectionAttribute.FoldableMode /SubsectionAttribute.FoldableMode were removed. New enum SectionImportance { Inner, Discrete, ComponentLevel } on SectionAttribute.Importance (default Inner) controls emphasis only — within the neutral grey family, no accent: ComponentLevel = standard grey bar, bold header, hairline separator (the strongest neutral read); Inner = same shape with a lighter grey bar (lighter than the list/TSF header) so nested sections recede a step; Discrete = no bar, muted normal-weight header, no separator. The category follows render context automatically: a section on a component inspector is promoted to ComponentLevel, while one nested inside a serialized sub-object stays Inner — set Importance explicitly only to override that (e.g. force a nested section to ComponentLevel, or Discrete anywhere). Edge-to-edge bleed still applies to every section (and still spans the container, not the window, inside the GraphWindow). Migration: drop FoldableMode = … from any [Section]/[Subsection] (all sections are foldable now); replace any Style = FoldoutStyle.X with Importance = SectionImportance.X (Discrete→Discrete, everything else→leave default and let context promote, or use ComponentLevel to force emphasis on a nested section).
  • Unified copy/paste context menu: right-clicking a type-selectable field or a Jungle list row now shows a single Copy / Paste (and Duplicate on list rows) instead of the previous mix of "Copy Value/Paste Value" and "Copy (Deep)/ Paste (Deep)/Duplicate (Deep)" that appeared in separate menus depending on where you clicked. The field's old immediate right-click menu (which preempted the list row's menu) was removed in favour of one UI Toolkit contextual menu; the list row contributes only Duplicate when an inner field already added Copy/Paste, so the menu never shows the same action twice. Dead "Copy Parent Value/Paste Parent Value" code (never wired) and the no-op mixed-selection copy were removed. Copy/Paste were always deep (independent instances) — only the labels changed.
  • Inline Jungle list add button: the inline [JungleList] layout no longer migrates the + onto the last row (which moved as rows expanded/collapsed). It now shows a single full-width "add new entry" bar that always sits under every row, including when the list is empty (the old "None" + tiny-+ empty row is gone). The bar text is contextual by default — "Add <ElementLabel>", falling back to "Add <singularized field name>" (so a "Bindings" field reads "Add Binding"). New JungleListAttribute.AddLabel overrides it per-site; inline-only — other layouts keep the header +. The bar is styled discreetly (small, muted) and brightens on hover.
  • Reactor "entries" renamed to "reactions": the per-source list on every reactor target is now reactions (was entries), and the reaction types are FloatReaction, IntReaction, BoolReaction, StringReaction, DoubleReaction, Vector3Reaction, GameObjectReaction, EventReaction, ExclusiveReaction, EventCycleReaction, GameObjectCycleReaction, BoolCycleReaction (were *TriggerEntry / *CycleEntry). The marker interface IReactorEntry is now IReaction and ICycleEntry is now ICycleReaction. Each reaction's inner body list is now processes (was reactions). Existing scenes/prefabs/assets migrate automatically via [FormerlySerializedAs] (fields) and [MovedFrom] (SerializeReference cycle reaction types) — no manual rewiring required.

[1.0.0] - 2024-01-01

  • Initial package structure extracted from the Jungle Core repository.
  • Added Unity Package Manager metadata and samples manifest.