Update terminology from 'schedule' to 'sequencer' and add tests for project sequence steps

This commit is contained in:
2026-04-14 23:15:02 +02:00
parent 28515a418f
commit abdab08cd7
2 changed files with 132 additions and 7 deletions

View File

@@ -10943,7 +10943,7 @@ export function App({ store, initialStatusMessage }: AppProps) {
return;
default:
throw new Error(
"The current schedule effect does not expose a numeric value."
"The current sequencer effect does not expose a numeric value."
);
}
}
@@ -10971,7 +10971,7 @@ export function App({ store, initialStatusMessage }: AppProps) {
return;
default:
throw new Error(
"The current schedule effect does not expose a color value."
"The current sequencer effect does not expose a color value."
);
}
}
@@ -11346,11 +11346,11 @@ export function App({ store, initialStatusMessage }: AppProps) {
type="button"
onClick={() => setSchedulePaneOpen(true)}
>
Open Schedule
Open Sequencer
</button>
<div className="material-summary">
Actor routines now own time-based presence orchestration and
resolve through the shared control surface.
resolve through the shared sequencer/control surface path.
</div>
</div>
@@ -16123,10 +16123,10 @@ export function App({ store, initialStatusMessage }: AppProps) {
</div>
<div className="form-section">
<div className="label">Schedule</div>
<div className="label">Sequencer</div>
<div className="material-summary">
NPC presence is now orchestrated from the project
scheduler instead of this inspector.
sequencer instead of this inspector.
</div>
<button
className="toolbar__button toolbar__button--compact"
@@ -16146,7 +16146,7 @@ export function App({ store, initialStatusMessage }: AppProps) {
);
}}
>
Open Schedule
Open Sequencer
</button>
</div>

View File

@@ -0,0 +1,125 @@
import { describe, expect, it } from "vitest";
import {
createActorControlTargetRef,
createLightControlTargetRef,
createPlaySoundControlEffect,
createSetActorPresenceControlEffect,
createSetLightEnabledControlEffect,
createSoundEmitterControlTargetRef
} from "../../src/controls/control-surface";
import {
createControlInteractionLink,
createPlaySoundInteractionLink,
createStartDialogueInteractionLink,
createTeleportPlayerInteractionLink,
createToggleVisibilityInteractionLink
} from "../../src/interactions/interaction-links";
import { createProjectScheduleRoutine } from "../../src/scheduler/project-scheduler";
import {
getInteractionLinkSequenceSteps,
getProjectScheduleRoutineSequenceSteps
} from "../../src/sequencer/project-sequence-steps";
describe("project sequence steps", () => {
it("normalizes existing interaction link actions into shared sequence steps", () => {
const playSoundLink = createPlaySoundInteractionLink({
id: "link-play-sound",
sourceEntityId: "entity-trigger-main",
targetSoundEmitterId: "entity-sound-main"
});
const dialogueLink = createStartDialogueInteractionLink({
id: "link-start-dialogue",
sourceEntityId: "entity-trigger-main",
dialogueId: "dialogue-main"
});
const teleportLink = createTeleportPlayerInteractionLink({
id: "link-teleport",
sourceEntityId: "entity-trigger-main",
targetEntityId: "entity-teleport-target"
});
const visibilityLink = createToggleVisibilityInteractionLink({
id: "link-hide-brush",
sourceEntityId: "entity-trigger-main",
targetBrushId: "brush-main",
visible: false
});
expect(getInteractionLinkSequenceSteps(playSoundLink)).toEqual([
{
type: "controlEffect",
effect: createPlaySoundControlEffect({
target: createSoundEmitterControlTargetRef("entity-sound-main")
})
}
]);
expect(getInteractionLinkSequenceSteps(dialogueLink)).toEqual([
{
type: "startDialogue",
dialogueId: "dialogue-main"
}
]);
expect(getInteractionLinkSequenceSteps(teleportLink)).toEqual([
{
type: "teleportPlayer",
targetEntityId: "entity-teleport-target"
}
]);
expect(getInteractionLinkSequenceSteps(visibilityLink)).toEqual([
{
type: "toggleVisibility",
targetBrushId: "brush-main",
visible: false
}
]);
});
it("projects schedule routines into shared sequence steps", () => {
const actorTarget = createActorControlTargetRef("actor-guard");
const lightTarget = createLightControlTargetRef(
"pointLight",
"entity-point-light-main"
);
const actorRoutine = createProjectScheduleRoutine({
id: "routine-guard",
title: "Guard Duty",
target: actorTarget,
effects: [
createSetActorPresenceControlEffect({
target: actorTarget,
active: true
})
]
});
const lightRoutine = createProjectScheduleRoutine({
id: "routine-light",
title: "Night Light",
target: lightTarget,
effect: createSetLightEnabledControlEffect({
target: lightTarget,
enabled: false
})
});
const directControlLink = createControlInteractionLink({
id: "link-light-control",
sourceEntityId: "entity-trigger-main",
effect: createSetLightEnabledControlEffect({
target: lightTarget,
enabled: false
})
});
expect(getProjectScheduleRoutineSequenceSteps(actorRoutine)).toEqual([
{
type: "controlEffect",
effect: createSetActorPresenceControlEffect({
target: actorTarget,
active: true
})
}
]);
expect(getProjectScheduleRoutineSequenceSteps(lightRoutine)).toEqual(
getInteractionLinkSequenceSteps(directControlLink)
);
});
});