Sections
Since 2.2.11Sections split an effect's Timeline into named stretches that repeat, branch, and can be switched from game code. A charge that lasts as long as the player holds a button, a magic circle that stays until it is dismissed, a laser that fires until it is let go: each is one effect with a start, a loop of unknown length, and an end.
How Sections Play
- A section starts where you place it and runs to the start of the next one. The last section runs to the end of the content.
- When a pass through a section ends, the clock goes back to the section's start while it has passes left. After its last pass it does what Then says.
- The clock jumps from the end of one pass straight to the start of the next, so the moment between them is never evaluated.
- Everything on the Timeline follows the clock. Animation, Activator, Speed, Audio and Post Process clips play again on every pass, and a signal inside a looping section fires on every pass.
- A Control clip that stays on across a loop keeps its object running. See On Section Loop.
- A Timeline without sections plays exactly as before.
Create Sections
The Sections row sits under the ruler. It appears once the Timeline has a section.
| Action | How |
|---|---|
| Start, loop and end in one go | Right-click the ruler and pick Quick create: start / loop / end. Only offered while the Timeline has no sections. It adds Start at 0, Loop at a third of the content repeating forever, and End at two thirds as the release section. |
| Add one section | Right-click the ruler and pick Add section here, or double-click an empty part of the Sections row. |
| Move a section's start | Drag the left edge of its band. It snaps to clip edges, markers, keys and the playhead; hold Ctrl to place it freely. A drag never passes the neighbouring sections. |
| Rename | Double-click the band, or pick Rename... in its menu. Jumps to the section and the release section follow the new name. |
| Remove | Select the band and press Delete, or pick Remove in its menu. |
Every edit can be undone. Faint lines run down the lanes at each section start, and clips, markers and keys snap to section starts, so content lines up with the sections.
Section Settings
Click a band to edit its section in the Inspector.
| Setting | Values | Meaning |
|---|---|---|
| Name | text | Unique in the Timeline. Java code and commands refer to sections by name. |
| Start | tick | Where the section begins. |
| Repeat | Once, N times, Forever | How many passes it plays. Forever repeats until the effect is moved on or stopped. |
| Then | Carry on, End, → a section | After its last pass: run on into the next section, end the Timeline here, or jump to another section. |
| Release Section | No, Yes | Yes makes this the section that stopping the effect plays. A Timeline has at most one. |
| Timing | At once, After this pass | Shown for the release section: start it at the next tick, or when the current pass ends. |
The band shows the settings at a glance:
| Mark | Meaning |
|---|---|
| Loop icon | Repeats forever. |
×3 | Repeats three times. |
■ | Then: End. |
→ Idle | Then: jump to Idle. |
| Amber left edge | The release section. |
Blue band, #2 | The section the preview is in, and which pass it is on. |
| Red band | Empty: it shares its start with another section, or starts after the content ends. Empty sections are left out at runtime, with a warning in the log. |
A band's right-click menu has Then ▸, Repeat ▸, Set as release section, Copy command, Rename... and Remove. Copy command copies a /photon fx section command that jumps to the section.
Preview
While the Timeline has sections, three buttons appear on the right of the transport bar, and the Sections row highlights the section the preview is in.
| Button | What it does |
|---|---|
| Advance | Stops repeating the current section. When this pass ends, it goes where Then says, as advance() does in game. |
| Release | Stops the effect the way the game does with destroy(false): the release section plays, then everything winds down. |
| Follow | On (default): repeats and jumps play as they do in game. Off: every section plays once, in time order. |
While the preview plays with Follow on, a band's menu also offers Jump here now and Jump here after this pass. Scrubbing and seeking always play the sections in time order, so the playhead lands where a fresh replay from the start would.
The Release Section
destroy(false) plays the release section first when the Timeline has one, then winds everything down. Most ways an effect stops call it: an entity dying, a block changing, /photon fx remove ... false, and mod code that stops an effect without forcing it. destroy(true) still removes everything at once, and a Timeline without a release section stops exactly as before.
While the release plays:
- the effect is no longer valid to its owner (
isValid()is false), so its executor lets go at once and a new effect can start on the same anchor while the old one finishes; - it takes no more requests;
- a Forever section plays once, and going back into a section already played on the way out ends the Timeline, so a release always ends;
- lights and light emission stay on until the remnants are gone.
An FX instance inside an effect that stops plays its own source's release section, if the source has one.
TIP
Give the release section a fixed length: Repeat Once, and Then Carry on or End. Started with release() rather than destroy(false), a Forever release section would loop forever.
In Game
Commands
/photon fx section entity <targets> <action> [fx id]
/photon fx section block <x y z> <action> [fx id]| Action | Effect |
|---|---|
jump <section> | From the next tick, play from the start of the section. |
queue <section> | When the current pass ends, go to the section instead. The switch is seamless. |
advance | Stop repeating. After this pass, go where Then says. |
release | Go to the release section, at once or after this pass as its Timing says. |
/photon fx section entity @s jump Vanish
/photon fx section block ~ ~ ~5 advance
/photon fx section entity @e[type=minecraft:zombie,distance=..8] queue "Big Bang" photon:spells/chargeQuote a section name that has spaces. The optional fx id limits the command to that effect. To stop an effect and play its release section, use /photon fx remove ... false.
Java
A laser that fires as long as a button is held needs nothing while it is held: Fire repeats forever. Stopping it plays Stop:
var executor = new EntityEffectExecutor(fx, level, player, EntityEffectExecutor.AutoRotate.LOOK);
executor.start();
// when the button is let go
executor.getRuntime().destroy(false); // plays Stop, then endsFXRuntime#sections() returns the effect's SectionControl:
| Method | Meaning |
|---|---|
hasSections() | Whether the Timeline has sections. |
names() | The section names, in time order. |
current() | The section playing, or a requested jump's target. null before the first section and after the end. |
pass() | Passes completed through the current section. |
jumpTo(name) | From the next tick, play from the start of name. |
queue(name) | When this pass ends, go to name instead. A later queue replaces an earlier one. |
advance() | Stop repeating; after this pass, go where Then says. |
release() | Go to the release section. Unlike destroy(false), the effect stays yours: you can jump back and release again. |
isReleased() / hasRelease() | Whether a release is under way or done / whether the Timeline has a release section. |
The requests return false when they do nothing: the section does not exist, the Timeline has ended or stopped, the effect is being stopped, advance() is called before the first section, or release() has no release section to go to or already went.
A charge attack that blasts only when fully charged:
var sections = executor.getRuntime().sections();
if ("Charged".equals(sections.current())) {
executor.getRuntime().destroy(false); // the release section: Blast
} else {
sections.jumpTo("Fizzle"); // let go too early
}Start an effect from a section instead of from 0, for example to bring back a persistent effect after a chunk reload without replaying its opening:
executor.setStartSection("Idle"); // before start()
executor.start();
// or, on a runtime you emit yourself:
runtime.emit(executor, 0, "Idle");An FX instance has sections of its own: ((FXInstanceObject) runtime.findObject("circle")).sections(). See FX Instances.
Client thread
Call SectionControl on the client thread. Sections run on each client, so two clients can switch a tick apart.
Limits
- A jump moves animated poses at once. Queue the jump to switch at the end of a pass, or make the poses meet.
- Audio clips loop on their own, not with the sections.
setRate(0)freezes the release section too./photon fx remove ... truecannot cut short an effect that is already playing its release, because the effect has left its executor. Java code that keeps the runtime can calldestroy(true).
Related
- On Exit and On Section Loop decide what Control clips do when they end and when a section loops.
- Lifetime Mode makes particles that loop until their emitter is stopped.
- FXRuntime Lifecycle covers
emit,destroyand the state queries.