Rosa is a tool to generate step routes for the SNES/SFC release of Final Fantasy IV. Step routes are specific walking patterns designed to manipulate the timing and details of random encounters. They are primarily used for speedrunning the game. Additional details can be found at ff4.aexoden.com.
Rosa requires Boost and LMDB to be installed on your system.
Rosa may or may not build in your particular environment. The code should be standard C++17 and as such, may compile on any modern standards-compliant compiler. However, the build is currently only tested on Clang 6 and 7. The included build machinery assumes as much.
Rosa is primarily designed to be run from within the main repository directory.
To build the executable, enter that main directory and execute
expects certain data files to be in particular locations relative to the
current working directory.
No options are strictly required, as there are sane defaults for all options, but some minimal options should be set to get any sort of real use out of the software.
Specifies the route definition for which to generate a step route. This file
should be named and located in the form
data/routes/%ROUTE%.txt where %ROUTE%
corresponds to the given route name. More details about the format of this file
are available later in this README.
Specifies the seed for which to generate the step route. This should be an integer from 0 to 255 (inclusive).
Specifies the maximum number of extra steps a route can take in a given segment. Zero is a slightly special value that disables all optimizations.
Specifying this parameter enables a special mode where the number of segments where extra steps can be taken is restricted to the given number. This will generally lower overall performance, especially once you start getting into the 10+ range. However, it is faster for smaller values, and any persistent cache is reusable across runs, regardless of how the parameter is changed. This allows you to generate routes quickly that use a few locations, and then refine those into more complicated routes. Do note, however, that the total time taken by multiple runs in this fashion is slower than a single run. It is, however, faster to use a preexisting cache from a faster run than to go entirely from scratch.
Specifies values for the given variable indices. The format is
c are indices and
d are values. In addition, a range
of values can be specified by appending a hyphen and an additional number (e.g.
Adjusts the optimization to use TAS-specific features. This currently only uses the minimum encounter timings instead of the average, but additional features are planned.
maximum-step-segments option is configured, this option enforces that
routes will always use the fewest locations possible to take steps that still
gives the optimum result. The default behavior is instead to prefer taking every
step as late as possible. Enabling this option will increase runtime to some
degree, as it requires calculating additional states.
Sets the type of cache used. There are three options available:
persistent. The default is
dynamic, which will cache all states.
This will use lots of memory on complicated routes. Using
fixed will trade
some of that memory usage for reduced performance. Depending on how close the
cache size is to the number of states, the performance may be drastically
The final option is
persistent, which uses a persistent database on the disk.
Early testing indicates a roughly 3x increase in execution time, but memory
usage becomes much less of an issue. Rosa makes no attempt to manage the
lifetime of this cache, and you are expected to know what you are doing. The
cache should only be used to mitigate high memory usage or to spread a
calculation across several runs. If the route definition changes or parameters
are modified, using the old cache could result in suboptimal generated routes.
If using a fixed-size cache, allows the user to fine tune the size of the cache (in states). The default is 1048576, but this is substantially too low for most routes. It is, however, relatively light on memory usage.
If using a persistent cache, controls the directory where the cache is located.
The default is
cache/. Each route/seed combination will automatically use its
own individual cache. There is not expected to be significant overlap between
seeds. If you wish to start with a fresh cache, you should delete the relevant
If using a persistent cache, directly specify the name of the directory where the cache will be located. The directory will be created if it already exists. As with the previous option, this location will be created it if it doesn't exist, and will never be deleted automatically. If specified, this option overrides the previous option.
There are a few fields that are mostly free-form strings, but the code may make assumptions about their values and format. These are defined below. Deviating from these formats may or may not work, and the ultimate behavior is undefined.
A party is indicated by a 20-character string, with each character representing the following:
The number of party members in the front row. Must be either
An indication of whether or not the party current has GP. Should be
-if not or
Gif they do.
An indication of whether or not this party is on a world map. Should be
-if not and
+if they are.
Characters 4-18 consist of 5 sets of 3 characters. The first character in each set is any letter from A-Z, with a capital letter designating an alive character and a lowercase letter designating a dead one. The following two characters are the agility of the character in decimal form.
The last two characters are the average party level, in decimal form.
Variable names are hexadecimal numbers designed to be used partially as if they were strings. Any hexadecimal number is technically a valid variable name, but the included routes are standardized on the following format:
The first digit should be a letter from A to E, specifying the type of variable.
The only currently used letters are
C for a choice or
E for extra steps.
The next four digits correspond to the related map number, as defined in the map definition.
The final two digits are an index, in case that particular map has more than one variable.
Encounter Formation Specification
This file defines the encounter formations and their groups. The only currently available data is for the USA release of Final Fantasy II. The system is designed to allow for future expansion, however.
These files live in the
data/encounters directory, and consist of
tab-delimited lines. Note that all fields must be filled. If a field needs to be
- should be used. The two types of lines are:
This line defines a particular encounter formation. The six fields are:
A number from 0 to 511 indicating the formation number.
A textual description of the encounter. This can be omitted if this formation number has already been assigned a description earlier in the file.
The party for which this particular line provides data.
The average duration of an encounter in frames, specified as a decimal with three digits after the decimal point.
The minimum duration of an encounter in frames, again specified as a decimal with three digits after the decimal point. In this case, those three digits should be zero.
This line defines a group of formations. The fields are:
The number of the group, ranging from 0 to 255.
A tab-delimited list of eight numbers indicating the formation numbers that are in this group. They need not be unique.
This file provides data about the maps available in the game. Similar to the encounter formation data, this file currently contains data for the USA release of Final Fantasy II, but is designed for future expansion.
The file is located in the
data/maps directory and consists of many
tab-delimited lines, with lines conforming to the below format:
This line defines a map. The fields are:
The map number, consisting of four hexadecimal numbers. For dungeon maps, this should be
3followed by the three-digit map number. For overworld, underworld, and lunar maps, the first digit should be
2respectively. The final three digits should refer to unique map regions.
The encounter rate of the map/region.
The encounter group of the map/region.
The title of the map. This string is currently unused in the software, but is intended to be the on-screen description of the map when entering.
The description of the map. This should be a complete textual description of the map, sufficient to adequately distinguish it from any other map.
Route definition files live in
data/routes and are named according to the
short name for a route (e.g.
paladin.txt for the Paladin% route).
They consist of many lines which provide information about the route. Like the other files, each line is a tab-delimited line. In addition, the file is limited to a maximum of 65536 lines (not including empty lines and comments).
There are numerous different lines, which will be described in the following sections.
This line provides the name of the route, and consists of
ROUTE followed by
This line provides the route version. This should be
VERSION followed by an
integer, ideally incremented after every change.
This is a line which will generate extra output, usually to help describe a location or indicate the position of a boss battle. The two fields are:
A string with the desired extra output.
This line changes the currently active party. The two fields are:
The new party, as a 20 character string as defined above.
This is the primary line type. It consists of the following fields:
A 7-digit hexadecimal number representing the variable name for this segment. If extra steps are not allowed in this segment, this should be
The 4-digit map number, in hexadecimal.
The number of tiles traversed on this segment.
The number of required steps on this segment.
The number of optional steps on this segment.
The number of transitions from map to map on this segment.
+if single extra steps are available, and a
-if they are not.
+if pairs of extra steps are available, and a
-if they are not.
+if this segment can take an extra steps for free when saving, and a
-if not. This is a TAS-specific feature that currently has no relevance in the software.
These three lines are used to define branching in the route. (For instance, to enter a side room and take extra steps. They cannot currently be nested.
This line indicates that there are multiple options on how to proceed. The line has the following fields:
A 7-digit hexadecimal number assigning the relevant variable name. Assigning a variable name of
-will essentially make it impossible to reach any option other than the first one.
The number of options available.
This line indicates a new option begins (and any previous one ends). It has the following fields:
A free-form string describing the option in as much detail as necessary.
This line signifies that the final option is ending, and normal non-optional segments begin.
This lines provide a facility to search for a particular encounter or set of encounters (e.g. for a grind fight).
This line defines that an encounter search is beginning. It has the following fields:
A string with a description of the search.
A plus-delimited list of encounters to search for. These are currently non- sequential, and the search will be declared successful as long as they are all found during the relevant segments, regardless of ordering. There can be up to four distinct formations listed, and each formation can be listed up to seven times if multiple encounters are required. These limits are not enforced by the code, but the behavior is undefined if you exceed them.
This line signifies that the encounter search is over. This allows a search to span multiple maps. The final map in a search must have an associated variable name, as if the encounter has not been found, extra steps will be forced until it is.
- Jason Lynch (Aexoden) email@example.com
Many of the original ideas for Rosa came from work done by the_roth and Myself086 with their own step routing work. This work was originally synthesized into a previous version of this tool, Spoony.
Eventually, various limitations of the Spoony architecture (primarily its inability to generate routes that were guaranteed optimal) came to light. Rosa is the culmination of a near-complete refactoring of the Spoony codebase to support an optimal solver. Early experiments with the new solver were undertaken under a separate Rosa project that is now defunct. The optimal solver incorporates ideas from fcoughlin's independent implementation of a step route optimizer, ff4step. Additional features to the route definition format have since been added, necessitating this release of Rosa.
The entire FF4 speedrunning community has been incredibly supportive, not only by providing information and by helping with research, but also by actually using the generated routes in runs to help prove their viability and accuracy.