Skip to content
Enthalpy-AC edited this page Oct 16, 2021 · 28 revisions

Catalysis Documentation

Welcome to the Catalysis documentation. Catalysis is an executable of a Python file, created by Enthalpy to convert text files into valid v6 trials. After familiarizing yourself with the syntax, use of Catalysis allows for extremely rapid scripting, compared to standard v6 and even v5.

Table of Contents

Changes/Notes

October 16 2021

  • Added three-line detection capabilities.
  • Added fade support.
  • Added support for appearance and disappearance modes.
  • Updated auto-uploader to work with new host.
  • Changed a bare prefix to call set_sprite rather than speaker_id

October 9 2016

  • Bugfix where Catalysis would not terminate after a bad number of lines.
  • The Windows executable can now be used for people with versions earlier than 10.
  • Minor refactoring.

October 2

  • Fixed to the internal loop.
  • Addition of an autohide action.
  • Added error catching on the number of errors allowable in selector.txt.

October 1

  • Fixed a bug where the pause of a colon couldn't be changed.
  • Allowed Catalysis to run in a loop.

September 30

  • Allowed pausing of em dashes and en dashes.
  • Fixed a bug in deferring Catalysis closure.
  • sceExamConvo now supports examining objects. This change is not backwards compatible.

September 29

  • Allowed the use of multiple scroll types. This change is backwards incompatible.
  • Allowed the use of a url when selecting a background for point.
  • Added "none" to the list of acceptable evidence selections with double-colon syntax.
  • Added a feature to defer Catalysis crashing until a specified number of errors has been reached, or the file with an error in it has finished running. This change modifies the selector.txt file and is not backwards compatible.

September 28

  • Fixed a bug that disabled all AA3 and AA4 places.
  • Fixed a bug where the speed command was not usable on a cross-examination statement.
  • Fixed a bug where animated AAO backgrounds were unusable.
  • Allowed the use of point on default places.

July 24

  • An auto-escape system has been added.
  • The demo case has been updated to use the auto-escape, as well as midword disabling of autopause.

July 23

  • Autopause, autowrap, and autoquote now take keywords instead of being toggled.
  • Autopausing is now disabled for characters in the middle of a word, unless you are in the new legacy mode.

May 14

  • Fixed a bug introduced in yesterday's update, where using custom sprites would interfere with the order of default sprites.

May 13

  • Migrated to Python3.
  • Auto-uploading will now open your case with the default browser, whatever it is.
  • Fixed a bug where non-ASCII characters would break error reporting.
  • Renamed revealFrame to revFrame for consistency.
  • Updated documentation on the positioning system.

April 23

  • Fixed a bug where press conversations would be incorrectly assigned to statements after the first cross-examination.
  • Fixed a bug where non-ASCII ellipses would be improperly punctuated.
  • Fixed miscellaneous errors where unicode in an unexpected place would break Catalysis.
  • Catalysis variables can now be used in any action argument, not just something that will be an expression in the AAO editor. $ and : symbols must now always be escaped in action arguments.

March 27

  • Catalysis now only accepts UTF-8 files. The logic around file encoding has been reworked accordingly.

January 2

  • Set an err.txt file to be generated with traceback information upon encountering an unknown error.
  • Fixed an error caused by trying to use Unicode on a Windows device, resulting in a file encoding that Catalysis couldn't read.
  • Fixed a crash when trying to call a black background by not giving an argument to place.
  • Silenced the error from failure to open the catalyzed case in the editor.
  • Put up a message that the catalyzed case is going to be opened in the editor.
  • Added the new "startup" configuration setting, which determines the default mode for startup animations.
  • Changed syntax for the point command.
  • Let the point command refer to an object, instead of just a region.
  • Fixed a glitch preventing subjects from being added to objects with space-separated names.
  • Added a default setting to hide previous characters when the place is displayed, unless the erase command has already been used on this frame.
  • Added a default setting to set the camera position to that of the most recently sprite-set/positioned person, if no position was given initially.
  • Fixed a glitch regarding multiline comments in macros.

December 31

  • Expressions with the point command have been re-enabled.
  • The error messages for examination selectors have been changed.

December 15

  • Miscellaneous error messages have been edited to be more useful.
  • Extra spaces at the beginning of a frame command are not purged any longer.
  • Several errors have been corrected throughout the documentation.
  • Expression mode for hiding and revealing introduction conversations, psyche-locks, talk conversations, and objects has had its complexity reduced. Many redundant arguments have been removed.
  • A critical bug when using the point command has been fixed.
  • breakPsy now has a break_now global argument. Setting it to anything will auto-break a lock.
  • Previously, you were not able to use default backgrounds for examination, but were able to for the point action. This is backwards of what AAO allows, so this has been flipped.
  • You can now use commas instead of commas and spaces to separate arguments.

The syntax for commands has been changed! Previously, command syntax looked like:

dispEv, foo, c, $'profiles', 1+shift_if_profile_changed, lr

This made it hard to tell what was global, what was an expression, and what was multiple. This ambiguity has been resolved under the new syntax:

argument_name, global_arg_1, global_arg_2
argument_for_first_set_of_multiples, second_arg
{expression_argument_for_first_set_of_multiples, $catalysis_anchor$}, second_arg
{escape_the_\}_brace, generic argument}, generic_arg
every_line_after_the_argument_name_is_interpreted_as_a_multiple, until_you_hit_a_colon:

This is a major change. Please see the actions section if you are still confused.

Set-up

Catalysis Prerequisites

Your version of Catalysis depends on your operating system. Pick the appropriate download version from this link. Those who want the executable version should pick the one specific to their operating system, while those who want the command line (Python 3) version should download the source code. You can use Catalysis by clicking on the executable or running catalysis.py. Additionally, please install the included font to ensure word wrapping features work properly.

To use Catalysis, all of your relevant text-files must be in UTF-8 encoding. If Catalysis cannot understand the first line of your file, not using the right encoding is the most likely culprit. Most text editors already support changes in encoding, so look up how yours handles it.

Using Catalysis

Before actually using Catalysis, there are some preliminary steps to do. First, ensure that you have a trial on AAO that you’re okay with losing completely, because the case Catalysis makes will go here. If you don’t have one, make one! When you have one, memorize its ID number.

Now open up the file called selector.txt. Currently, it looks like:

USERNAME:
AAO_username_here
PASSWORD:
AAO_password_here
DIRECTORY:
first_directory
TRIAL_ID:
trial_id_number_here
MAX_ERRORS:
max_errors_before_crash_here

If you want Catalysis to automatically upload the data into your case, update the username, password, and trial id numbers with the target information. If you do not want those, set the trial id to not be a number. Catalysis will still output the file as testData.txt in the file of your choice, where you can use the save page instead.

The directory field is the folder/directory where you store the text files to make the trial from. If you have multiple Catalysis cases, you can keep them in different directories and simply change the directory value to work on a different case.

The max errors field specifies how many errors will cause Catalysis to stop running. This must be a number at least one.

You can now run Catalysis to make your first case using Catalysis! If you are logged into AAO on Firefox when you do so, Catalysis will open your new case in the editor for you. Right now, though, it just creates a popup, so it’s time to learn how to do more with it.

You can either continue on with the documentation, or look over the sample case provided and what it looks like in the editor, and then return here.

Writing Objects

Introduction to Objects

The first Catalysis technique to master is making objects. An "object" includes a pop-up, music, sound… Anything that has a tab for it, and that isn’t a frame.

To begin, open up the objects.txt file in yourfirs_directory folder. Let’s start with Pop-ups.

Pop-Up Syntax

When you open up the file, you should already see:

Popup {
}

This makes a Popup object, as seen in the trial Catalysis made in the "Using Catalysis" section. All other objects are written in the same way. Of course, blank pop-ups are boring, so we need to learn attributes.

To make an attribute, insert a line between the two braces that looks like attribute: value. When making multiple attributes, each goes in its own line.

To make a Popup with the name "My Popup":

Popup {
name: My Popup
}

Popups have three and only three attributes:

name - Give the name of the object.

path - Give the ‘location’ of the object as a URL or AAO built-in.

base - Set all other applicable attributes to correspond to the given AAO built-in, if applicable. Applicable for name and path. Table of bases available here.

base, which is common to all objects, combines values that naturally go together. You can make an objection popup just by typing...:

Popup {
base: Objection
}

What if you want the Objection base, but to change the popup to Hold It? Just put two colons after the attribute name, and you use only that attribute’s "piece" of the base. You can always use two-colon syntax for anything that base handles, and never for anything else. Observe:

Popup {
base: Objection
path:: Hold it
}

Rather than typing "Hold it" into the URL bar, the path is set to AAO’s own “Hold It.” Note that we defined the path once to be Objection using base and once to be Hold it using path. Later commands always take priority, so the path of Hold it overrides that of Objection.

How, then, do you know what the ‘right’ value for base or double-colon syntax is? It’s supposed to be the most obvious choice possible, but if in doubt, check against the table provided.

Additionally, there may be times when you want to tell Catalysis to use a certain object later on. To do that, you must give the object a Catalysis handle, as below:

Popup Catalysis_Handle {
}

A Catalysis handle can be anything except a kind of object, like a place or popup. If you give an object a handle, that handle will serve as the object's name unless overriden. For example, the above snippet is equivalent to:

Popup Catalysis_Handle {
name: Catalysis_Handle
}

and unless you need handle features, that is also equivalent to:

Popup {
name: Catalysis_Handle
}

Note that while a Catalysis handle and name may often be the same, and they have a weakly symmetric relationship syntactically, they are entirely different ideas! A handle is how you point Catalysis to an object, and a name is the object's name in the editor. We won’t be needing this feature for a while, but keep it in the back of your mind for now!

Sound Syntax

Sound syntax is similar.

name - Give the name of the object.

path - Give the ‘location’ of the object as a URL or AAO built-in.

volume - Give the volume, an integer greater than zero.

base - Set all other attributes to correspond to the given AAO built-in, if applicable. Applicable for name and path. Table of values available here.

The only new thing here is the volume attribute, which returns an error message if it gets a value that isn’t an integer greater than zero. For example, suppose that object_data.txt read like this:

Sound {
base: Anger
volume: ohaimark
}

Because "ohaimark" doesn’t make any sense as a volume, Catalysis will just tell you back:

Error on line 3 of first_directory/object_data.txt. Volume must be an integer.

Entering invalid data in other ways will also give you error messages.

Like with popups, sound built-in names are similar to what you see in the editor. The only major difference is that speech is formatted as Speaker Kind-Of-Bubble, so Apollo Gotcha and Edgeworth Take That are both valid.

Music Syntax

name - Give the name of the object.

path - Give the ‘location’ of the object as a URL or AAO built-in.

volume - Give the volume, an integer greater than zero.

loop - Give the time to start looping from, an integer at least zero. Warning! loop_start is currently not built into base! If you want to change this, see this topic.

base - Set all other attributes to correspond to the given AAO built-in, if applicable. Applicable for name and path. Table of values available here.

Little has changed here, though base names are more complicated than previous base names. You may want to just use the table, but the system of rules is as follows:

Most name bases are an abbreviation to specify which "kind" of track it is, then the track number. The first game is PW (Phoenix Wright), second is JFA, third T&T, fourth AJ, fifth is AAI, and sixth is PP. So the seventh track of AJ is AJ7. Should a single number correspond to multiple tracks, like T&T31, the tracks are labeled T&T31, T&T31a, and T&T31b.

Orchestra tracks, follow the same syntax as for main-game tracks, but append O to the start of the track. The orchestral version of Prosecutor’s Path’s objection theme is then OPP107. Steven Corteus tracks are the same, but with SC. Tor4 is TOR.

Other remixes, however, do not specify the track numbers in-editor and the primary method of accessing them is thus not viable. In these cases, use the name of the group, then a one-word descriptor. Enigmar’s cornered theme, for instance, is Enigmar Pursuit. Note that Blue Jack is abbreviated as BJ, Remixes/Trailers is Trailer, when there are multiple varieties here, they are numbered, but with the 1 being implicit. So Blue Jack’s objection sequence is BJ Objection, BJ Objection 2, and BJ Objection 3. Trailer Pursuit themes must specify the game after Trailer to differentiate between the two pursuits.

Place Syntax

name - Give the name of the object.

path - Give the ‘location’ of the object as a URL or AAO built-in.

base - Set all other attributes to correspond to the given AAO built-in, if applicable. Applicable for name and base. Table of values available here.

Making places is straightforward. Making foreground and background objects, though, requires an extension of the syntax. Remember Catalysis handles from earlier? You’ll need to use one now!

Place My_1st_Place {
base: gant l
}

Now that the place has a handle, we can look at subojects!

Foreground and Background Object Syntax

name - Give the name of the object.

path - Give the ‘location’ of the object as a URL or AAO built-in.

hidden - Controls whether the object is hidden or not. Calling this flips whether or not the object is hidden, regardless of the argument.

x - The x-offset for the object. Must be an integer.

y - The y-offset for the object. Must be an integer.

base - Set all other attributes to correspond to the given AAO built-in, if applicable. Applicable for name and base.

Foreground and background objects are objects that are part of another object, a specific place. Hence, they are sub-objects. Sub-object syntax is near identical to object syntax. The difference is that instead, the first line must be Catalysis_Handle_Of_Object Type_of_Suboject {. Here is how to create a background object. Notice that the same rules for defining attributes apply.

Place My_1st_Place {
name: place name
}

My_1st_Place background {
base: aj det
name:: pw judge
hidden: true
}

Making a foreground object simply requires switching background to foreground. There are six defaults here: pw judge, pw court, pw det, and then the three aj versions.

Evidence Syntax

name - Give the name of the evidence.

description - Give the "brown box" description of the object as a URL or AAO built-in. Supports line continuation.

metadata - Gives the metadata, which is the "green box." Supports line continuation.

hidden - Controls whether the object is hidden or not. Calling this flips whether or not the object is hidden, regardless of the argument.

icon - Gives the icon for the evidence as a URL or AAO built-in.

base - Set all other attributes to correspond to the given AAO built-in, if applicable. Applicable for name and icon. Table of values here.

Evidence follows the usual trend, but with a big difference. To write metadata or a description, you need to be able to hit the "enter" button, but Catalysis treats that as the start of a new attribute!

Instead, you can create the equivalent of a newline through line continuation. To use it, start your next line with a colon immediately after the first line of the attribute. Here’s a three-line example:

Evidence Victims_Passport {
base: passport
metadata: Type: Documents
:Submitted as evidence by Detective
: Gumshoe at the initial hearing.
}

Note that one colon is not followed by a space, and the other is. Both are acceptable. If you used more spaces, Catalysis will insert those into your case.

Check Button Syntax

If you want to add a check button, add another subobject! The subobjects here are text, image, and sound, and they all only have one attribute: content. Only the content of text supports line continuation. Continuing from the previous example:

Evidence Victims_Passport {
base: passport
metadata: Type: Documents
:Submitted as evidence by Detective
: Gumshoe at the initial hearing.
}

Victims_Passport text {
content: Shows the victim was out of
: the country until the day before the
: murder.
}

Profile Syntax

Profiles are the same as always!

long - Give the "long name" of the profile. This shows up in the Court Record.

short - Give the "short name" of the profile. This shows up in textboxes.

description - Give the "brown box" description of the object as a URL or AAO built-in. Supports line continuation.

metadata - Gives the metadata, which is the "green box." Supports line continuation.

hidden - Controls whether the object is hidden or not. Calling this flips whether or not the object is hidden, regardless of the argument.

sprite - Sets the sprites and icon to be that of the requested AAO built-in.

icon - Gives the icon for the person as a URL or AAO built-in. This overrides the icon set by sprite.

voice - Set the voice. Takes "male," “female”, “type,” “none,” and “auto” as options.

prefix - Set the prefix. Used for frames. Duplicates are not permitted. Sets the suffix for the sprites to their defaults if sprite is already selected.

suffix - Adjust the suffixes. Used for frames. Duplicates are not permitted. May only be used is sprite has been used and prefix after it, or after a use of base.

base - Set all other attributes to correspond to the given AAO built-in, if applicable. Applicable for long, short, sprite, voice and prefix. Table of non-prefix values here.

So far, it’s pretty straightforward! prefix and suffix are new, but don’t worry about those yet. Those special commands will be explained in-depth when the time comes. We also have an object we can add here, the custom sprite.

Custom Sprite Syntax

Custom sprites work like any other subobject. They take the arguments name, still, talk, startup, duration, suffix. The first argument is the "name" your custom sprite will take. The next three ask for URLs for the relevant sprites. duration is the duration of the startup animation. suffix is a string, and its purpose will be explained later.

Example:

Profile My_1st_Profile {
}

My_1st_Profile sprite {
name: My Name
}

Comment Syntax

Catalysis lets you leave comments in your script. A comment is text that Catalysis does not "read," but people can. This lets you leave notes to yourself or other collaborators.

To do a comment on a single line, start the line with a double /. For example:

// This is a comment.

To do one on multiple lines, start the first line with /* and end the last with */. If you wish, these characters may be on their own lines. For example, both:

/*
This is my comment.
Isn’t is nice?
*/

and

/* This is my comment.
Isn’t is nice? */

are valid.

Writing Frames

Introduction to Frames

Objects won’t do much without frames! Frame syntax is radically different from object syntax, but is extremely easy to use. It’s finally time to open up frame_data.txt and start working with frames!

Writing Dialogue

Dialogue in Catalysis is as simple as writing, but you need to preface each frame with a command. When all you want is dialogue, use the command null. To make a single frame of dialogue, write in frame_data.txt:

null:
This is my first frame, and it’s going to be awesome! I’m \so\ excited!

Catalysis automatically adds the proper line breaks and pauses. (To disable either feature or edit the auto-pause, see Config Syntax, which also describes Catalysis’s automatic quote replacement.) This may result in unintended four-liners, which must be fixed manually.

To exempt a punctuation mark from having a pause added after it, prefix the punctuation mark with the character . This is referred to as "escaping" the character. A \ must also be escaped, unless pauses are disabled.

To write the above frame without any pauses, write:

null:
This is my first frame\, and it’s going to be awesome\! I’m \\so\\ excited!

The ending punctuation needs no \ because the last punctuation mark is never followed by a pause.

To add a blank line of dialogue, create a newline and give it nothing but spaces. For example:

null:
This is my first frame, and it’s going to be awesome! I’m \so\ excited!
        
There were spaces on the above line, so you’ll see a newline in the dialogue

Adding a speaker requires covering additional Profile syntax…

Aside: Return to Profile Syntax

The goal is to specify a speaker and a sprite through the syntax:

lb.n:

The part before the dot, the prefix, tells us who is speaking. The part after the dot, the suffix, tells us what post they are in. These use the prefix and suffix attributes from profiles and sprites.

Prefixes and suffixes can be any sequence of alphanumeric characters or underscores. Prefix must always come before suffix, and in order for the default sprites to have their suffixes set, sprite must be defined before prefix, so Catalysis knows which default sprites you are using. You can find the default suffixes here.

In custom_sprites, the suffix attribute gives the sprite the suffix.

In a profile, the suffix attribute makes changes from the default suffix listings for the default sprites. There are three rules here:

  • To redefine a specific sprite, use the syntax sprite_name_from_table: new_suffix.

  • To do multiple redefinitions in a single line, separate the redefinitions with a comma and a space.

  • To redefine the sprite that occurs in the editor (or on the Prefix-Suffix Table) right after the previous sprite, just type your new suffix without the colon or table value. If used at the start of a new suffix line, this will redefine the first sprite.

For example, Lisa Basil has three sprites: normal, happy, and nervous. To redefine happy and nervous, we can do any of the following:

Profile Basil {
sprite:: lisabasil
prefix:: lisabasil
suffix: happy: hap, nervous: nerv
}
Profile Basil {
sprite:: lisabasil
prefix: ls
suffix: suffix: nervous: nerv, happy: hap
}
Profile Basil {
base: lisabasil
suffix: suffix: happy: hap, nerv
}

If we wanted to give her a custom sprite, we could write:

Basil Sprite {
suffix: sf
}

Syntax here can seem imposing, so reread this section and experiment around, if necessary.

Speaker Syntax

So, how do you add a speaker? Replace the line that said "null" with a prefix, a period, and then the suffix. To make a Lisa Basil with default prefix and suffix say that last frame...

lb.n:
This is my first frame, and it’s going to be awesome! I’m so excited!

Alternately, if you want Lisa to speak without defining a new sprite for her on this frame, just type lb: instead of lb.n:

Observe how quick it is to specify this! This is the advantage of a text-based system, and short keywords. Specifying a character counts as a command.

Note that the character position is automatically set to center, and if a place is defined on this frame, the place position will be set to the position of the last character unless a position was explicitly set for the place.

Command Syntax

To do anything else with frames, use the command library! Each command will be explained in turn, but the general syntax looks like this:

command, argument, argument
command
prefix.suffix:

Commands go on separate rows, with arguments separated by a comma and no more than one space. (Any other spaces go into the command) A colon ends the last command row, to tell Catalysis that what comes next is dialogue.

If you ever need to use a "literal" character or characters that Catalysis uses as part of the grammar, escape it. These symbols are commas followed by a space, : at the end of a command, _ at the end of an argument, and . For example “Override, with space:” would be processed as the single “Override, with space,” going into dialogue, while “Override\, with space:” is split into “Override\” and “with space:”.

If you ever need to create a "blank" argument for a command, put an underscore or nothing (optionally prefaced with a space) after the comma. For example:

sceTalkConvo, _, , my_anchor:

This makes both arguments before my_anchor blank.

NOTE: You may want to look at Introduction to Macros and Configuration at this point.

General Commands

null

Takes no arguments. A filler command to show that no more commands are intended.

popup

Takes one argument. Displays the popup with the given handle.

music

Takes one argument. Plays the music with the given handle. If no argument is provided, music will be shut off.

sound

Takes one argument. Plays the sound effect with the given handle.

place

Takes two arguments. Displays the place with the given handle (first argument, assumes black background if not provided) and gives it the specified position (second argument, assumes center if not provided). The first argument may also be the keyword for a pre-defined place, if that name is not claimed by something else. Place cannot be set on a frame after a character, since just like the editor, Catalysis has to handle characters differently depending on if they’re after a place. Allowed place positions are:

c, center, l, left, r, right, l2, AAI left, r2, AAI right, ll, left of left, rl, right of left, lr, left of right, rr, right of right, lc, left of center, rc, and right of center

If no place is explicitly defined, then each time a character is set or repositioned, the screen position will move to that character's position. If erase has not already been used, then calling a place will set previous characters to be hidden. If you do not, use erase twice before setting the place.

wait

Takes as an argument the frame’s wait time in milliseconds.

hide

Takes no arguments. Toggles whether the frame is hidden.

merge

Takes no arguments. Toggles whether the frame is merged.

erase

Takes no arguments. Toggles whether previous characters are erased. Note that declaring a place before declaring erase will set previous characters to be hidden.

scroll

Takes as an argument the scroll type for the frame. Available scroll types are "none", "linear", "bezier", "ease_in", and "ease_out". Set to "none" by default.

speed

Takes as an argument the frame’s typing speed.

mirror

Takes no argument, but toggles whether the latest sprite is mirrored. Requires a sprite be set.

color

Takes as an argument a hexadecimal code or word to set the text color to. Note that the keyword for typewriter is lime not green. AAO’s blue is 6BC7F6, but skyblue is very close.

fade

Constructs a fade. The first argument is one of in, out and controls whether it is a fade in or fade out. The second argument is the fade color, which works as does color. The third argument is the time in ms. The fourth argument controls what is faded. Permissible keywords are: bg, bgchar, nottext, all.

blip

Takes as an argument a keyword for the kind of speech blip to use. Reset whenever a new character is called. Permissible keywords are:

n, none, m, male, f, female, t, type, a, and auto

sync

Takes as an argument the keyword for lipsyncing the current speaker. Requires a character be defined on that frame. Permissible keywords are:

s, sync, n, do not talk, k, keep talking, a, and auto.

appear

Takes as an argument the keyword for the current speaker's appearance animation. Requires a character be defined on that frame. Permissible keywords are:

n, none, l, left, r, right, f, fade

disappear

Takes as an argument the keyword for the current speaker's disappearance animation. Requires a character be defined on that frame. Permissible keywords are:

n, none, l, left, r, right, f, fade, a, appear

startup

Takes as an argument the keyword for the current speaker’s startup animation. Requires a character be defined on that frame. Permissible keywords are:

s, skip, d, during, b, and before

Can be used if the character lacks a startup animation, but will do nothing.

cPos

Takes as an argument the keyword for the current speaker’s startup position. Requires a character and place be defined on that frame. Shares position keywords with place.

If the place command called on this frame did not explicitly declare a position, then cPos will set the place position to be cPos's position. cPos does not need to be called if you just want the center place.

pPos

Takes as an argument the keyword for the current place’s position, when the place has not been set. Due to the AAO editor, many places are not available under this command. Set the place explicitly or have somebody at the relevant position talk, instead. Permissible arguments are:

a, auto, n, no move, ac, and align center

speakerName

Takes as an argument the custom name for the speaker (optional). If no name is provided, there will be no textbox.

speakerId

Takes as an argument the name of the character the character to lipsync to. Giving no argument means there is no speaker, and giving ? as the argument sets the speaker to unknown.

anc

Takes as an argument an "anchor name." By referring to this anchor later, you can redirect to the frame on which this anchor is placed. By itself, this command does nothing.

autohide

This command does nothing on its own but changes the reading instructions for frames. This toggles the autohide function, which is originally off. When autohide is on, any time a character is called on a frame without a place and without erase being called earlier, characters will be set to hidden.

Cross-Examinations

Unlike most Catalysis commands, cross-examinations depend on the user following an established sequence of commands. Breaking the sequence will cause an error message! The sequences are listed below in the order of usage.

ceStart

Takes no arguments, and must be used to start a cross-examination. Directly after this, you must have the command ceStatement or assistStart. Because Catalysis handles creation of new frames for you, you don’t even have a blank line between this. Catalysis would interpret this as trying to create a blank frame between starting the cross-examination and going onto the cross-examination statement or start of the assistant conversation.

ceStatement

Takes an optional argument creates a cross-examination statement. Providing any optional argument means that statement has no press conversation. After a cross-examination statement frame is written, you must have another ceStatement, or assistStart. You can, however, have other commands while on the frame.

Implementation Detail: After you’ve create a blank line after ceStatement, you enter "ceStatement and make_frame." This is simply a way Catalysis keeps track of what part of the cross-examination sequence you’re in, as the commands you’re allowed to write “change” when you make a new frame. Otherwise, you could have frames in-between ceStatements!

contra

Takes two arguments: the handle of the contradictory evidence or profile, and the "anchor" to redirect to. It must occur after ceStatement.

assist

Takes no arguments, but starts the assistant conversation. This is mandatory. The next cross-examination-specific command must be press (if there are press conversations), fail (if failure conversation but no press conversations), or ceEnd, ending the cross-examination.

press

Takes no arguments, but starts the press conversation. You must have one for each press conversation, and these go in order. The next cross-examination-specific command must be press, fail, or ceEnd.

fail

Command fail takes no arguments but starts the fail conversation. You can have frames in-between. Command ceEnd ends the cross-examination.

ceEnd

Takes no arguments, and ends the cross-examination.

Example

/* There’s no linebreak between these two because you can’t 
create a new frame between starting the cross-examination and
cross-examination statements. Also, this statement has no
press conversation. */

ceStart
ceStatement, skip:
This is the first statement.

// Element alpha contradicts this statement.
ceStatement
contra, alpha, CE1flag:
This is the second statement.

assist
color, red:
This text is in red.

null:
A blank frame in the conversation.

// The following dialogue has Phoenix speaking.
press
pw.n:
The press conversation has begun.

// This failure conversation is optional.
fail:
You get a penalty!

// As soon as we’re out of failEnd, we’re out of the CE. 
ceEnd
anc, CE1flag:
You found the contradiction.

Investigations

Like cross-examinations, investigations rely on commands given in a very exact sequence. The general rule here is that each command must follow the next, with the exception that convo commands can be skipped entirely or repeated, and sceLocks can be skipped.

sceIntro

Takes two arguments, an optional name for the investigation, and an optional argument to hide the investigation. (Any argument here will hide the conversation.) Starts the introduction conversation.

sceMain

Takes one argument, an optional anchor name. Supplying a name allows for this anchor to be referenced in "move" commands. This command controls the central frame from which the player accesses other investigation options. Commands not normally allowed on this frame are not allowed here.

Implementation Detail: You may see "sceMain and make_frame" if you don’t enter the command “sceTalk” after creating a new frame after sceMain.

sceTalk

Takes no arguments, but starts the talk conversations.

sceTalkConvo

Takes an optional argument to name the conversation, an optional hidden argument, and an optonal anchor for the talk conversation. Supplying anything for thei hidden argument hides the talk conversation.

scePres

Takes no arguments, but starts the present conversations. Commands entered from here until the next investigation command create the default present.

scePresConvo

Starts a present conversation and takes as an argument the handle of the object to present.

sceLocks

Starts the psyche-lock sequence and takes arguments. If the first argument is a word, the locks will be hidden. Any other arguments must be the x and y coordinate (in pixels) of each lock. This command is entirely optional.

sceExam

Creates the examine option and takes as an optional argument the Catalysis name of the place to examine. If no argument is supplied, it will default to the black place. Commands entered from here until the next investigation command create the default examine.

sceExamConvo

Creates an examine option. It takes as a mandatory argument the type of object to examine: a region or an object.

If a region, it next takes the shape to create: poly for polygon, rect for rectangle, or circle for circle. It also takes as arguments the pixel-numbers that specify the region to examine. poly requires a sequence of x and y coordinates, rect requires upper-left x, upper-left y, lower-right x, lower-right y, and circle needs x-coordinate of the center, y-coordinate of the center, and radius. Comma escaping is unnecessary.

If an object, simply supply the name of the object. If working with an AAO default, any dummy word will do.

sceMove

Creates the move options. Its arguments are a sequence of anchors from sceMain of the scenes to move to, and name overrides. To omit a name override, simply don’t type anything after the comma and space, or use the underscore notation.

Example

sceIntro, My Scene:
Introduction conversation initiated.

null:
Introduction conversation closed.

// Setting the place to be the Office…
sceMain, Place_Anchor
place, Office

sceTalk
sceTalkConvo, First Talk Option, , my_anchor:
Because I included nothing after the comma and space, this talk option isn’t hidden. It has an anchor set, and the first frame is blank except for this text.

null:
The def

scePres
color, green:
This is the default present dialogue.

scePresConvo, Badge:
As long as the Badge evidence exists, this piece of dialogue...

null:
...will control the present conversation for presenting it.

sceLocks, dummy, 38, 194:
This is the psyche-lock convo. The lock is hidden. Removing the word "dummy" and just having , , would reveal it.

sceExam, Office:
Have a default examine conversation!

sceExamConvo, circle, 30, 45, 90:
This will trigger if the user clicks the circle of radius 30, centered at 45, 90.

sceMove, Place_Anchor, Override Name

Actions

Catalysis allows actions, and the complexity of writing an action depends on how complex of a use you want. The following rules apply:

  • The first line starts with the name of the action. It takes arguments corresponding to the global part, things that the action can only do once (like theframe to redirect on failure).

  • Each line after this, until a line either ends in an unescaped colon or is blank, is interpreted as a multiple part. A multiple part can be repeated within the action (like a piece of evidence to accept).

  • The global part and the multiple part may each have "subparts" that correspond to a single thing you can select through the editor.

  • To write an argument of an action - global or multiple - as a runtime expression, enclose the expression value of that part with { and }. An argument may have further pieces when a runtime expression is used, and those additionals pieces need not be prefixed with anything. If you do not want to use expressions, you don’t need to use { and }.

  • If you want a literal $, :, {, or }, escape it with \.

  • To use an anchor value, enclose the anchor name in $. Only anchors that make sense in context can be used. Acceptable anchors are named objects, frame numbers, talk options, scenes, etc. The kind of anchor to use depends on context.

  • If in an expression, you want to refer to an anchor value that wouldn't normally make sense (for example, you need an evidence id in a frame-redirect to use an evidence_is_revaled check), use the following syntax {kind_of_anchor: name_of_anchor}. Kinds of anchors are limited to: frame, scene, talk, talk scene, evidence, profile. A talk scene anchor is a talk anchor that refers to the scene of the conversation, and not the conversation itself.

The following examples illustrate these principles:

setOver, alpha

A normal command with a single global argument.

dispEv
Badge, tr
Magatama, bl

A normal command with two multiple parameters. The first displays the "Badge" evidence in the topright, and the second displays "Magatama" in the bottom-left. This is an example of multiple parameters.

dispEv
Badge, {my_expression}

The same command, but the position is now the runtime expression "my_expression" without quotes. To see what normal values for an argument are like, try experimenting in the editor.

dispEv
Badge, \{my_expression

You are no longer making an expression, but trying to select the built-in position that goes with {my_expression.

dispEv
{'evidence', 1}, tr

The first argument has been replaced with an expression. Making the evidence to select an expression splits it into two further pieces.

dispEv
{'evidence', $Badge$+1}, tr

The word "Badge" is now enclosed in $. Since it’s part of an expression, Catalysis will replace $Badge$ with the value that the anchor “Badge” corresponds to, assuming the $Badge$ anchor makes sense. Here, it “makes sense” for Badge to refer to the id of the evidence named “Badge,” so Catalysis will use that. If you set “Badge” to something else, like a talk conversation, that makes no sense, so Catalysis crashes.

dispEv
Badge, $my_expression$

anc, my_expression

Even though you’ve set an anchor named "my_expression," only an evidence anchor would make sense here, so Catalysis will crash.

dispEv
Badge, $frame: my_expression$

anc, my_expression

You have now explicitly told Catalysis that you are using a frame anchor, so this code will work. Note that this need not be in an expression, in curly braces, to work!

Syntax for actions is more complicated, and has the following subheading:

global: global args; multiple: multiple args

$global args -> This maps each multiple arg, to each "subpart" in expression mode

$multiple args -> If this ends in an asterisk*, it supports an anchor, even in expression mode


dispEv

global: None; multiple: evidence/profile handle, position keyword

$evidence/profile handle -> evidence_or_profile*, object_id*

$position keyword -> position term

Displays evidence. Valid position keywords are tl, tr, bl, br, a, topleft, topright, bottomleft, bottomright, and auto.

hideEv | revEv

global: None; multiple: evidence/profile handle

$evidence/profile handle -> evidence_or_profile*, object_id*

Hides or reveals evidence.

setOver | proceed

global: frame anchor; multiple: None

$frame anchor -> frame_id*

Sets the game over redirection or frame to proceed to. Can’t be used on a merged frame.

hideFrame | revFrame

*global: None; multiple: frame anchor

$frame anchor -> frame_id*

Sets the frame to hide or reveal. Usable on a merged frame.

gameOver

global: kind_of_gameover, data_to_send, series_part_to_go_to, frame_to_go_to; multiple: None

$kind_of_gameover -> Kind keyword -> kind_of_gameover

$data_to_send -> Data keyword -> data_to_send

$series_part_to_go_to -> Position-in-series ID -> series_part_to_go_there

$frame_to_go_to -> Frame ID -> frame_to_go_to

Sets the game over redirection. If there are any expressions, or the first argument is another, all arguments are needed. If the first argument is next, the first two arguments are needed. If the first argument is none or end.

The first argument must be one of the above terms, and controls the "kind" of gameOver. Keywords are “end,” “next,” or “another.”

The second argument controls what data is sent over. Keywords are: none, var, full, 0, 1, or 2, to send no data, variable data, or the full data.

The third argument is the number-in-series of the part to go to.

The fourth argument is the frame number to go to. It does not accept an anchor.

Can’t be used on a merged frame.

hideObj | revObj

global: None; multiple: handle of subobject’s place, subobject name

$handle of subobject’s place -> place_id*

$subobject name -> fg_or_bg, subobject_id*

Hides or reveals a foreground or background object. To hide the object of a pre-defined place, omit the subobject name entirely, not even an underscore, and simply give the pre-defined place’s keyword.

Note that this action uses a subobject's name instead of its handle. This is done here because giving a foreground object a handle will be redundant. This is the one time where the handle-name symmetry means that a name functions like a handle.

hideSce | revSce

global: scene anchor; multiple: None

$scene anchor -> scene_type, scene_id*

Hides or reveals a scene.

hideIntro | revIntro

global: scene anchor; multiple: None

$scene anchor -> scene_type, scene_id*, section_type, section_id*

Hides or reveals a scene’s introduction conversation.

hideTalk | revTalk

global: talk anchor; multiple: None

$talk anchor -> scene_type, scene_id*, section_type, section_id, conv_type, conv_id*

Hides or reveals a scene’s talk conversation.

hidePsyButton | revPsyButton

global: scene anchor; multiple: None

$scene anchor -> scene_type, scene_id*, section_type, section_id*

Hides or reveals a scene’s psyche-lock conversation.

hidePsy | revPsy

global: None; multiple: None

Hides or reveals a scene’s physical psyche-locks. Can only be used in a scene.

breakPsy

global: auto_break; multiple: lock_id

$auto_break -> hide_if_set

$lock_id -> scene_type, scene_id, section_type, section_id, lock_id

Hides or reveals a scene’s physical psyche-locks. Can only be used in a scene. Giving any argument for the global will auto-hide one psyche-lock. Hiding lock number 0 is equivalent to using the automatic feature to hide a lock.

setHealth | redHealth

global: points; multiple: None

$points -> points

Sets or reduces health, per the given number. Can’t be used on a merged frame.

flashHealth | incHealth

global: points; multiple: None

$points -> points

Flashes or increases health, per the given number.

choice

global: back_button; multiple: choice_text, frame_anchor

$back_button -> back_button_yes_or_no

$choice_text -> choice_text

$frame_anchor -> frame_id*

Displays a list of options for the player to choose from. Cannot be called on a merged frame. The back_button argument will only be used if you are in psyche-locks. Giving any non-blank argument enables the back button unless using an expression.

askEv

global: back_button, permissible_evidence_keyword, fail_frame_anchor; multiple: evidence/profile handle, frame_anchor

$back_button -> back_button_yes_or_no

$permissible_evidence_keyword -> evidence-keyword

$fail_frame_anchor -> frame_id*

$evidence/profile -> evidence_or_profile*, object_id*

$frame_anchor -> frame_anchor*

Prompts the player for evidence. Back button behavior is the same as with choice. The evidence keyword determines what evidence can be presented. The keywords are ev, evidence, pro, profiles, and all.

point

global: back_button, background, fail_frame_anchor; multiple: region_term, movement_term(s), frame_anchor

$back_button -> back_button_yes_or_no

$background -> place_id or url*

$fail_frame_anchor -> frame_id*

$region term -> Expressions Not Supported

$movement_term -> movement_term

$frame_anchor -> frame_anchor*

Prompts the player to point at an area. Back button behavior is the same as with choice.

Each multiple argument must start with a region term, either "region" or "object". Selecting "region" tells Catalysis to expect a set of coordinations, in the same style of sceExamConvo. Selecting "object" tells it to expect the name of the subobject corresponding to the place.

Due to the abundance of commas in examination coordinates, comma escaping is unnecessary, and Catalysis will handle that for you. Be warned that the first space after commas, if intended as part of the argument, will be purged, so a second space is needed. The frame anchor will always be the last argument.

playerIn

global: None; multiple: name, type keyword, password

$name -> name

$type keyword -> type

$password -> password

Defines a variable with the given name, based on player input. Acceptable keywords for the type are s, string, w, word, f, and float. If any non-blank argument is given in value mode for the password argument, password mode will be enabled. Cannot be used on a merged frame.

varDef

global: None; multiple: name, value

$name -> name

$value -> value

Defines variables with the given names and values.

expTest

global: object type keyword, test variable, test expression, fail frame anchor; multiple: success value, frame anchor

$object type keyword -> object type

$test variable -> test variable

$test expression -> test expression

$fail frame anchor -> fail frame id*

$success value -> success value

$frame anchor -> frame id*

Compares a given value or expression against various values and goes to the frame that matches the values, or the failure conversation. The permissible object type keywords are exp, expression, var, and var_name. If the object type keyword is not an expression, you can skip test variable or test expression, whichever is inapplicable. Cannot be used on a merged frame.

condit

global: fail frame anchor; multiple: condition to test, target frame anchor

$fail frame anchor -> fail frame id*

$condition to test -> condition to test

$target frame anchor -> target frame id*

Checks all given conditions and goes to the frame matching the first true condition. If all conditions are false, it goes to the first false frame. Cannot be used on a merged frame.

Comment Syntax

Comments can be added in frame_parser.txt. To ensure that comments and text for the game are kept separate, comments are only allowed immediately after an object. Everything else is the same.

Writing Macros and Configuration

Introduction to Macros and Configuration

Catalysis is quasi-customizable, giving the ability to create custom commands and adjust the behavior of commands. Creation of a custom command is known as creation of a "macro," and adjusting command behavior is known as editing configuration.

Macro Syntax

You can write any custom command as a sequence of other commands or macros through the following syntax:

macro_name {
macro_line_1_with_arguments
}

macro_line_1 is a command, just as in frame_data.txt, except without any colon syntax. The command can be calling a character. Or it could be another macro, as demonstrated here:

gen_obj {
wait, 1500
popup, obj
music
dialogue, [#s]
sound, shout
}

pw_obj {
gen_obj
sound, pw_obj
}

Calling the gen_obj command will create a generic objection, but calling pw_obj will make it Phoenix’s objection. Note that there is a pw_obj macro and a pw_obj sound object. This is fine! A macro can take any name except a name of a default Catalysis command, or CONFIG.

Utility Functions

Creating new frames and setting dialogue cannot be done by normal commands, so there are utility functions to make frames and set dialogue. These functions, while usable in frame_data.txt, are designed only for use in macros. In frames, Catalysis handles these automatically.

make_frame

Makes a frame. Takes no argument.

dialogue

Adds everything after the first comma and space into the textbox without word wrapping or pausing. This is intended mainly for effects like adding pauses. Literal \ must be escaped. Having a spare \ at the end of the command will create a newline.

set_sprite

Sets the sprite. Takes the prefix and suffix of the relevant sprites as the arguments. As with cPos, if the place position has only been implcitly defined, this will move the camera to the position of the sprite.

Configuration Syntax

Configuration is also done in macro_parser.txt. It looks like:

CONFIG {
config_attribute: config_value
config_attribute_2: coinfig_value_2
}

This syntax is near identical to object syntax.

threelines

Takes as a value "on" or "off". "on" by default. "on" will automatically raise an error if text takes more than three lines. "off" will not.

autopause

Takes as a value "on", "off", or "legacy". "on" by default. "on" will automatically pause any valid punctuation not in the middle of a word, except the very last one. "legacy" will also pause punctuation in the middle of a word. "off" disables the feature. Escaped punctuation is also exempted, as detailed here.

autowrap

Takes as a value "on" or "off". "on" by defult. "on" will automatically word wrap for AAO screens. "off" will not.

autoquote

Takes as a value "on" or "off". "on" by defult. "on" will automatically convert smart quotes to regular one. "off" will not. (Technically, Unicode 2018 and 2019 turn to 27, and Unicode 201C and 201D turn to 22.)

autoescape

Takes a series of space separated words. Any word in the list will be exempted from auto-pausing. This is useful for abbreviations, such as Mr. or Aug. The words are case-insensitive, so either mr. or Mr. will work. The punctuation must be included.

startup

Determines the default value for startup animations, whether they play before text, during text, or after text. Permissible values are skip, s, before, b, during, and d.

. ! , - – — ? … ; :

Giving a punctuation mark in the above set, followed by a number will change the pause Catalysis sets for that symbol, with 0 removing the pause altogether.

The following code, which disables word wrap, disables pausing for colons, and adjusts the pause of a single period, and multiple periods. Note that … stands for any grouping of more than one period, which is taken to be an ellipsis.

CONFIG {
autowrap: false
:: 0
.: 200
...: 1000
}

Comment Syntax

Comments can be added with the same syntax as before. Both kinds of comments are allowed anywhere.