(Link to video)

Sync Info

MD5s
93f3a8e039ba1083ab351bf153ee4013  Animancer.x86_64
32ff50bac87f8d2d7644b60d316d3527  Animancer.pck
Command-line options should have --audio-driver ALSA
Audio will sound corrupted due to a Godot bug affecting old Godot versions. The game can be patched to fix the bug. At offset 0x138F9AB of the Animancer.x86_64 file, change the 0x63 to 0x01. This will result in the file having the MD5 fe9892c32e2b12b84fb3abc2c0f1e417. The run will sync regardless of this patch to note.

Comments

You have lost your soul. Your goal is to collect your soul, which is split into 3 pieces. You have the power to take a soul of different creatures to use their abilities. One soul allows for a double jump, another soul allows for a dash, and finally one of the souls allows for shooting fire balls.
For this TAS, only the dash soul is used, purely for speed purposes. Most of the game can be skipped with an infinite jump glitch. After you finish an attack, there is a small window where you are able to jump. This renders the double jump soul useless.
The path choosen is relatively straight forward given these circumstances. You are normally intended to backtrack after you have collected souls to collect the final piece of your soul, which is leftwards of where you initially spawn. The infinite jump glitch however let's this soul be obtained early and skip the backtracking.
After this, the infinite jump glitch can be used to get to the high ground of the grass area, where you normally have to go around through the cave to reach that high area. Here the second soul piece can be obtained.
Going forwards, various enemies are encountered, including importantly a dashing bird enemy. Killing this enemy allows for the dash soul to be obtained, letting the player quickly dash horizontally.
It is then just a mad dash all the way rightwards and downwards into the cave where the final soul piece resides. The game is done once the player touches this final soul piece.

feos: Claiming for judging.
feos: Nice glitch, and truly brilliant research, accepted.
To the publisher: Please patch the game file as explained above, or the audio will be broken (I verified).

despoa: Processing...

TASVideoAgent
They/Them
Moderator
Joined: 8/3/2004
Posts: 14772
Location: 127.0.0.1
This topic is for the purpose of discussing #7931: CasualPokePlayer's Linux Animancer in 01:17.45
Site Admin, Skilled player (1234)
Joined: 4/17/2010
Posts: 11251
Location: RU
How did you figure out which address to patch?
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Emulator Coder, Experienced player, Judge (593)
Joined: 2/26/2020
Posts: 691
Location: California
The core issue ended up being something found on the libTAS discord. It's simply this line of code being wrong: https://github.com/godotengine/godot/blob/3.2.1-stable/drivers/alsa/audio_driver_alsa.cpp#L190 as uint8_t* was the wrong type, uint16_t* was the correct one to use (that exact fix was later done in Godot anyways https://github.com/godotengine/godot/commit/4bf141a47e9d3ee2d38347d643aeca907e4e602b). The game runs on Godot 3.2.1, which predates this fix. I figured it should be possible to insert effectively a * 2 somewhere in the function's machine code to fix the issue. The way I found the function was probably more complicated than it needed to be. First, I compiled ALSA myself with -g (so debug symbols were available) and installed it on my system. Then I was able to simply run the game under gdb and put a breakpoint at snd_pcm_writei, and use the return address to figure out where the problematic function was located (this was the only callsite for this function, so this worked without much issue). With that, I had gdb spit out a disassembly the entire function, and with that I was able to deduce the assembly for calculating the second arg, and was able to figure out where I could place a * 2 for it. The patch specifically changes a movsxd rsi,esi (48 63 f6) to add rsi,rsi (48 01 f6). The original opcode is effectively a no-op in this context if esi is positive (if it is negative it would crash regardless), so this provided 3 free bytes to form a * 2 opcode. And it so happens changing it to add rsi,rsi (a+a is the same as a*2) is just a 1 byte change here, so I used that.
Post subject: Movie published
TASVideoAgent
They/Them
Moderator
Joined: 8/3/2004
Posts: 14772
Location: 127.0.0.1
This movie has been published. The posts before this message apply to the submission, and posts after this message apply to the published movie. ---- [5065] Linux Animancer by CasualPokePlayer in 01:17.45