An auto splitter for Hollow Knight: Silksong.
Get LiveSplit, 1.8.34 or later.
Right-click for the context menu:
- Open Splits, From File... : Select your
.lsssplits file. Go to HKSplitMaker to generate and download.lsssplits files. - Edit Splits... : Activate the autosplitter.
- Compare Against: Game Time.
See also:
Go to the LiveSplit One Druid Latest Release page,
and under the Assets section, download the one for your architecture and operating system.
When you run LiveSplitOne, it needs to have permission to read memory of other processes.
- Windows: no additional steps required.
- Linux: set the capabilities to include
CAP_SYS_PTRACE, with a command likesudo setcap CAP_SYS_PTRACE=+eip LiveSplitOneto run once after downloading LiveSplitOne. - Mac: you have to run it under
sudo, with a command likesudo ./LiveSplitOneto run every time you want to open it.
Right-click or Control-click for the context menu:
- Splits, Open... : Select your
.lsssplits file. Go to HKSplitMaker to generate and download.lsssplits files. - Open Auto-splitter... : Select the
silksong_autosplit_wasm_stable.wasmfile. Go to the silksong-autosplit-wasm Latest Release to download that. - Compare Against: Game Time.
- Hotkeys: Configure the hotkeys you want. The default hotkeys use numpad, so if your computer doesn't have a numpad, configure them differently.
The autosplitter currently requires the game to be running as an Intel / x86_64 process, not an Apple / arm64 process. So on Apple Silicon (M1, M2, etc.) Macs, you have to run the game under Rosetta:
- Right click on
Hollow Knight Silksong.appin Game Files,Get Info, check the box forOpen using Rosetta. - Next to
Hollow Knight Silksong.app, put asteam_appid.txtfile containing the number1030300. - Open
Hollow Knight Silksong.appdirectly from where it is in Game Files, not from your Steam library. - Check in Activity Moniter, on the CPU tab, the Kind column should say
Intelfor Silksong, notApple.
Go to the OBS LiveSplit One Latest Release page,
and under the Assets section, download the one for your architecture and operating system.
Follow the instructions in How to install:
- Windows: Extract the
obs-livesplit-one.dlltoC:\Program Files\obs-studio\obs-plugins\64bitor equivalent install directory. - Linux: Ensure the plugins folder exists with
mkdir -p $HOME/.config/obs-studio/plugins, then extract with a command liketar -zxvf obs-livesplit-one-*-x86_64-unknown-linux-gnu.tar.gz -C $HOME/.config/obs-studio/plugins/.
When you run OBS, it needs to have permission to read memory of other processes.
- Windows: no additional steps required.
- Linux: set the capabilities to include
CAP_SYS_PTRACE, with a command likesudo setcap CAP_SYS_PTRACE=+eip /usr/bin/obsto run once after downloading OBS.
Add OBS Source: LiveSplit One.
Properties:
- Splits: Select your splits file. Go to HKSplitMaker to generate and download
.lsssplits files. - Activate
Open the OBS Settings from File, Settings:
- Go to the Hotkeys section and scroll down until you find LiveSplit One.
- Set a hotkey for
Toggle Timing Method, and hit Ok. - Hit that hotkey once to switch from the default, Real Time, to Game Time.
You can show the completion percent with Edit layout:
- Plus, Information, Text
- Layout settings, Text:
- check the box for Custom Variable
- Custom Variable Name:
percent
Some percents might not update the percent immediately, but will update on the next save point or when you open inventory.
If you have the Hit Counter setting turned on, you can show the number of hits with Edit Layout:
- Plus, Information, Text
- Layout settings, Text:
- check the box for Custom Variable
- Custom Variable Name:
hits
You can also send hits to HitCounterManager via the LiveSplit.HitCounterManagerConnector component.
This auto splitter is written in Rust. In order to compile it, you need to install the Rust compiler: Install Rust.
Afterwards install the WebAssembly target:
rustup target add wasm32-unknown-unknown --toolchain stableThe auto splitter can now be compiled:
cargo b --releaseThe auto splitter is then available at:
target/wasm32-unknown-unknown/release/silksong_autosplit_wasm.wasm
Make sure to look into the API documentation for the asr crate.
You can use the debugger while developing the auto splitter to more easily see the log messages, statistics, dump memory, step through the code and more.
The repository comes with preconfigured Visual Studio Code tasks. During
development it is recommended to use the Debug Auto Splitter launch action to
run the asr-debugger. You need to install the CodeLLDB extension to run it.
You can then use the Build Auto Splitter (Debug) task to manually build the
auto splitter. This will automatically hot reload the auto splitter in the
asr-debugger.
Alternatively you can install the cargo watch
subcommand and run the Watch Auto Splitter task for it to automatically build
when you save your changes.
The debugger is able to step through the code. You can set breakpoints in VSCode and it should stop there when the breakpoint is hit. Inspecting variables may not work all the time.
My approach to adding a new autosplit would look like this:
- Search through the list of fields (Silksong-Mono-dissector.TXT) to find one or more candidate fields that might correspond to what the autosplit should look for. For example on
Silk Spear (Skill), my candidate fields werehasSilkSpecialandhasNeedleThrow, and I wasn't sure which was the right one. - Test all candidate fields using a testing tool (https://github.com/AlexKnauth/asr-unity-mono-mac-testing/tree/silksong in combination with https://github.com/LiveSplit/asr-debugger can test it on all 3 OS's, not just Mac), ideally playing the game from the point right before getting to the point you want, seeing that good candidates should be
falsebefore, and then once you get the skill or boss or whatever, good candidates should betrueafter. Even better to test using a 2nd moniter so you can see exactly when a field goes fromfalsetotrue. After I did this forhasSilkSpecialandhasNeedleThrow, I saw both go fromfalsetotrueat basically the same time, so this didn't actually narrow it down, but at least confirmed they were related. - If multiple candidates pass step (2), ask for help. In the example of
hasSilkSpecialandhasNeedleThrow, I got help from Atomic and Kazekai on the speedrun discord#ss-tech-supportchannel. - Make a new branch on your clone of the Github repository for the new feature you want to add. I'd recommend that you don't just use your master branch.
- Add the field to the relevant
declare_pointers!statement insilksong_memory.rs, add the split to theSplitsdatatype insplits.rs, and add the code for the split in the relevant function (eithermenu_splits,transition_splits, orcontinuous_splitsinsplits.rs). - Do not update
splits.json, unless you are deploying a new release, in which case see below. - Make a Pull Request on the Github repository (https://github.com/AlexKnauth/silksong-autosplit-wasm/pulls).
My approach to deploying a new release looks like this:
- Review Pull Requests, and merge those that are good and ready to the master branch.
- Update
splits.jsonwith the commandmake examples/splits.json. Ifmakesays it's up-to-date and you know it isn't,touch src/splits.rsbefore runningmakeagain. - Update
Cargo.tomlwith the new version number, following Semantic Versioning. GivenMAJOR.MINOR.PATCH:- Increment
PATCHwhen just releasing bug-fixes that don't add any new settings or splits. - Increment
MINORwhen the release includes new features, new settings, or new splits. - Increment
MAJORif there've been incompatible settings changes, but like... try to avoid those if possible.
- Increment
- Run
cargo bin both debug and--releasemode, and in both--no-default-featuresand default-features mode. Check thatCargo.lockhas been updated. - Commit those changes, which should include
splits.json,Cargo.toml, andCargo.lock, with a commit name starting withReleaseand then the new version number. - Add a tag with the new version number on the Release commit, and push both master and the tag.
- Check the CI to make sure all jobs pass. Sometimes there's a data race between jobs for
legacyvsstable, where they both try to create their own release at the same time, so a release with only one of them is created as the other fails. When this happens, re-run the failed jobs to ensure that the release contains bothlegacyandstablevariants.