tetsuji
tetsuji copied to clipboard
Errata
As a follow up to #1, there's a few things that are incorrect in the article. Some of these are nitpicks, some of these are more significant, but I felt they all warranted being pointed out somewhere.
Mobile adapter documentation
- The unlimited battle adapter is reflected by the third byte of the 0x17 telephone status command being 0xf0 or higher. This is sampled during the mobile adapter splash screen and stored in the save file from there on (although it's reset when the splash screen detects an adapter once more). Source: Dan docs
- The first byte in a transfer data packet is the socket id. This is useful when opening multiple tcp connections to a server, but in direct call (p2p) connections it's always set to 0xff and ignored by the adapter. Source: Dan docs
- The second byte in the transfer data packet for a p2p connection is a size byte, not a packet id. This is imposed by the mobile adapter library, although I'm not sure why it exists as it's not used by the adapter itself. The best way to identify what packet is what is likely through the sequence id, like you've identified. Source (recent research)
General pokemon game knowledge
- クりス is the default player name for the female character, Kris.
- The random 10-byte packet is likely the RNG seed, as this is necessary for multiplayer battles to function.
Misc
- The
4Fcharacter is the<LINE>character. The reason it's used in the 1500 payload is to set the text writing pointer to a predictable location (the start of the textbox), as this pointer is written to the jump destination, and will be the first two bytes that are executed. - The first self-contained bootstrap on the glitch city page works on JP - I've just tested it, the jump destination is $CD46 - but player and pokemon names are too short to store anything useful, and usually names are first copied to wStringBuffer1 ($D05B) before being executed, so they're truncated. There may be ways to chain multiple strings together by jumping to a different one (like with the
3F/<ENEMY>character, and doing something like "4F 15 08 05 C9 3F" followed by "15 00 <code>" inwOTClassName), but it's a bit complicated in this exploit scenario. (letterbombs by attaching mail to traded mon are very much possible with this) - Across the article Nintendo is attributed for various things in Game Freak's game. The character encoding and the mobile scripts being a few examples.
Lacking research
- I wonder if the limit_crystal packet includes the remaining battle time for the player, as the battle needs to stop before the timer runs out for the player with the least time.
- There's various things that must be transferred during battle which might be amongst the packets you weren't sure about. One are the configurable battle messages through the easy chat system, printed at the start of a battle, and when the opponent wins or loses. Another being the mobile trainer cards, which you won't see unless you've made your own.
There's quite a few things here, so I'll respond one-by-one:
Mobile adapater
- This is fascinating! I'm definitely going to try and this and see. I was pulling my hair out for quite a while trying to figure this out and had no luck, hence why I concluded that it wasn't possible. If people ever want to re-implement the online battle functionality, this would be super important to have.
- Ahh, this makes perfect sense.
- D'oh! Of course the second byte is the packet length - it seems so obvious now!
General pokemon game knowledge
- Oops, I guess it's been a while since I played through Crystal casually!
- I suspected this might be the case, but had nothing to back it up - thanks for confirming!
Misc
- The behaviour of
$4Fmakes perfect sense. I had quite a bit of trouble trying to find technical explanations for a lot of these ACE tricks, so ended up only comprehending the minimum required to get the exploit working - Again, this makes perfect sense. When I was playing around trying to get this to work, I found that if the "shellcode" was too long in the
<code>part, the glitch didn't trigger at all, and the battle would just start with corrupted text. - Oops - this is 100% a mistake on my part. Big oversight - thanks for pointing out.
Lacking research
- This is certainly possible. I was unable to figure out what those first four bytes mean. However, seeing as the player can actually run from these battles ("move"
$FFin the "tetsuji" packets), I wonder if the game doesn't simply "run" when it detects that it has run out of time? I guess it depends on whether the opponent is informed that you ran out of time, or simply ran away? - Oooh, this is another good point. Unfortunately I don't speak Japanese, and muddled my way through most of the menuing using Google Lens. There were quite a few options in the final GIF that didn't translate well and I don't fully understand - so I assumed that the packets I couldn't make sense of were related to that.
A massive thanks again for your comments - I really appreciate you taking the time to write this up. As on #1, are you okay with me updating the relevant parts of the article with some of these comments (crediting you where appropriate)?
I was pulling my hair out for quite a while trying to figure this out and had no luck, hence why I concluded that it wasn't possible. If people ever want to re-implement the online battle functionality, this would be super important to have.
I don't remember exactly how it was documented in dan docs, but I remember it being a pretty painful dive through the pokecrystal code... there's a lot of layers of indirection in there and it's a genuine pain to follow, so it's not an unreasonable conclusion there. Interestingly enough, this value is also checked by the GBA library, so I wonder if any GBA games used it as well (despite not being exposed in the public header).
I had quite a bit of trouble trying to find technical explanations for a lot of these ACE tricks, so ended up only comprehending the minimum required to get the exploit working
Yeah... Unfortunately most people and in particular speedrunners aren't very good at explaining this sort of thing. There's a lot of cobbled-together knowledge that has been accumulated over the years but the deeper you dig, the more you'll find that nobody really bothered to explain things, and the 0x1500 wiki page is no exception.
I wonder if the game doesn't simply "run" when it detects that it has run out of time? I guess it depends on whether the opponent is informed that you ran out of time, or simply ran away?
That would put the player with the least remaining time at a disadvantage, as running is an automatic lose condition. Also the battle interface warns both players of the remaining time during the battle itself, though I'll admit I haven't stared at this hard enough yet to figure out if the remaining time is in sync for both players or whether time running out is a draw rather than a win/lose condition.
are you okay with me updating the relevant parts of the article with some of these comments
Feel free, a lot of this info is cobbled together from various sources including shonumi's dan docs (which you already noted in the blog post) and some people in the REON Discord who are going through all the mobile features trying to re-create them in US crystal.
And no problem, I love seeing people mess around with this sort of thing, though info about niche things like this is often hard to find so I'm glad to be able to help.