124
edits
Changes
RNG write-up
*Stage 14-2
=== Enemy Patterns RNG ======= In Summary ====A lot of Some enemy patterns are only a function of how many frames have elapsed since the start of the screen and Simon's current position on screen. This allows for pattern manipulation on enemies such as the Bat Boss, Birds, and the Mummies.White Skeletons are also affected by RNG Other enemies patterns instead, on top of Simon's current position on screen, depend on RNG.<br />The RNG algorithm is a factor of the previous RNG value, as well as how many frames have elapsed since the start of the screen. On certain frames, the factors mentioned aboveRNG value can be very predictable. NotablyThis allows for a smaller extent of manipulation, they have for example on white skeletons, by simply losing a certain amount of frames before ancountering said enemies. This can force them into a limited set amount of patterns (chosen at random, or sometimes even a single possible pattern. ==== The Technical Version ====In Castlevania, whenever the code is finished doing everything it needed to do for the current frame, it enters an idle loop while waiting for the NMI interrupt to occur, signaling the start of the next frame. During this idle loop, the RNG value gets advanced over and over. Here's the code of the idle loop (taken from [https://github.com/josephstevenspgh/Castlevania-Labelled-Disassembly this public disassembly]): <nowiki>Legend: CurrentRandomBonusId = $6F FrameCounter = $1A BonusTable = $C03F MainLoop $C030 A5 6F: lda CurrentRandomBonusId $C032 05 1A: ora FrameCounter $C034 29 0F: and #$0F $C036 A8: tay $C037 B9 3F C0: lda BonusTable,y $C03A 85 6F: sta CurrentRandomBonusId $C03C 4C 30 C0: jmp MainLoop BonusTable $C03F .byte $33,$BB,$3F,$80,$2E,$A9,$61,$87,$AD,$C3,$B2,$C8,$7C,$25,$48,$7A</nowiki> On one hand, the fact that the RNG algorithm is placed in the idle loop can make it very hard to manipulate its value, because the length of this loop will be affected by how many things the game has already processed on that frames, where in the loop the NMI interrupt happened on the previous frame (since it will resume exactly where it left off on the next frame), as well as CPU/PPU sync (which is deterministic on most emulators but random on a real console).<br />On the other hand, this RNG algorithm is extremely prone to getting stuck on either a single value, or a very limited set of values. In other words, the idle loop will pretty much always loop over a limited set of value. There are even values from the BonusTable array that are never going to get picked.<br />On top of that, the RNG value will always reset every 16 frames (to value 0x7A). This gives the value that the RNG will assume a degree of predictability. Assuming the loop runs for at least a few interations (which it pretty much always does, outside of laggy areas), here is a list of all the possible value that the RNG can contain on any of the 16 values of the room's frame counter: <nowiki>Legend: The value on the left represents the value of the current room's frame counter, modulo 16 (since that's what the RNG algorithm uses) depending , as well as the conditions that have to be met for the values stated on those two factorsthe right to potentially occur (which is essentially a specific value from the previous frame). The exact pattern gets chosen value(s) on the right represent the set of possible values that the RNG could contain at randomthe end of the idle loop, on the specific frame and conditions specified. This allows * = Regardless of previous value if 0xXX = If the value from the previous frame was 0xXX 0x0: 0x7A, 0x3F, 0xB2 0x1, *: 0xC8, 0xC3, 0x80, 0xBB 0x2, *: 0xB2, 0x3F, 0x7A 0x3, if 0xB2: 0x80 0x3, if 0x3F: 0xC8 0x3, if 0x7A: 0xC8 0x4, *: 0x7C 0x5, *: 0x25, 0xA9 0x6, if 0x25: 0x87 0x6, if 0xA9: 0x48 0x7, if 0x87: 0x87 0x7, if 0x48: 0x7A 0x8, *: 0xB2 0x9, *: 0xC8, 0xC3 0xA, *: 0xB2 0xB, *: 0xC8 0xC, *: 0x7C 0xD, *: 0x25 0xE, *: 0x48 0xF, *: 0x7A</nowiki> These values will then be read on demand by an enemy, which will determine their pattern (interpreted in a unique way for every enemy). Note that this RNG read will not additionally advance the RNG.<br />For a smaller extent practical example, with the standard strat of manipulationentering Dracula's room without losing any frames, Dracula's pattern will be determined with the frame counter reading 0xC7.<br />On this frame, the possible values are either 0x87 or 0x7A. If it reads 0x87, this will make Dracula do the fast fireball pattern, while if it reads 0x7A, this will make Dracula do the slow fireball pattern. This essentially makes either pattern a 50% chance that is impossible to control in an RTA setting.
=== Additional Links ===
*[http://tasvideos.org/GameResources/NES/Castlevania.html TASVideos tricks page]