A TAS of Pokemon Emerald using Arbitrary Code Execution (ACE) to take the game where it's never gone before, faster than ever before!
Table of contents
- RNG Manipulation
- Game version
- Pomeg Glitch
- Special Thanks
- Possible Improvements
I'm working on the encoding movie, it should be linked in here soon!
Suggested screenshot(s): https://imgur.com/a/Dv5pu3M
Emulator used: BizHawk 2.4 (mGBA core)
I started on 2.3.2, but it should sync on both that version and 2.4.
You'll need to set Skip BIOS to False and the RTC initial time to 1/1/2010.
- Starts from scratch; no save data
- Completes the game as fast as possible
- Heavy RNG Manipulation
- Corrupts RAM
- Abuses glitches
- Executes arbitrary code
Pokémon Emerald is the final game in the 3rd generation of Pokémon, developed by GameFreak and released in 2005 as the sequel to Ruby & Sapphire. The game features a new story where you capture and fight with Pokémon against not one but two villainous teams. It also has a few new glitches not present in the games before it.
When I started working with the Pokémon Emerald decompilation project, I learned about many of these glitches, including arbitrary code execution using glitch moves via the Pomeg glitch. I found out that Pomeg berries were available several minutes before the published TAS and RTA runs picked them up, and wondered why this was the case. Previous runs beat Emerald by acquiring a pokémon with a glitch Instant Victory Move, which let them win any battle, but they still had to beat the 6th gym and the Elite Four to finish the game.
ACE setups for Emerald had been researched by Metarkai and others and were known to be possible. There are a few Youtube videos around describing how to perform them, but none of the setups were fast enough to be useful for a TAS—they either require many unlikely corruptions to set up, write code via glitch items that take time to acquire, or need in-game trade pokémon that are too far out of the way to get.
If a better, more consistent ACE could be found, the game could be beaten with only 5 badges and in much less time. I became convinced that this had to be possible. But in order to find out, I had to do my own research.
I started to look for a better way, and gave it up after a few weeks out of frustration. I had been testing on the English version of Emerald, using nicknames to write code, but because of the limited character set it was painful and impractical. Eventually I tried again and found that on the Japanese version of Emerald, things were better and ACE could be a viable strategy in a TAS, and possibly even RTA. The beta version of this TAS using move ACE can be found here.
Soon afterwards, I was linked to a video of a Japanese runner performing an as-yet unknown ACE method. I reverse-engineered and improved on that method, and after several speedrunners found success with it, I decided that using it would be faster.
This TAS is the result of that research, and, I think, demonstrates a significant technical improvement, beating the game with only 5 badges using a custom payload written in Japanese PC Boxes.
The result is a 20 minute improvement over the published TAS.
There are a few terms I'll use that are important to distinguish:
- Exactly 280,896 cpu cycles or 4389/262144 of a second. Emerald runs at approximately 59.73 FPS.
- 1 advancement of the RNG state.
Cycles are not in sync with frames because many things advance the RNG state:
- In the overworld, the RNG advances once per frame
- Each time an NPC/trainer turns or walks on their own, the RNG advances
- In battle, the RNG advances twice per frame
- AI/Accuracy/critical/damage calculation advances the RNG
- Crossing encounter tiles (grass) advances the RNG 1-2 times during the encounter check
- Running near NPC trainers (spinners) advances the RNG around twice per frame
It's important to count both cycles and frames, because some events in the game are cycle-locked but not frame-locked, meaning that they occur on a certain cycle but that cycle may possibly be reached at an earlier frame. There are many cases where frames can be saved by advancing the RNG faster than it otherwise would, such as in battles or near spinners.
Emerald's RNG is a 32 bit LCG that uses the formula
next = (current * 0x41c64e6d + 0x6073) mod 2^32. The full 32-bit state is not exposed when the RNG is used—only the high 16 bits are shifted right and returned. Throughout,
rngrefers only to the high 16 bits of the full 32-bit state.
Because of a programming oversight, the RNG is not seeded on soft reset, meaning that the initial seed is always zero. The only time the RNG is seeded is when starting a new game, immediately after the player confirms their name. This process is quite precise: when the naming screen is entered, the game starts one of the GBA's fast timers, which runs at a multiple of the CPU clock (much faster than the framerate). Confirming the name stops this timer and seeds the RNG with its value.
Trainer ID/Secret ID Manipulation
The visible trainer ID is set when the name is confirmed; this is also the value used to seed the RNG. The hidden, secret ID is set just before your sprite disappears after Birch's speech, using the RNG state at that time. In-game, these values are combined internally into a single 32 bit value, with the TID and SID as the low and high 16 bits respectively. Although the timer for the TID is very fast, it can be manipulated in a limited way by waiting/pressing more or fewer buttons in the naming screen, because pressing a button takes slightly more cycles. The SID can be manipulated simply by waiting for the correct cycle.
Method 1 (Mudkip) manipulation
Smogon has a good article on this. When you pick a starter, the RNG is advanced 4 times.
- The first and second values become the low & high 16 bits of the PID, respectively.
- The third and fourth values become the starter's IVs.
Battle AI/Quick Claw manipulation
Each turn in battle, just before the game displays the FIGHT option, the opponent's AI runs, advancing the RNG a number of times (this is highly variable, and dependent on what your pokémon is, their moves, etc). A value known as the
randomTurnNumberis also chosen from the RNG. This is used only for Quick Claw—if it is less than 0x3333, Quick Claw allows the holder to go first.
By timing when turns start the AI's decisions can be manipulated to choose certain moves, or allow Quick Claw to activate.
Whether a move will hit is determined just before the attack string is printed. The formula is:
if (rng mod 100) < move_accuracy * stages then HIT, where
stagesis a scaling float that is normally 1, and goes up & down with accuracy and evasion stages.
Critical and damage calculation are done just after the attack string is printed. Damage calculation happens 6 cycles after critical calculation.
The critical formula is:
if (rng mod crit_mod) == 0 then CRIT; in this run
crit_modis always 16. Damage is calculated as a scaling value, from 85-100%, inclusive:
scale = 100 - (rng mod 16).
Critical hits always deal double damage, and ignore any of the target's stat boosts.
Wild Pokémon/Encounter manipulation
There's an important overworld value called the
tileTransitionState. This value is normally 1 while moving, 0 when standing still, and briefly 2 when the player passes over the center of a tile.
Encounters occur 1 frame/2 cycles after the frame just before this value becomes 2. If stepping between similar tiles (i.e grass into grass), the formula is:
if (rng mod 2880) < rate * 16 then ENCOUNTER, where
rateis the encounter rate of the area.
If an encounter occurs, the RNG is advanced several times:
slot = rng mod 100. Each land area has 12 slots; the slot value determines which pokémon appears. The twelve slots together cover the entire 0-99 range.
- The RNG is used to calculate the encounter level.
nature = rng mod 25. The RNG is rolled to pick an initial nature. Afterwards, the RNG is advanced twice at a time, forming a PID, until
PID mod 25 == nature
Encounters can be manipulated by timing the cycle on which the tile transition occurs. When on the bike, the encounter rate is reduced by 20% (the rate is calculated as
rate * 16 * 80 / 100). There are also fewer slots when surfing, and some other minor details that aren't too important.
Although text does move slightly faster on the Japanese version of Emerald, this is not why I chose it. Rather, the advantage of JP Emerald lies in its character set. The Japanese character set gives access to many more bytes than the English set. Because arbitrary code execution targets PC box names, having more characters available makes the assembly payload shorter and easier to write. In speedruns of English Emerald, 8 box names of code are required to beat the game. In contrast this TAS requires only 5.
Learning that JP had this property and disassembling the Japanese ROM is what inspired me to make this TAS in the first place.
The Pomeg glitch has been known since around 2006-2007, but it took years for its full potential to be realized. The name comes from the use of Pomeg berries. Using a Pomeg Berry on a pokémon which gained HP through EVS will decrease its HP. If the pokemon loses its last HP due to this, it will be knocked out, even if it is the last conscious pokémon. This will not force the player to white out and the totally KO-ed party allows you to battle with Eggs and perform Glitzer Popping, among other things.
Named by Werster, this glitch works by accessing "pokémon" beyond the sixth slot of the party and modifying memory.
Bulbapedia has an article on this glitch.
The procedure in this run works as follows:
- In order, create a team of: 1 "sacrifice" pokémon (Poochyena), 1 pokémon at 1 HP for the Pomeg glitch (Abra), and a third pokémon you want to corrupt (Marshtomp).
- Enter a battle, knock out the sacrifice pokemon, and set the last used party slot to 3 (by switching in Marshtomp).
- Deposit the third pokémon. Now slot 3 is empty, but the player still has the conscious Pomeg pokémon.
- Use the Pomeg berry on the Pomeg pokémon. Now the player has no conscious pokémon but does not white out.
- Enter a wild battle. The game scans the player party for a conscious pokémon to send out. Since it sees none, it does not update the index, and sends out the now-empty slot 3, a ?? or "Decamark".
- Enter the party menu, view the summary of the sacrifice pokémon, and exit it. This refreshes the party count to zero.
- The party selection pointer underflows, allowing pokémon above slot 1 to be selected by repeatedly pressing Up.
- The selection pointer is warped into non-party memory, starting at Box 2 Slot 24 of the PC, and ascending 100 bytes with each up press.
As the pointer ascends, it treats 100-byte blocks of memory as party pokémon, and runs an anti-cheat function on them. If the checksum of this "pokémon" is invalid, which is likely, a few bits will be set or flipped corresponding to the
badEggbits.. This minor bit-flipping allows for precise corruption of RAM.
When the pointer selects an invalid block, two types of corruption can occur:
- Type 1 corruptions are fixed, 20 bytes after the pointer, and set bits 0 and 2 to 1.
- Type 2 corruptions vary depending on the PID of the block and can set bit 6 to 1 or 0 depending on "pokémon" data.
Corrupting a pokémon's PID can swap the order of its data structures, for instances, swapping EVs and moves, or (in this run) EVs and species number. If done carefully, this corruption keep the checksum legal and gives access to "glitch" moves or pokémon outside the normal move/species lists.
Another anti-cheat feature works in our favor here: PC and Item data's memory locations are randomly shifted by an offset whenever the player opens the party menu, enters a battle, etc. Since the memory location of a pokémon targeted for corruption can be manipulated, but the corruption locations are fixed, certain kinds of corruptions are always possible, you just need to roll the right memory layout.
In this run, corruption type 2 is used to set bit 6 of Marshtomp's PID, causing its EV data to turn into its growth data. This turns it into an Egg of a glitch species (0x615), which lets us trigger ACE by viewing its sprite.
In Emerald, every Pokemon has a small animation that plays when it is viewed. The pokemon species specifies the callback function that should be called. Glitch pokemon, whose species number is higher than the total number of actual pokemon, read the pointer for this callback from out-of-bounds data. By figuring out the formula for what determines the callback address, I found that there are several glitch pokemon whose callback functions are in RAM, specifically in PC data which we can manipulate. In this run, we acquire glitch pokemon 0x0615 and hatch it, running code in PC Box names.
The early game is similar to previous Emerald TASes. The main differences pre-Pomeg are:
- Marshtomp KOs a Solrock in Meteor Falls to gain 6 Attack EVs.
- Fly is not needed and so there is no need to catch a Tailow.
- Fewer items are used, and they are purchased at Fallarbor's Mart earlier.
- Strength is not acquired or used; we instead backtrack through Route 113.
- We fight different trainers in the Petalburg Gym, because of the required EVs on Marshtomp.
- A "sacrifice" pokémon (Poochyena) is caught.
- We buy two HP Ups from the Slateport market.
- Pomeg berries are acquired earlier from the Berry Master, along with a Kelpsy Berry.
After getting the Pomeg berry, the route diverges significantly. Everything from the Weather Institute onwards is skipped by warping to the end of the game.
The first thing to do is to disable animations to save time throughout the run, and pick a nice-looking border. I chose the kana for 'U' as my trainer name because it was short and represents 'U', the viewer. And because it seemed like it might be funny to anyone who speaks Japanese unlike me. A few extra buttons (L&R) are pressed here to manipulate trainer ID—since the RNG is seeded with the timer here, we need to pick a seed that gives us access to a good Mudkip!
Specifically, we'll be using a Rash Mudkip with PID
89613C19and these IVs: (30, 31, 16, 28, 1, 10).
The first step we take in the truck plays a "bumping" sound, which happens when we bump into a wall and immediately turn on the next frame instead of waiting to turn. This is used throughout the run.
Once we have Mudkip, we battle Brendan, get Running Shoes, our Pokédex (not that we'll be filling it much), Poké Balls, and we're off!
After beating the Youngster, we do some furious running near the spinner girl to advance the RNG more quickly for the Ralts manipulation.
We'll need to teleport back here 3 times later, so we briefly enter the Pokémon Center to set the Teleport point.
Poor Wally. He wants a Pokémon but can't figure out how to catch one!
Unfortunately for him, we manipulate his borrowed Zigzagoon and the Ralts he fights so that he KOs it instead of catching it. The game doesn't actually take this into account, but we still save time by skipping the catch animation.
This can only happen if Zigzagoon has an Attack IV of more than 25, and Ralts has a Defense-lowering Nature and less than 4 HP IVs and 6 Defense IVs. It's rare for a given RNG cycle to cause this, which necessitated advancing the RNG earlier to hit it.
We finally get away from Dad, and Wally, only for Scott to show up and stall us even more. We then head west to Petalburg Woods to find a Devon clerk looking for a Shroomish, but he's attacked by a Team Aqua Grunt! 3 critical Tackles make quick work of his Poochyena though. Mudkip's speed, which usually doesn't matter much in this run, matters here: if it doesn't have a higher enough Speed IV, this Poochyena will outspeed it and make us take 3 hits instead of 2.
The first thing we do is head right to the Trainer School to get the Quick Claw, which will let us make Mudkip go first even if the foe is faster. Then we go into the Gym and battle Youngster Josh, so that we can level up and learn Water Gun.
Four Torrent boosted Water Guns later and we've beaten Roxanne and taken our first badge from under her Nosepass! We head out and chase after the Devon clerk from earlier, who tells us the Aqua Grunt stole his Devon Goods. We head onto Route 116 in pursuit. We dodge a few spinners, defeat a Hiker, and get to Rusturf Tunnel where Mr. Briney tells us the Grunt has stolen his beloved Peeko. We confront the Grunt for him and reunite Briney and his pet. We head back to Rustboro but on the way, we catch an Abra for Teleport and to use for Pomeg glitching later.
After a very long conversation with Mr. Stone, we get the Pokénav and two more delivery quests. We teleport back to Petalburg to try and avoid Brendan...but he shows up anyway at Briney's cottage! Deciding he's not worth battling, we ignore him and ask Mr. Briney to take us to Dewford.
Our boat is somehow briefly stopped in its tracks by a call on the Pokenav from dad, but we make it to Dewford eventually. Steven really likes rocks and so we find him deep inside Granite Cave to deliver Mr. Stone's Letter. Using the Escape Rope actually loses time here, so we head right out and enter Brawly's gym. Brawly is a tricky fight because of how easily Makuhita can KO us, but with Torrent-boosted Water Gun we acquire the Knuckle Badge and evolve our Mudkip! We then cruise onwards to Slateport.
Not much happens here of note except our final heal of the run from Capt. Stern. From here on every move we use counts, because we need to have enough Water Gun PP all the way through our fifth gym badge.
North on Route 110 are two annoying fights. Plusle and Minun love to use Quick Attack, which outspeeds Marshtomp even with Quick Claw and wastes time, so we manipulate the AI's move choice to get past both PokéFans.
We then run into Brendan again. This is one of the hardest fights in the game and is infamous in speedruns. To KO Grovyle we either need two max damage critical Tackles (a 1/256 chance for each), or two critical Mud Shots (Mud Shot loses time because it prints more text). We manage to get one of each, and also manipulate Grovyle's Absorb damage so that we can have enough health for later.
We get Rock Smash so we can smash rocks and the Mach Bike so we can go fast. Wally, his Uncle, and our stalker Scott all stall us, but we eventually get into the Gym. Does Wally's Uncle even have a name?..anyway, this gym goes by fast with Mud Shot for damage and the Quick Claw to outspeed all of Wattson's pokémon.
Next, we head north to Route 111 & 113, though we're interrupted by a call from Wally. We go southwest to Meteor Falls, picking up a Protein on the way, for the most pointless cutscene ever—both team Magma and Aqua are up to no good. We KO a Solrock for Attack EVs and pick up some items before backtracking all the way back to Mt. Chimney.
We battle our way up the mountain and breeze through Maxie's monologue. We Tackle Mightyena to start, making sure its Bite leaves us with 22 HP at level 25. A few well-timed Water Guns later and we're ready to head back down the mountain to fight Flannery. That's also the last we'll be seeing of either villainous team this run. Since all of Flannery's pokémon are Fire types our only real challenge is getting the critical hit on Torkoal. Finally, we teleport to Petalburg for the closest thing to a final boss fight in this run.
Petalburg City Part 2
We're finally ready to fight Dad. The Gym trainers we fight are chosen to limit the EV gain on Marshtomp so that we don't go over the amount we need. We use our Super Potion to heal Marshtomp almost to full to prepare for the most difficult fight in the run. Even at +2 boosts from the X Sp. Attacks, we still need critical hits to defeat all of Norman's pokémon. Remember all that talk about managing health? If we have more than 28 HP when we get to Slaking, it will always use Facade, which always KOs us. If we have less than about 28, its weaker Faint Attack will KO us. With exactly 28 HP, we can manipulate Feint Attack to do 27 damage and let us survive, avoid activating Slaking's Sitrus Berry and KO it on the second turn. We claim our 5th badge and victory over Dad, talk to "Uncle" to get Surf, and head out to completely ignore the rest of the game's story.
Here is where the fun really begins. We make the long trek back to Mauville and Route 119, catching a Poochyena on the way. We also detour down to Slateport's market to pick up two HP Ups, one for Abra and one for Marshtomp. Ideally, we would do this detour earlier, right before leaving Slateport for the first time, but we don't have enough money until after fighting the PokéFans, so its faster to do it now. We're then stopped by our first and only Double Battle. The events of this battle are extremely important. In it we KO Poochyena, bring Abra down to 1 health, and set our last used party slot to 3 (by sending out Marshtomp in Poochyena's place). We head east to chat with Steven and do some furious running near the blonde spinner to set up an encounter later.
Finally we get what we came for—a Pomeg Berry! We also pick up a Kelpsy Berry to finalize Marshtomp's EVs at 21 HP, 6 Attack, before teleporting back to Petalburg for the final time.
Marshtomp needs to be placed in Box 2 slot 24 and we begin writing our payload in Box 1.
Using the Pomeg Berry on Abra knocks it out, leaving us with a totally KOed party. When we enter a battle on a precise frame, the memory layout is such so that we can corrupt Marshtomp's PID, swapping its EV and species data and turning it into species 0x0615. The game gets confused and thinks we have zero pokémon, so it just sends out the pokémon in the 3rd slot, the last slot we used which is now empty. Viewing Poochyena's summary refreshes the party count and lets us select more than 6 pokémon, and we scroll up once to corrupt the first possible address and Marshtomp's PID.
Returning to the PC, we finish our box name payload and withdraw our glitched Egg. The box names are ARM assembly code that will allow us to input even more code using the buttons, one byte per frame. Unfortunately for this Egg to hatch, we need to complete the next Egg cycle, which rolls over every 255 steps meaning we have to do some biking.
When the Egg hatches, a lot happens very quickly. As soon as the glitch sprite is on screen, the animation starts and begins running the code in the Box names. This code lets us write bytes based on the buttons that are pressed, and by pressing L&R we break the input loop and run whatever we input. We're free to input any game-ending payload here, but there are good and bad options for quickly beating the game.
Timing stops at the final input after which completing the game is inevitable.
Teleporting to the Hall of Fame map is doable, and triggers full game completion. However I'd still have to press A on the text boxes and the Hall of Fame screen itself, which adds additional time.
Calling the Hall of Fame sequence itself works too. Doing that requires clearing the memory used by onscreen sprites, or the sequence will crash, but it's not a huge problem. However this doesn't set all game completion flags, it just put our save location in Littleroot. And I'd still have to press A on the "Congratulations" to trigger the end credits.
We could also call the credits directly, but this completes exactly none of the game, it just rolls the credits.
In the end I settled for something hackier than all 3 solutions. Instead of letting code execution return to the main loop of the game, I wrote my own main loop, that mimics the normal one but treats A as being pressed regardless of actual input. After that, all it takes is a hacky teleport into the map, and a return to this main loop to take away the controls. The final input is the final byte of code—everything after basically happens on autoplay. When the game resets after the credits, the custom code in RAM will be wiped, but the game is still completely beaten, and faster than ever before!
All of this applies only to the movie I requested be used for encoding.
Towards the end of the development of this TAS I felt that the ending needed some more flair. To me ACE is a lot more interesting if you do something with it beyond just a credits warp. Since no GBA emulator supports subframe inputs yet, I wasn't able to do anything graphically advanced like Mr. Wint's famous Pokémon Yellow TAS, since I can only input one byte per frame. With that aside though, there are still a lot of cool things we can do!
Emerald has a section of save data commonly called the "ram script", about 1 kilobyte in size. This script was, I believe, occasionally used by event distributions for the games. It enables a custom script, complete with text and other events, to be placed into save data semi-permanently, to be activated by talking to any specific NPC.
So with total control of the game, why not put something there as basically an Easter egg?
I thought it would be fun if I put myself into the game, complete with customized text, maybe even a custom battle!
It turns out that writing data into the ram script is pretty easy. There's a checksum needed, but we can just call the game's function to calculate it.
One problem, though, is that since the script is in save data, it is randomly shifted in memory just like PC data. This would make embedding assembly code into the script and calling it difficult, if there weren't a way around it. Since save data can only be shifted by at most 128 bytes, all we need is a short stub at the start of the script to call our code, 128 bytes of zeroes, followed by the code we wanted to call. Then we have the stub jumped to a fix memory location that will either be our code, or a bunch of zeroes that do nothing until we eventually run into our code.
Ok, so we can embed code in save data! What can we use it for?
Well, firstly, we can use that code to copy the rest of the script to a fixed, unused memory location. This makes assembling the actual script easier since it knows its at a fixed location and the assembler can figure out addresses of things we want to reference, like blocks of text.
Running embedded code is also needed to trigger the custom battle. Emerald wasn't designed to allow script-triggered battles with data in RAM. There are script commands for starting battles, but they only allow us to use data from the ROM which we can't modify. To start a battle with a custom trainer and pokémon, we have to hackily call a few functions, but it only takes a hundred assembly instructions or so.
With all that figured out, I had a way to put myself, text, pokémon, and all, into the game, complete with a rare reward for winning the battle.
Now for the battle itself.
Battles in Emerald are very dependent on data being set at the right times. I had to input very little additional code to create the effects shown. I modified the input payload to let me write code to any address, or run code at any address, and I added some functions to call on demand to print text to the screen and change the RNG. Everything you see is the result of key variables being altered at precise times--strings are written into memory just before I print them, damage is modified right before its applied, move targets are changed, and an entire valid pokémon is written into RAM (The TAS Porygon2) just before I send it out. I think it's a fun demonstration of how deep knowledge of a game's inner workings can lead to things that would never be possible in normal play.
- FractalFusion, for suggestions on the forums and overall game knowledge
- Pidgey from PRET, for helping with disassembling the JP ROM
- Everyone else from pret
- GoddessMaria, for her Emerald TAS that helped me learn
- Metarkai, for his documentation of the Pomeg glitch
- endrift, for mGBA and fixing *two* bugs I found over the making of this TAS
- Everyone in the Pokémon RTA Discord for their routing and spinner docs, and for letting me pester them with ACE strats
- It's possible that there is a better seed with a different Mudkip that could be faster. The only way to really tell
would be to write a bot to try them all
GoddessMaria: Hello, merrp, and welcome to TASVideos. Excellent work on improving the published submission. The thorough research and deep work into the game's inner workings definitely shows without sacrificing speed and showed that a previously written off method for this branch was indeed optimal. Audience response was also positive, too. Well done!
Accepting as an improvement to the previous movie.
Spikestuff: ♫ Gotta corrupt them all! Pokémon! ♫
feos: The author requested (on Discord) that this submission is set to Delayed while a new improvement is being implemented.
feos: Reset to new.
ThunderAxe31: File replaced with a 02:36.69 improvement.
ThunderAxe31: Usually, I would have asked to make a new submission for such a large improvement, but in this case the movie contents appeared visually similar to the initial movie, so audience response is still relevant; also, there is no need keep the initial file for a rejection precedent either.
This movie aims to beat the game as fast as possible. For this purpose, the author developed a new strategy for making use of the Pomeg glitch, in order to execute arbitrary code that instantly triggers the game ending. The currently published movie for fastest completion is labelled "Pomeg glitch", while this submission is labelled "game end glitch", even though they both revolve around the usage of said glitch. The reason is because we prefer to use broader definitions when available, and in this case the submission manages to fall within the category of movies that reach the ending instantly via a glitch, regardless of if that glitch is making use of arbitrary code execution or not.
This movie is very optimized, as demonstrated by the extensive documentation of its development.
While there have not been posted a lot of thoughts about the entertainment feeling of the audience, I must note that this movie contains the kind of RPG TASing that people tend to like, with all the careful route planning and the unexpected plot twists. I also have to note that the submission accumulated 20 Yes votes and nothing else, which is uncommon.
With that said, accepting for Moons this movie and obsoleting the published "Pomeg glitch" movie.
As a note: merrp doesn't have updated post input so the screenshot suggestions won't be used.
As a note: merrp doesn't have updated post input so the screenshot suggestions won't be used.