Scenario is a cutscene engine for Sphere which allows you to coordinate complex cutscenes and other actions (such as animations) using multiple timelines and cooperative multithreading.
The current version is
Scenario 3.8.1, released on
March 14, 2015.
Get the script:Changelog:v3.8.1- Added support for minisphere's IsSkippedFrame.
v3.8- Refactored entire codebase and added documentation comments for all methods and scenelets.
- Fixed bugs when forking inside of a doWhile loop where instructions inside the loop could overwrite each others' state.
- Changed doWhile and doIf to take a function (lambda) as argument. The function will be called at scene time and should return true or false to determine how to proceed.
- Removed scenelets doUntil and set.
v3.7.3- Hotfix for broken doIf and doUntil scenelets.
v3.7.2- Hotfix release to fix call scenelet regression in 3.7.
v3.7.1- Hotfix release to restore fork functionality which was completely broken in 3.7.
v3.7:- BREAKING CHANGE - Removed 'state' argument from all scenelet functions; scenelets should store state data using 'this' instead. Any custom scenelets will have to be rewritten.
- New optional finish handler for scenelets, called immediately after the scenelet stops running (i.e. when its update function returns false).
- Support for variables: Use set to set a variable; increment or decement to add or subtract 1 from its value, respectively. Variables can be accessed in scenelet code via scene.variables['var_name']
- New control-flow commands: doIf, doWhile, doUntil. doIf executes a block of commands only if a specified condition is met, the other two are similar but execute the same block repeatedly (loop) while or until the condition is met, respectively.
v3.6:- Renamed beginFork and endFork to fork and end, respectively.
- New scene looping feature: Pass 'true' to the Scenario() constructor for an endlessly looping scene. This is useful for running looping animations in the background. Call Scenario.stop() if you need to break the loop.
- New optional waitUntilDone argument for run() that mimics the old blocking behavior. Helpful for cutscenes.
- Color mask for the fadeTo command is now shared by all scenes and persists after a scene ends. Don't forget to fade back in or the player won't be able to see anything!
- Screen fades and camera manipulations are no longer reverted automatically at the end of a scene. This must now be done manually.
- Running a scene no longer clears its command queue. This lets you run the same scene more than once. Great for caching animation commands!
v3.5.4:- Sphere map engine is no longer required to be running to execute a scenario.
v3.5.3:- Running a scenario no longer detaches input automatically. If this is needed, you must detach and reattach the input yourself.
v3.5.2:- Added new commands marquee and tween. The latter is great for coordinating complex UI animations.
v3.5.1:- Removed unusable marquee command.
v3.5:- User is required to call Scenario.initialize before using the engine.
- Calls to Scenario.update and Scenario.render must be added to the update and render scripts, respectively.
- run() now returns immediately instead of running its own update loop. If your game relied on the old blocking behavior, you'll have to modify it.
- New method: scene.isRunning checks whether the scene is still executing and returns true if it is, false if not.
v3.1:- Built-in commands now use seconds instead of milliseconds for duration.
- Renamed 1 identifier:
- Added support for cascaded command calls. This is the preferred method for scene composition now; examples updated accordingly.
- Completed refactoring started in 3.0.
v3.0:- Major refactoring to make the codebase more readable and less bug-prone.
- Renamed 4 identifiers:
- defineAction -> defineCommand
- walkPerson -> movePerson
- execute -> run
- handleInput -> checkInput
How to use Scenario:First things first: The Sphere map engine must be running in order for Scenario to work. Then when you need a cutscene, you write something like this:
DetachInput();
new Scenario()
.marquee("Chapter 13: Some Random Girl Blows Up")
.movePerson("Katelyn", "north", 100, 2, true)
.pause(2.0) // 2-second delay
.killPerson("Katelyn")
.playSound("BigExplosion.wav")
.run(true); // true to wait until scene finished, false to run in background
AttachInput("hero");
The real power of Scenario, however, lies in its forking feature, which enables multiple simultaneous timelines. For example, you can have the background music (or the screen!) fade in while other actions take place at the same time. As in this example:
DetachInput();
new Scenario()
.fork() // fork the timeline
// we're fading in, so we specify a transparent color (alpha=0) to fade to
.fadeTo(CreateColor(0, 0, 0, 0), 5.0) // fade in over 5 seconds
.end() // end the fork block
.marquee("Chapter 13: Some Random Girl Blows Up")
.movePerson("Katelyn", "north", 100, 2, true)
.synchronize() // pause until all forks are finished - we want to make sure the fade-in has finished before she blows up!
.killPerson("Katelyn")
.playSound("BigExplosion.wav")
.run(true);
AttachInput("hero");
Starting with version 3.7, Scenario also includes support for conditional execution and looping.
// The following scene flashes the screen to white and back twice:
var flashes = 0;
new Scenario()
.doWhile(function() { return flashes++ < 2; }) // 2 iterations
.fadeTo(CreateColor(255, 255, 255, 255), 0.25)
.fadeTo(CreateColor(0, 0, 0, 0), 0.25)
.end()
.run();