Skip to content

Instantly share code, notes, and snippets.

@just-ero
Last active April 5, 2024 23:53
Show Gist options
  • Save just-ero/9f21152d9b3982cee3bc522d3114a633 to your computer and use it in GitHub Desktop.
Save just-ero/9f21152d9b3982cee3bc522d3114a633 to your computer and use it in GitHub Desktop.
Provides some general information about how to go about making a LiveSplit auto splitter.

Resources to learn making very simple Auto Splitters

Preamble: this should not be attempted with online games or games which have an anti cheat in place, it could result in permanent bans.

Learn how to use Cheat Engine

The Cheat Engine section in the #tutorials channel in the Speedrun Tool Development Discord server has a few tutorials and guides. It is recommended to also do the Cheat Engine tutorial when the software is first launched. The Cheat Engine wiki and forums also have more resources. Cheat Engine is usually used to find health or money addresses to edit their values. Those addresses will be the information your auto splitter will depend on for everything it does. Should the goal be to split upon level changes, searching for an index (often int (4 Bytes)) or a name (string) can yield good results. For load removal, an address that has a specific value only when the game is loading is the most useful (e.g. 1 when loading, 0 otherwise (this would be a bool, but shows up as a Byte in Cheat Engine)). The values to look for will differ between games, the process to search will always be more or less the same. If none of your attempts result in success, some out-of-the-box techniques may need to be tried; other people's auto splitters may be able to lend inspiration.

Some important notes:

  • for most games, it is sufficient to find an address to a desired value (money, health, etc.) and perform a pointer scan on it

  • when the value's found address is in a green color, a pointer scan does not need to be done (this is called a static address)

  • for Unity games, some special techniques can be applied:

    • decompile the game's Assembly-CSharp.dll file with one of these programs
    • for IL2CPP games, dump information as best as possible with one of these programs
    • when exploring the code, interesting classes are usually called something along the lines of GameManager, PlayerController, GlobalData, LevelScript
      • especially good are classes which have a static "instance" field of themselves or inherit from a Singleton<T>[1]
    • use Cheat Engine's mono dissect feature to explore classes, fields, offsets, and addresses
    • IMPORTANT NOTE: mono has a very specific way for building pointers manually, such that blind pointer scans need not be used!
    • all Unity games make use of a SceneManager, which stores the current scene, its index and all scenes which are meant to be loaded (making splitting and load removal incredibly easy)
  • for Unreal Engine games, some special techniques can be applied:

    • some games' classes and fields can be retrieved along with their names and offsets
    • most games' pointers start in the game's GWorld, a static pointer to the current game world, or GEngine, a static pointer to the game engine
    • techniques to retrieve the mentioned objects vary throughout engine versions
      • there is no free software to help with this!
    • IMPORTANT NOTE: when the mentioned objects can be successfully retrieved, blind pointer scans need not be used!
  • for GameMaker Studio games, some special techniques can be applied:

    • GMS games have a static address to an int (4 Bytes) value storing the current room_id, making a lot of things very easy
    • all other variables in every GMS game are of type double, even bools

For further questions, please join the Discord and post any and all questions in #auto-splitters!

Learn how to write auto splitter scripts (ASL scripts)

Once all addresses and/or pointers have been found, a script can be created.

Resources:

Important notes from the documentation:

ASL Pointers

  • ASL uses native C# 6 in every block except state {}; if something is unclear or other assistance is required, the Microsoft Docs can go a long way

[1]:
public GameManager
{
    public static GameManager _instance;
}    
public GameManager : Singleton<GameManager> { }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment