Say the Spire Documentation

# Introduction

Welcome to Say the Spire, a mod that provides blind accessibility for the game Slay the Spire. Note that currently only the Steam version of the game on Windows is officially supported.

## Getting Started

Follow the instructions on the installation page. After that it is highly recommended you read the Important Notes page. After that experiment with the game and refer to this documentation as needed.

# Mod Installation and Setup

For recent changes, see the change log.

For compilation instructions for developers, go here.

## Installation

### Using Steam Workshop (Recommended)

If you own the game on Steam, Say the Spire can be subscribed to (installed) from the Steam Workshop. If you are doing this, it will require you to subscribe to ModTheSpire and BaseMod. Check the bottom of the page after clicking subscribe and it will link you to the required mods. Alternatively all requirements are linked to in the list below.

- ModTheSpire Steam Workshop
- BaseMod Steam Workshop
- Say the Spire Steam Workshop

When you are subscribed to Steam Workshop items they will be automatically downloaded. Updates to those items are also automatic. Say the Spire will announce the current version number when it is launched.

### Manual Installation

If you do not want to install from the steam workshop, you can copy all requirements manually. Note that the version of ModTheSpire on GitHub is out of date compared to the Steam Workshop version. It is highly recommended that you install all of the mods via the Steam Workshop for better compatibility and more frequent updates.

First, download all dependencies. You can either install them from the Steam Workshop links above or download them from their GitHub pages listed below.

- ModTheSpire GitHub Latest Release Download and extract ModTheSpire.zip
- BaseMod GitHub Latest Release Download BaseMod.jar
- Say the Spire GitHub Latest Release download and extract the zip file

Now create a folder called `mods` in your Slay the Spire game directory. This is most likely to be `C:\Program Files (x86)\Steam\steamapps\common\SlayTheSpire`. Copy all of the files in the ModTheSpire zip to the game's root directory (there should be `mts.cmd`, `mts.sh`, and `ModTheSpire.jar`). Copy Basemod.jar and SayTheSpire.jar to the mods directory.

Make sure that you do not have multiple instances of the same mod installed from different sources for Say the Spire or any mods it depends on. for example, do not have both the steam workshop and mods folder versions of BaseMod installed. Conflicting mods can cause the game to break and prevent mods from functioning properly.

Note that you can have different mods from different sources. For example you can have ModTheSpire from the workshop and BaseMod from GitHub.

## Setup

After you have installed the needed mods, you can launch the game using one of the following options. See the Mod the Spire section for how to handle some accessibility issues with the modding tool.

- Recommended: Download and run the mts_steam.cmd file or use the same file from the GitHub release' zip folder. It shouldn't matter where this file is launched from. If your steam directory is not the default, open the mts_steam.cmd file in notepad or wordpad and change the path after the /d to the correct directory. Whenever you want to play the game using mods, launch that file.
  - Your Slay the Spire base directory may already have an `mts.cmd`. If it does you can launch that.
- in steam, right click on the game, click play, OCR, left click on play with mods, then left click on play. This is not ideal but it works.
- Launch using a manual call to java (not recommended)

### Speech

On Windows, speech output will be automatic and no extra steps are needed. On linux an additional step is required.

The screen reader implementation for Linux uses the speechd library, which is old and uses tcp sockets to send text to Speech Dispatcher. Speech-dispatcher needs to be initialized with a tcp socket before Say the Spire can be used. An example command is given below, though you may need to modify it depending on your system setup if it doesn't work:

    speech-dispatcher -c inet_socket -t 0 -P "$HOME/.local/share/speechd.pid"

## Mod the Spire

Mod the Spire is the software that handles game mods. It allows you to activate and deactivate mods. When play is pressed, the mods are loaded into the game and the game is run.

Mod the Spire is not the most accessible piece of software, however it can be worked with.

### Windows Accessibility Tips

If you are on Windows, NVDA object navigation is required for more specific mod configuration, however you do not need it for enabling all mods to start with. If NVDA doesn't recognize objects in the window (reading "unknown" or just reading nothing at all), run the following command using cmd prompt or batch. If your steam directory is not default, change the steam path accordingly.

    "C:\Program Files (x86)\Steam\steamapps\common\SlayTheSpire\jre\bin\jabswitch" -enable

This command enables Java Access Bridge. If you run this command from the command prompt, it should output "Java Access Bridge has been enabled".

Note that if you are using jaws, Mod the Spire will not work with certain older versions of jaws due to them not supporting Java Access Bridge (no controls will be read). If you are using jaws, you can hit enter as soon as mod the spire opens to play. Note that doing this will play with the currently enabled mods, however by default no mods are enabled. If setting up mods though you will have to switch to NVDA or some other scree nreader that has Java Access Bridge support.

#### Windows Specific Mod Configuration

If you are using NVDA, you can use object Nav to view the information for each mod and to enable/disable the mod. To do so, arrow over the list item for a mod and press the move to first contained object key. You can then use move to previous and next object to interact with this section. This collection of objects includes the mod checkbox (toggle with Activate current Navigator object) as well as the mod's name and other information.

### Quick Mod Setup

If you want to quickly enable/disable all mods, do the following. This is most likely what you want if setting up the game for the first time or just running Say the Spire with no additional game mods.

- If this is the first time running Mod the Spire, click toggle all mods on/off, then click play. This will enable all mods as new mods start out disabled by default.
- If this is a subsequent run of Mod the Spire, you want to enable all mods (maybe after adding a new one), and you have already enabled mods, click the toggle all mods on/off button twice then click play. If you haven't changed your mods since the previous run you can just hit play; your mod state is saved.

# Important Notes

## Important: Achievement Enabler and Game Leaderboards

When the game is launched in a modded state, achievements and daily run leaderboard submissions are disabled by default. The game tracks the state of certain achievements to determine when some characters are unlocked, so it is important that you enable achievements with the Achievement Enabler mod linked below.

- Achievement Enabler Steam Workshop
- there is currently no GitHub repository for this mod.

## Important: Cloud Saves

When the game is launched via ModTheSpire using the mts_steam.cmd file, it does not run all of the usual Steam functions that would be run if the game was launched normally. As a result, your game data is not automatically backed up to the Steam Cloud. To fix this, run the game normally and select the option to upload your data. This prompt should load as a standard html page, however it may not and OCR may be required. You can copy the json files from the game directory to manually back up your saves as an alternative. Unfortunately there seems to be no way to have data periodically back up with Steam itself. Make sure to do this somewhat frequently or you will lose your progress should you lose the local save files.

## Settings not Saving

There is a bug related to game settings not saving. The game does not seem to trigger settings being saved when you adjust some specific settings, namely the three volume sliders. To get these settings to save, toggle one of the settings checkboxes (such as ambience). this should trigger your settings to be saved correctly.

# General Mod Usage

The mod automatically sets up dll files needed for screen reader functionality and removes them after the game is closed. If the mod is working correctly, you will hear the current version of Say the Spire read out by either your screen reader or SAPI if your screen reader is not running when the game launches.

It is highly recommended that you refer to the Keyboard Support/Virtual Input and UI sections after reading this page.

The mod narrates UI elements automatically. It will also announce many game events as they occur without any additional player input required. To access additional statistics and tooltips however you will need to use the buffer system.

there is an extra set of controller and keyboard inputs to provide information. This is generally refered to as the buffer system and is mapped to the right stick or control plus the arrow keys on keyboard by default. As you move over various UI Elements, contextual buffers will appear. These are just lists of various pieces of information about the element you're focusing on. For example, if you hover over a card, the card buffer will be automatically focused and will contain information such as the card's name, energy cost, description, etc.

Think of buffers as a way to refer to different areas of the screen quickly, similarly to how you could scan visually. For example, while hovered over a card, you can move to the player buffer to view player info without having to move there with the other controls. Buffers are also used to provide access to UI Tooltips (for example character information on the character selection screen, etc).

The buffer system is also used for the map. Using the buffer controls lets you browse available paths and choices when available. For more information, see the map section.

# Game UI

## General Overview of UI Querks

This game has some unusual qualities to the UI (due to the fact that controller support was added in later; the game was primarily mouse driven before that). for more detail on any of these, see the sections below this list. In general keep in mind:

- Certain prompts (confirmation, tutorial, hand card selection, etc) require you to hit proceed to get out of them. For confirmation prompts, you can also hit cancel to back out. Note that this is not always the case.
  - Note that if you have the disable confirm for single card selection option on, you do not have to hit proceed after selecting a card.
- Nearly everything has contextual actions mapped to the various controls. For example, hitting top panel/x/square will allow you to delete a save slot and proceed/y/triangle will allow you to rename that slot.
- For the options screen, for some reason you have to move the right stick left and right to adjust the volume sliders (or ctrl left/right by default on keyboard).
- In many circumstances a grid or hand card select screen will appear. Note that this is not the normal turn play card from hand screen. For example an instance of this is playing warcry (where you have to select a card to put on top of your draw pile). You need to hit proceed to exit this screen after selecting cards. For the hand card select screens, they are laid out in two rows (top row is cards selected, bottom row is cards in hand).

## Confirmation Prompts

Prompts such as the abandon run prompt provide a yes/no option. To confirm one of these prompts, use the proceed input. to cancel one, use the cancel input.

## Hand Card Select

Hand card select prompts consist of two rows. The bottom row contains the cards you can select from; the top row contains cards that have been selected. You can hit confirm on a card in the top row to deselect it. Once done, you can hit proceed (y/triangle/e) to confirm your selections.

## Menus

The menus overall work as expected, however:

- In the main menu, you can get to your save slots by hitting the map input (back/select/m).
  - In the save slots menu, hitting top panel (x/square/t) will allow you to delete a save slot and hitting proceed (y/triangle/e) will allow you to rename one.
- Character Select
  - hitting proceed (y/triangle/e) will toggle ascension mode, master deck and exhaust view inputs (the bumpers or d and f for keyboard) will change the ascension level.
- Custom Run
  - Top panel (x/square/t) will toggle ascension mode, deck view and exhaust view (the bumpers or d and f for keyboard) will change ascension level
  - Proceed (y/triangle/e) to start the run
- Settings Screen
  - This menu is laid out in a very inconsistent grid of two columns. Moving between items is not always consistent, especially when switching columns. This is not an issue with the mod but appears to be related to how the controller support for the game is implemented.
  - You can change tabs with the deck and exhaust inputs (bumpers or d or f on keyboard). Be very careful in the controls tab however as it is not supported by the mod yet.
  - Buffer controls next/previous (right stick left/right or ctrl left/right arrow) change volume sliders
- In-run pause menu/settings screen
  - To abandon a run, hit proceed (y/triangle/e)
  - to return to the main menu without abandoning the run, hit discard (rt/r2/w)
- Singing Bowl Relic requires exhaust view input (rb/r1/f)

## Game UI

The game, both in battle and outside of it, is laid out in a grid.

### Top Panel

The top panel takes up the top part of the screen and holds a number of your resources, such as your relics. You can get to it at any time by pressing top panel (x/square/t). You will have to do this to review other buffers if the map is currently showing. The top panel is always visible, regardless of whether the map, battle, or an event is currently displayed.

- The top row holds your player hp, your gold, your potions, and the ascension level (if applicable).
- The second row shows all of your relics

### Battle

The battle screen is laid out as follows, from bottom to top:

- Your hand
- the second row shows the player and monsters
- the third row shows any orbs and orb slots (if applicable; if not this row is not there)
- the top panel

When you play a card that does not require a target, you must hit the confirm button again in order to play it. If a target is required however you can just select it without having to double the input.

# The Map

While viewing the map, the buffer system is replaced with a map viewer. This allows you to quickly follow paths.

When playing Slay the Spire, you can view the whole map for a given act at any time by pressing map, as well as it being automatically shown between rooms. The map consists of rooms with curved lines indicating where you can travel to. The location of the player is either below the map (beginning of an act) or the room they last completed.

The map viewer is essentially a virtual cursor. If you move over a map node normally in the course of gameplay (that is, using the d-pad, arrow keys, or left stick), the virtual cursor will be set to that map node.

Use right stick left and right or control left and right arrows to move between possible choices (rooms you can move to from this node, only in the forward direction). Use right stick up or control up arrow to follow the path forward; this will move continuously until you hit a choice or dead end (such as a boss). Use right stick down or control down arrow to retrace your steps.

For example if given the following 3x4 map:

| 1 | 2 | 3 | 4
--- | --- | --- | --- | ---
2 | monster | elite | unknown | monster
1 | blank | merchant | unknown | blank
0 | monster | blank | blank | blank

Say you are starting below the bottom row. You have a single choice (monster, far bottom left) The only choice from there is merchant. There are however three choices (monster, elite, or unknown). From the bottom room your map focus will be on the first choice (monster). hitting forward will follow the path until it hits a branch point, so it will read something like this. monster, merchant, choice After that it will allow you to browse the choices as before. Note that it reads the choice again at the start of the path to avoid confusion, this isn't a bug. If moving backwards, the path is read in reverse as you would expect, unless you disable this setting in the config file.

# Keyboard Support and Virtual Input

## Keyboard Support

Say the Spire provides full keyboard support for the game. This is enabled by enabling the virtual_input setting in the config file (should be enabled by default). Virtual input also allows for additional mod behavior; see the section below.

Keyboard support works by emulating gamepad controls. For example, pressing e (proceed) is equivalent to triggering the same action via a gamepad (y/triangle by default). The game has a number of UI querks; it is recommended that you read the UI section.

Keyboard remappings can currently be modified by editing input.json. A better method for remapping is being worked on and it is not recommended you do this unless you are familiar with json. If you are modifying existing mappings, it should be safe to just modify the values within quotes.

# What Actually is Virtual Input?

Virtual input is a mod setting that adds a layer of hooks between the game's pre-existing input and the mod. This essentially means that the mod has additional control over how input is processed and adds the capacity for the mod to add new inputs. By default this setting is enabled, but can be disabled in the config file if you prefer to use the game's input handling. Note that doing this will disable keyboard support and revert to the game's keyboard handling, which lacks most of the features that the mod has. The buffer system for gamepad controls will still work when virtual input is disabled.

# Gamepad and Keyboard Controls

These are the default gamepad and keyboard controls for Say the Spire. The gamepad controls by default match what the game uses. for information on Virtual Input and Keyboard Support, go here.

## Game and Mod General Controls

Action | Controller (xbox/ps) | Keyboard
--- | --- | ---
movement (menus, general UI) | d-pad or left stick | arrow keys
confirm | a/x | enter
top panel, delete save slot | x/square | t
proceed, rename save slot, toggle ascension mode | y/triangle | e
cancel | b/circle | escape
master deck view, decrease ascension level | lb/l1 | d
Draw pile view/some other contextual options | lt/l2 | q
Exhaust pile, Singing Bowl hp increase, increase ascension level | rb/r1 | f
Discard pile/some contextual options | rt/r2 | w
buffers, map, and settings sliders | right stick | control arrows
settings/pause | start | backspace
Map, save slots (from main menu), general back option | select | m

## Info Controls

You can press control in combination with another key to quickly read additional information about the player or general game state. These controls are only available for keyboard and more will be added in future updates. To see the health of the player for example, use ctrl+h.

Action | Keyboard
--- | ---
Current Block | ctrl b
Current Gold | ctrl g
Health | ctrl h
Energy | ctrl y
Summarized intents (total incoming damage) | ctrl i
detailed intents (read all monster intents) | alt i
Current Act Boss | ctrl n

# Config Files and Changing Mod Settings

After first launching the game, two config files are created that allow you to modify certain aspects of the mod. These files can be found at:

- Windows: `%LOCALAPPDATA%\ModTheSpire\sayTheSpire\`
- Linux: `~/.config/ModTheSpire/sayTheSpire/`
- Mac: `~/Library/Preferences/ModTheSpire/sayTheSpire/`

The settings.ini file allows you to change various settings related to the mod. The input.json stores keyboard mappings. It is not recommended to manually modify input.json unless you are familiar with json.

## Settings.ini

This is a list of all of the available options in settings.ini. To change one of these, change the value to the right of the `=`. For example you could disable reading block text by changing `block_text = true` to `block_text = false`.

Certain config options require an array, a list of values. An array always starts with `[` and ends with `]`. These values must be enclosed in quotes if they are strings of text. For example to exclude cards and relics, you would use `exclude_read_typenames = ["card", "relic"]`

### [advanced]

Advanced settings related to the internals of the mod.

Setting | Accepted Values | Default Value | Description
--- | --- | --- | ---
use_updated_card_description | true, false | false | whether or not to use a different internal property to get card descriptions. This should be enabled if you are trying to use mods that do not have properly rendered card descriptions. This may break depending on your current game language so use this with caution.
prefered_speech_handler_order | [ array of speech handler names ] | [] | Your prefered order of speech handlers. For more information, see the next section on speech handlers.
speech_handler_force_system_speech | true, false | false | Whether or not system speech (for example SAPI) is used (if your speech handler supports it.)

#### Speech Handler Priority

The mod has a number of speech handlers stored internally. Each speech handler allows output via a specific library or process and the best one for your system is loaded by default (for example Tolk for Windows). There is a default order for them. when the mod is first loaded, handlers are checked in order. If one meets the criteria to be used (for example correct operating system) it is set as the active speech handler and all text output from the mod will be output via that handler.

If you would prefer a different order (such as forcing clipboard output for example), you can reorder the list via the advanced.prefered_speech_handler_order setting. The speech handler names you add to the list will be moved to the beginning of the list in the order you specify. For a list of speech handlers, see the table below. The table below lists the handlers in their default order.

Handler | description | Criteria to Use | Supports System Speech
--- | --- | --- | ---
tolk_resources | Uses the Tolk (screen reader output) library for Windows and automatically extracts dlls needed at runtime. Dll files are removed when the game is closed. | Windows | Yes
tolk | Uses the Tolk (screen reader output) library for Windows. You will need to copy required screenreader dll files to the game directory to use this handler. | Windows | Yes
clipboard | Sends all text output to the clipboard. This is useful for translation or for some specific screen readers. | All | No

### [combat]

Settings related to combat messages.

Setting | Accepted Values | Default Value | Description
--- | --- | --- | ---
block_text | true, false | true | Whether or not to read when a creature gains block.
buff_debuff text | true, false | true | Whether or not to read when a creature gains a buff or debuff.
card_events | true, false | true | Whether or not card events are read. These include cards being added to draw, discard, etc as well as cards being exhausted.
orb_events | true, false | true | Whether or not orb events are read. This includes when orbs are channeled and evoked.

### [input]

Settings related to virtual input.

Setting | Accepted Values | Default Value | Description
--- | --- | --- | ---
virtual_input | true or false | true | Whether or not virtual input is enabled.

### [map]

Settings related to map reading.

Setting | Accepted Values | Default Value | Description
--- | --- | --- | ---
read_reversed_paths | true, false | true | Whether or not to read the path in reverse when moving backward on the map, as if you were tracing it visually. Many people prefer to disable this to save time but it is enabled by default for clarity.

### [ui]

Contains settings related to the game's UI and how certain elements are read out.

Setting | Accepted Values | Default Value | Description
--- | --- | --- | ---
read_proceed_text | true, false | true | Whether or not to read the proceed text when the option is available (for example to skip a combat reward)
read_banner_text | true, false | true | Whether or not banner text is read. Banner text appears at the top of the screen and generally acts as a screen title.
read_positions | true, false | true | Whether or not to read the position of an element (for example 1 of 3 in a list)
read_types | true, false | true | Whether or not element types, such as button, are read for each UI element.
read_obtain_events | true, false | true | Whether or not the mod notifies you when you obtain an object (such as a card, potion, relic, etc).
exclude_read_typenames | [array of strings] | [] empty | An array or list of types to not be read. For example if you do not want cards and relics to say card or relic after their name, you could set this to `["card", "relic"]`.

### [resources]

Settings related to how resources are loaded and unloaded. If you are experiencing a crash when closing the game, set both of these to false.

Setting | Accepted Values | Default Value | Description
--- | --- | --- | ---
unload_native_libs | true, false | true | Whether or not to unload the screen reader libraries from memory when the game closes.
dispose_resource_files | true, false | true | Whether or not to delete the screen reader dll files in the slay the Spire root directory after the game closes and they are unloaded from memory. Do not enable this unless unload_native_libs is enabled or it won't work.

# For Developers

If you are looking to work on adding additional functionality to the mod, this section details how to compile the mod. if you are looking to localize the mod, go here.

## Compilation

### Mod Requirements

SayTheSpire requires both ModTheSpire and BaseMod in order to run. As a result it needs these jars to compile.

- ModTheSpire
- BaseMod

Paste modTheSpire.jar and BaseMod.jar into the lib folder at the root of this repository. If one does not exist it is safe to create one.

### Setting up Screen Reader Libs

In order to use screen reader output, you need Output libraries for all supported operating systems. These are required for the mod to compile.

#### Windows

For screen reader output on windows, the Tolk library is required. You can find Tolk here. Clone this repository and compile the .jar.

You need to set up the Tolk.jar as a maven dependency. To do so, run this command from the repository's root, substituting in the correct path for your Tolk.jar and leaving the other parameters unchanged:

    mvn install:install-file -Dfile=path/to/Tolk.jar -DgroupId=com.davykager.tolk -DartifactId=Tolk -Dversion=unknown -Dpackaging=jar

If you want screen reader dlls to automatically extract at runtime, download the release from the Tolk github page (Latest build from AppVeyor). Paste the x86 and x64 directories in src/main/resources/tolk/, so you should have a directory structure resembling this.

- src/main/resources/
  - tolk/
    - x86/
    - x64/

Note that if you do not add these files to resources, you will have to manually place the correct dlls in your root SlayTheSpire game directory.

#### Linux

For screen reader output on Linux, speech dispatcher via the speechd library is used. Clone the speechd github repository and use ant to compile it.

You will then need to set up the package as a Maven dependency. To do this, use this command, substituting in the correct path to speechd.jar while leaving the other parameters unchanged:

    mvn install:install-file -Dfile=path/to/speechd.jar -DgroupId=speechd -DartifactId=speechd -Dversion=unknown -Dpackaging=jar

### Packaging and Setup

To compile the mod, run

    mvn package

This should compile the mod and bundle all needed screenreader library files and other dependencies into the main .jar file. After that, copy mods/sayTheSpire.jar to your Slay the Spire mods directory.

# Localization

The mod can be localized into any language the game supports. Currently there are no language files besides English implemented. This page provides information on how the system works and how to submit language files. Keep in mind that this feature is still in early beta and that more strings will be added as the mod develops, though the currently existing strings shouldn't change.

You will need to be comfortable with the json file format and to be familiar with how java projects and Slay the Spire mods are compiled. For more info on this I recommend looking at the available documentation for ModTheSpire. I also recommend looking at the notes for translators file compiled with the game's .jar file (/localization/TRANSLATOR_README.txt).

## How it Works

Language files are written in the json format. When Say the Spire outputs localized text, it checks 3 locations in order, falling back to the next one if no localization string matching the text to be localized is found in that file:

- your mod config directory/sayTheSpire/languageTemp.json (note this is the folder where settings for Say the Spire are stored on your hard drive, not in the mod .jar file)
- /localization/langcode/say-the-spire.json (this is bundled in the mod .jar file)
- /localization/eng/say-the-spire.json (this is bundled in the mod .jar file)

An example of a set of localization strings would look like this (from the localization strings for the card buffer):

        "card": {
          "faceDown": "face down card",
          "localizedName": "current card",
          "localizedNameUpgraded": "upgrade preview",
          "noFurtherUpgrade": "This card cannot be upgraded any further.",
          "noObj": "No card available; report to mod developer.",
          "content": {
            "cost": "{cost} energy",
            "typeAndRarity": "{type} type, {rarity} rarity",
            "unknownKeyword": "Unknown keyword {unknownKeyword} found; report to mod developer."
          }
        },

The keys are just references that Say the Spire uses for the localization strings themselves; the strings are the values of each object (the text in quotes after the ':'). Any text surrounded by {}, for example "{cost} energy", is a substitution. When the string is localized, it will substitute the {energy} for the amount of energy required to play the card. As an example, for bash this string would render as "2 energy" in English. Note that substitutions themselves are assumed to be localized (for example, if a substitution {rarity} held a card rarity, the text passed to that substitution would be localized already.)

## How to Localize

To localize the mod for a given language:

- If there is no file for a language, start with the english json file and use that as a base. If you are working on a preexisting language file, copy it from the corresponding src/main/resources/localization directory and use it as a base. You can save this in your mod config directory as languageTemp.json; this file will have priority over any other language file. This means that you won't have to recompile the entire mod every time you make a change.
- Change the strings for all values in each object (do not change any keys). Make sure to preserve all substitutions (for example {maxHealth}). Note that the language file will not automatically reload when it is updated; you must currently restart the game for your changes to take effect.
- When you have finished working on your file, there are a few ways you can submit changes:
  - Fork the repository, copy your file to the correct src/main/resources/localization folder and submit a pull request. This is the recommended approach.
  - Open an issue on the github repository and attach your .json file to it.

# Developer API

Say the Spire comes with an API that allows other mods to interact with it. This is currently in very early stages so a lot of the functionality isn't yet exposed and it may not be obvious how to fully use it.

To access the API, import `sayTheSpire.SayTheSpire`. More detailed information will be posted here later, but see the SayTheSpire.java file for more information on the functions that have been added so far.

# Change Log

## 0.5.0-beta (2023-05-24)

This is the last major UI patch before version 1.0. This adds support for the few remaining inaccessible screens and fixes missing unlock texts. Note that, despite the leaderboard and daily leaderboard screens being supported, your own scores will not be automatically uploaded due to Slay the Spire preventing modded games from posting scores.

- Added: Unlock texts (such as cards, characters, and relics being unlocked) will now be read correctly. Note that you can't view information on what you just unlocked on the unlock screen; this is a game limitation as far as I can tell and everyone has to check other screens for that info.
- Fixed: The daily run screen will no longer constantly force the buffer focus onto the UI buffer.
- Added: The daily leaderboard is now supported.
- Added: The leaderboards screen is now supported.
- Added: The credits are now read out.
- Added: The patch notes screen is now supported.

## 0.4.3-Beta (2023-5-10)

- Added: The run history screen is now fully supported.
- Fixed: element types (such as button) will now actually be localized
- Fixed: the dropdown menus have been refactored behind the scenes. This shouldn't have any noticeable effects but please report it if there are any.
- Added: Russian localization (thanks @darrthscorrp)

## 0.4.2-BETA (2023-02-26)

- Added: Added an official API for other mods to interact with Say the Spire. for more information, please see the relevant section of the documentation.
- Fixed: The shop has been reworked; cards that are added after the shop opens (for example from the courier artifact) will now be correctly read out
- Fixed: Speech will now actually interrupt for all inputs (not just controllers)
- Fixed: The info from shortcut keys (for example ctrl b to see block in combat) can now be correctly localized.
- Added: Added a comma between your list of powers and the word powers to make it less ambiguous
- Added: Added additional logging info to more reliably detect issues when loading speech handlers.
- Added: Added monster name substitutions as certain monsters have multiple variants, yet they have the same name for all versions of the monster. The blue and red slavers should now be correctly read out. If there are any more monsters like this that I missed please let me know.

## 0.4.1-beta (2023-01-05)

- Fixed: The game will no longer crash when disabling ascension mode due to an incorrect string path.
- Added: The game can now be localized. If there is a file for your language, messages from Say the Spire should automatically use that language. Note that there are no other language files yet besides English. For more information on localization or how to contribute localized strings, see the documentation.
- Added: Screen reader output via Speech Dispatcher on Linux (thanks Lilmike).
- The Map:
  - Fixed edge tags not reading when cursoring over a map node
  - Edges that require flight are now correctly labeled and the mod does not consider every edge to require flight once you obtain the Winged Boots
  - The map viewer no longer focuses an incorrect node at the start of act 3 when cursoring over a node on the map.
  - The map viewer will no longer crash if looking for a backward path in Act 4
  - The currently focused map choice is now read out again when you view the map screen

## 0.4.0-beta (2022-12-22)

- This was a large update; most of the code behind the scenes was refactored in order to support localization. Localization is not quite ready yet; this update is to make sure that the initial changes to the framework are working. There haven't been many obvious changes to the gameplay itself.
- The map:
  - This update significantly refactors the code for map navigation behind the scenes. The new code allows for easier localization as well as potential support for other types of maps and methods for viewing the maps in the future. No immediate changes should be noticeable (besides some text updates), however this was a significant update so some things may be broken that I missed. Please report anything that seems to not be working as intended.
  - Nodes you can travel to via flight only (for example using the Wing Boots relic) are now marked with "requires flight"
- Fixed: Issue where null text values could be output, causing most speech handlers to crash.
- Added: You can use ctrl p to check your powers.

## 0.3.5-beta (2022-06-06)

This is a quick patch to fix a bug where the virtual input setting was not being checked consistently. This lead to the virtual input keyboard support being always active as well as controller behavior being odd on certain screens.

## 0.3.4-beta (2022-05-23)

This is a quick fix to prevent a number of issues prior to adding localization support.

- The mod will no longer cause the game to crash due to conflicting versions of com.google.gson. This was causing crashes with some mods that use gson such as Downfall.
- com.google.gson is now used behind the scenes for json loading and saving. This should not change mod functionality in any way but this was needed to prepare for localization support.
- The mod no longer bundles a number of redundant dependencies in the .jar file. This should noticeably reduce the startup time of the game.
- Fixed an error in change log (you remove cards, not sell them) and updated documentation important notes with Steam accessibility changes and some clarifications.
- input.json now is actually loaded and no longer throws a null pointer exception.
- Added some keyboard shortcuts:
  - ctrl+y: Read player energy
  - ctrl+i: Read incoming damage (summarized monster intents)
  - alt+i: Read the intents of all monsters in sequence
- Speech output:
  - Speech handlers can be reordered (for example you could set clipboard output first if you prefer)
  - System speech (such as SAPI) can now be forced for speech handlers that support it.

## 0.3.3-beta

This should be the last general bug fix and gameplay notification patch before more features are added.

- Added: Achievement items on the character stats screen now have location information.
- Fixed: Block gains are now correctly read out if block was already greater than 0 (it was previously triggering on the wrong event and only reading when your block was 0 before the gain.)
- Added: Combat orb events are now read out (such as when they are channeled and when they are evoked). This can be configured; see the config section of the documentation for more info.
- Added: Monster deaths are now read out.
- Fixed: The input.json loading process is no longer horribly broken. This will allow for more actions to be mapped successfully without causing the game to crash.
- Added additional keyboard hotkeys to quickly read important player information:
  - The current act boss (ctrl n)
  - Player Block (ctrl b)
  - Player Gold (ctrl g)
  - Player HP (ctrl h)
- Fixed: The manual installation instructions in the documentation were incorrect; this has been fixed.

## 0.3.2-beta

- Fixed: The Gremlin Match game card bug is now actually fixed and will no longer read all of the possible cards before the game starts
- Added: The character stats screen is now supported. This screen appears to be buggy however and will not let you scroll to the individual character stats (below the achievement grid) correctly some of the time. This seems to be a game issue and not a mod one.
- A large number of events are now correctly read out:
  - Card manipulation events, such as cards being exhausted and added to your hand, draw, discard, and deck as well as the discard pile being shuffled into the draw pile
  - Cards are now read out when shown briefly (for example when two random cards are upgraded)
  - Obtained gold
  - Obtained key
  - Obtained potion
  - Obtained relic
- Added: You can now disable obtained events (obtain potion, relic, etc) and in combat card events (card exhausted, etc). For information on this, see the config documentation.

## 0.3.1-beta

A number of gameplay fixes and additions.

- Added: Blights are now accessible.
- Fixed: The buffers now correctly update when switching between items as per the pre-0.2.0 behavior. You should no longer get inaccurate player hp values when moving between items in the player buffer for example.
- Added: You can now prevent all element types (such as button) from being read or prevent specific element types from being read. See the configuration documentation for more information.
- Fixed: Buttons in the main menu are now actually considered buttons by the mod so UI settings related to them now work properly.

## 0.3.0-beta

This patch fixes a number of issues related to UI.

- The compendium screens are now fully supported
- The various deck view screens (draw, discard, etc) now read your total number of cards on that screen and announce the screen you are on.
- Cards
  - Location now properly announced
  - A new config setting has been added to improve mod compatibility as the localization fixes in the last beta broke certain card descriptions that were updated during gameplay by various mods. If you want to use certain mods that do this, set advanced.use_updated_card_description in your settings.ini file to true. Note that this will most likely break localization for certain languages (currently confirmed to break for Japanese).
  - Fixed an issue where numbers followed by punctuation would read incorrectly, for example the Feed card. See the text parsing section.
- Combat Rewards Screen
  - All rewards now have location information and properly update buffers
- Events
  - Fixed potential bug with Gremlin Match game where it would read the names of all cards as the event started
- General Gameplay Screen
  - All of the tooltips and associated resources are now viewable by browsing the main screen as intended (they are to the left of your potions)
  - The ascension level tooltip is now accessible (to the right of your potions)
- Monsters
  - Power tips (the descriptions of any applied powers in the buffer) will no longer incorrectly show formatting information if that information occurs at the start of the first word of the effect description (for example #y at the beginning of weak's description)
  - Monsters now have location information
- Potions
  - Potion location is now properly announced
  - Fixed a bug where you could not read the tooltip for an empty potion slot
  - Potion rarity has been added to the potion buffer
- Relics
  - Location is now properly announced
  - Relic rarity has been added to the relic buffer
- Shops
  - All shop items now have location information approximately corresponding to their on screen position
  - The button to remove a card is now actually announced as a button and has location information
- Text Parsing
  - Fixed a bug where words containing numbers would break if the number was immediately followed by punctuation. this primarily effected cards such as feed, where the 3 hp increase was read as !m!.

## Beta 0.2.0

- The versioning scheme has been changed to semantic versioning. This should allow for more clear version numbering for frequent updates instead of large spread out beta releases as it has been so far.
- Added: Introduction of the virtual input system allowing for keyboard support and additional mod specific menus. See the Virtual Input section of the readme for more information.
- Fixed: Strategic (attack and debuff intent) damage now correctly shows multihitting attacks
- Fixed: If no screen reader is running, the mod now correctly defaults to using SAPI on Windows.
- Fixed: Potential issues with speech not stopping on button press or stopping at the wrong time
- Fixed: Resolution options in settings no longer have "tab tab" after them
- Fixed: You can no longer see a face down or locked card's energy cost.
- Fixed: A number of issues related to buffers have been fixed
  - Buffers should no longer eroniously report null items
  - When the mod focuses a buffer (for example when moving over a card and the buffer for that card is selected), the buffer now correctly updates. this should prevent needing to refocus the buffer to read card information in some situations.
  - Fixed a potential crash if no buffer was selected and you tried to read the next or previous item.
  - Fixed a long standing bug where trying to review buffer items on the treasure chest screen would crash the game.
- Fixed: A number of issues related to parsing text in certain languages
  - Variable numbers on cards should now be read for all languages such as damage or block (thanks to @yncat for the code contribution).
  - Fixed issue in settings menu where the language dropdown would have formatting tags read for some languages
  - Strings of single characters will no longer crash the game in certain situations. This may fix issues with certain non-English language strings crashing the game.
- Added: Two new settings have been added to the config file: resources.dispose_resource_files and resources.unload_native_libs. These were added to deal with a rare issue with certain Steam setups that can cause the game to crash upon closing. These are both on by default but should be set to false if people are experiencing game crashes. The issue has most likely been fixed but these settings are left here just in case.
- Added: Messages sent to logs by Say the Spire have been standardized to fit the style of Slay the Spire's logs. This should make debug output a lot more clear.
- Added: The Say the Spire version is announced after the splash screen fully fades out.
- Fixed: The game should no longer crash on shutdown for some steam setups due to unloading the wrong native libraries too early. If a crash on shutdown occurs please report it (see the known issues section of this change log).
- Fixed: Dropdown menus that are not yet recognized by the mod will no longer cause the game to crash. As a result the run history screen will no longer crash the game. Note that the screen itself is still not yet read by the mod.
- Added: Card rarity is now included in the card buffer (thanks to @ohylli for the code contribution).

### Known Issues

- There was a rare crash for certain Steam setups that occured when the game is closed. It is believed that this issue is fixed, however if this happens, open settings.ini and change dispose_resource_files and unload_native_libs to false under the resources section. Screen reader dlls and a few .lib files will be left in your Slay the Spire program directory but nothing else will be effected.

## Beta 4/Public Beta 1

- Fixed: An update to Slay the Spire broke the mod due to a game file being removed; this has been fixed. Please report any other issues that may have been introduced in the most recent Slay the Spire update.

- Added: Certain UI elements (such as cards and orbs) now read their relative positions

- Fixed: The death text quote now reads correctly if you lose multiple runs in the same game session

- Added: the proceed option is now read out

- Fixed: You can no longer view card information if the cards are visually face down or locked

- Added: Match and Keep (the gremlin card matching event) is now supported

- Added: A config file can now be found in either your local app data (windows) or home config directory (linux). Currently the only supported config options are UI position reading, banner text reading, proceed reading, in battle block gains, in battle buff/debuff text, and reversed path reading.

- Fixed: Removed some redundant checks for hovered cards, hopefully this should remove some of the UI issues like some cards being read multiple times (this does not effect the hand, which I cannot fix)

- Added: All controller inputs now interrupt speech (as per normal screen reader behavior when using a keyboard application). This should make the game feel less sluggish.

- Changed: There have been some behind the scenes UI changes. Please report any buttons labeled incorrectly.

- Fixed: Hopefully the last of the settings name issues has been fixed (upload data no longer has #B in the name)

- Fixed: Dropdown menus in settings now read the elements correctly when the dropdown scrolls vertically

- Added: When a new event occurs, the event buffer's position is changed to that event

- Fixed: The player name is now correct for when text above them is read during combat (this would break when changing save slots).

- Fixed: Sort button headers for card grids should now be reading properly

- Added: Initial support for the daily climb screen. Only the challenge info is read currently, the leaderboard will come in the next beta.

- Fixed: Power text in combat should now be reading properly again. This is currently experimental and may still be broken. There are some oddities in the way text is displayed; I'm outputting how the game displays the text (for example when a buf is initially applied, it only says the name and not the initial amount).

- Added: In combat block gains are announced.

## Beta 3

- Added: Initial support for sort header buttons, however I don't think this is working properly
- Fixed: It was possible to have incorrect speech libraries be loaded or have working speech libraries fail to load
- Fixed: Some tooltips in settings were not being parsed correctly
- Fixed: Certain Settings screen items had incorrect tooltips associated with them due to the UI buffer not updating
- Added: The custom mode screen is now supported
- Added: Death and victory screens are now supported
- Aded: You can view game over stats on the death and victory screens individually (move over them, check buffers for additional descriptions if any)
- Added: Hopefully boss chests are read properly.
- Added: The banner is now read (some text at the top of the screen used contextually in diferent parts of the game). This includes a short line of text on the death screen, screen titles for areas such as awards "spoils!" etc.
- Added: When the map does a long scroll animation, the act boss is read

## Beta 2

- Fixed: Player name in player buffer is now correct when switching between save slots
- Treasure chests are now read? Hopefully?
- Fixed: Previously missing event text is now read properly (speech interrupt on card selection screens, etc was interrupting it)
- Changed: The monster short (text read when hovering over a monster) is now more convenient; the intent and block are read before the hp
- Added: keywords on cards are now in the card buffer.
- Fixed: Buffers would crash on certain screens, such as the death screen
- Fixed: Buffers should no longer read "name: null" when moving to them
- Fixed: Main menu buttons would sometimes repeat their label infinitely if you skipped past them too quickly (for example mashing select from the game over screen)
- Fixed: In combat events should no longer break in weird ways (such as wrong enemy names, wrong dialogue associated with each event, etc)
- Added: You can now see the relic and card previews for event choices (they show up in their respective buffers)
- Fixed issue where buffers updated at the wrong time (this could lead to buffers reading as empty when they were not, etc). also added more accurate buffer error messages.

### Changes That Could be Considered Spoilers

- The location of the emerald key is now announced on the map (as burning icon)

# Known Issues

- there is possibly a bug with some Steam setups where closing the game will crash due to native library files not being unloaded. It is believed this is fixed, but if this still occurs change resources.dispose_resource_files and resources.unload_native_libs to false in settings.ini.
- daily climb (leaderboard section doesn't read), input settings, and credits screens do not read. These are being worked on.
- Certain text (such as the character select text screen's title) don't automatically read. This is being worked on.
- Required controller inputs are not read/viewable. This is being worked on.
- The UI can jump between cards a few times (for example when retaining cards as the silent). this isn't an issue I can fix and does not break the game in any way.
- Currently certain text is only read in English (for example UI element types).
- There appears to be an issue where game input will not work at all if a ps5 controller is connected. I don't know what causes this but it doesn't seem to be anything related to the mod itself. If anyone has any information about this please let me know

# Credits

## Beta Testers

Thanks to the beta testers who tested the public and private betas, including but not limited to:

- Ahmad Abukhdair
- Austin Hicks
- Brandon Cole Website
- Kelsey Hendrix
- Mike Breedlove
- SightlessKombat Website