Last active
June 14, 2023 08:37
-
-
Save jessechounard/c3fe77537fd6bd79eab6cd09588522ae to your computer and use it in GitHub Desktop.
SpeedrunHelper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // This file is for the speedrun community to use as a base for | |
| // their LiveSplit autosplitter. You can set it up to read the | |
| // memory you've layed out, and they can take it from there. | |
| state("GameName") { | |
| } | |
| startup { | |
| vars.scanTarget = new SigScanTarget(0, | |
| "de c0 ad de de c0 37 13" // tag (0x1337c0dedeadc0de) | |
| ); | |
| } | |
| init { | |
| var speedrunHelperPtr = IntPtr.Zero; | |
| foreach (var page in game.MemoryPages()) { | |
| var scanner = new SignatureScanner(game, page.BaseAddress, (int)page.RegionSize); | |
| speedrunHelperPtr = scanner.Scan(vars.scanTarget); | |
| if(speedrunHelperPtr != IntPtr.Zero) { | |
| print("[Autosplitter] GameName.SpeedrunHelper Found : " + speedrunHelperPtr.ToString("X")); | |
| break; | |
| } | |
| } | |
| if(speedrunHelperPtr == IntPtr.Zero) { | |
| throw new Exception("[Autosplitter] Can't find signature"); | |
| } | |
| vars.gameStarted = new MemoryWatcher<int>(speedrunHelperPtr + 8); | |
| vars.levelComplete = new MemoryWatcher<int>(speedrunHelperPtr + 12); | |
| vars.reset = new MemoryWatcher<int>(speedrunHelperPtr + 16); | |
| vars.watchers = new MemoryWatcherList() { | |
| vars.gameStarted, | |
| vars.levelComplete, | |
| vars.reset | |
| }; | |
| } | |
| update { | |
| vars.watchers.UpdateAll(game); | |
| } | |
| start { | |
| return vars.gameStarted.Current == 1 && vars.gameStarted.Old == 0; | |
| } | |
| split { | |
| return vars.levelComplete.Current == 1 && vars.levelComplete.Old == 0; | |
| } | |
| reset { | |
| return vars.reset.Current == 1 && vars.reset.Old == 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // This file is for game developers looking to make it easier on | |
| // the speedrun community to make an autosplitter for your game | |
| // The same idea would work in any language that supports fixed | |
| // layout of variables in static memory. | |
| // | |
| // Keep in mind, this is all read only, if someone uses a memory | |
| // editor to write to this memory, it won't change the state of | |
| // your game. So feel free to share any state variables here | |
| // that you think external tool developers might want access to. | |
| // (Score, time, number of lives, health, version number, etc.) | |
| // Just document what's in there and let the community build | |
| // a bunch of cool crap! | |
| namespace GameName | |
| { | |
| [StructLayout(LayoutKind.Sequential)] | |
| public static class SpeedrunHelper | |
| { | |
| public static ulong tag = 0x1337c0dedeadc0de; | |
| public static int gameStarted = 0; | |
| public static int levelComplete = 0; | |
| public static int reset = 0; | |
| } | |
| // in your GameName.Program.Main function | |
| private static void Main() | |
| { | |
| // access the static class ASAP to make sure it's in memory and ready to go | |
| SpeedrunHelper.gameStarted = SpeedrunHelper.levelComplete = SpeedrunHelper.reset = 0; | |
| // your Main() startup code | |
| } | |
| // we changes states in the splitter when we see the variables changing states | |
| // set gameStarted to 0 in the main menu, set it to 1 when they hit play | |
| // set levelComplete to 0 when a new level is launched, set it to 1 when the reach the end | |
| // whenever the player chooses to exit early to the main menu set reset to 1 | |
| // set it back to 0 once the game starts | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment