# .font: font.text_2
2023-08-09 15:31 dustin  
# .font: font.text_1
the sixth cave about the ΘΘΘ amoeba already, and it has still new surprises for Κ!  it turns out that a certain milling sound is quite annoying for the growing animal that it immediately... well, just try it out for yourself :d  
  
ideas behind this cave:  
| show how the ΛΛΛ stops the ΘΘΘ

# .font: font.text_2
2023-08-09 23:11 DarkStoorM  
# .font: font.text_1
Woah, it's been 35 caves already! :D

# .font: font.text_2
2023-08-09 23:52 dustin  
# .font: font.text_1
yeah, and there're still things to explore for newcomer-Κ! :d

# .font: font.text_2
2023-08-10 20:53 dustin  
# .font: font.text_1
perhaps this is the right cave to explain why the ΛΛΛ can sometimes stop the ΘΘΘ but sometimes not. in fact, the whole ΛΛΛ-stops-ΘΘΘ-rule was never an intended feature at all!  
  
| the story starts with the very first bd1 game. the engine used for this game had a bug concerning the ΛΛΛ: every time a Β was thrown through the ΛΛΛ, the cavescan restarted. this had several unintended effects:  
  
1. choppy movements when the ΛΛΛ converts ΒΒΒ. this is something every bd1 player has experienced, especially in cave o where the ΛΛΛ converts a lot of ΒΒΒ in short time.  
(btw if you want to play a bit with the bug, try it out in cave o: during conversion, Κ is slower than normal in the lower half of the cave, and quicker than usual in the top half of the cave! reason: the lower half, below the ΛΛΛ, is scanned too rarely because the cavescan always restarts when a Β falls through the ΛΛΛ.) :d  
  
2. a few ΒΒΒ can get lost during conversion if the ΛΛΛ converts many ΒΒΒ in short time. (this was exploited, for example, in don pedro's bd5, cave i - if Κ converts the ΒΒΒ too quickly, he won't get all the ΑΑΑ!) (reason: this is a direct result from 1. above. the newly converted ΑΑΑ below the ΛΛΛ are scanned too rarely, so they can't fall down quickly enough to make space for the next ΒΒΒ to be converted!)  
  
3. the third effect is the one we're talking about: if there's an Θ in the cave, and if all parts of the Θ are below the ΛΛΛ, then the Θ will convert into ΑΑΑ as soon as the ΛΛΛ is activated! (this is because the cavescan restarts before the ΘΘΘ was scanned, so the ΘΘΘ had no chance to grow, and the engine thinks it's trapped!)  
  
| while the bug was fixed for the bd2 engine, bd3 was again made with the old buggy bd1 engine, and the developpers exploited the ΛΛΛ-ΘΘΘ-bug in intermission 1 and cave o. in both caves, Κ has to convert an ΘΘΘ by activating a ΛΛΛ. so this was the startpoint of the "ΛΛΛ stops ΘΘΘ" rule! don pedro and other bd1 engine hackers also made caves around this bug/ funny feature/ whatever :d  
  
| tbh i'm not certain how this feature was handled in the official construction kit (plck) and its descendants (1stb, clck engines), but in gdash and here at this site, "magic wall stops amoeba" is an option which the cave designer can choose to switch on or off for each cave seperately. that's why here at this site, in some caves it works, in others it doesn't. so, if you have ΘΘΘ and ΛΛΛ in the same cave, just try it out - activate the ΛΛΛ and expect the unexpected! :d

# .font: font.text_2
2023-08-10 21:14 DarkStoorM  
# .font: font.text_1
Oh! So now I understand why - although I don't know if it's the same in the original source code, I read in one specification document there is a variable for "at least one amoeba could grow this frame", which handles the "trapped" state for amoeba. So, if the scan gets interrupted before ΘΘΘ gets scanned, this counter is 0 and ΘΘΘ figures as trapped, so on the next frame ΘΘΘ converts :D  
  
I was curious what this "magic wall bug" was all the time!

# .font: font.text_2
2023-08-11 10:20 nesdori  
# .font: font.text_1
 darkstoorm , that same variable is indeed used in the c64 bd code and that's why the amoeba gets converted :)  
  
but why this bug occurs?  
  
c64 assembly has two kind of unconditional jumps, JMP is direct jump and JSR is a subroutine call. JSR stores the current program counter onto the stack and then jumps to the specified address and there should be RTS instruction at the end of subroutine which pulls the program counter back from the stack ja then returns to that address, continuing execution from the point where the JSR was executed.  
  
playing different sounds are subroutines in bd1. they should therefore be called with JSR. however, at then end of "| falls through a magic wall" -handling routine there's a JMP instead of JSR to play "falling \" sound. now there's a wrong return address on the stack and when RTS is executed, the address which is pulled is actually a return address of the entire scanning routine and is supposed to be pulled and returned into when the scanning is over. now the execution is returned there after playing the sound which causes the scanning to end abruptly.  
  
so basically this bug occurs because JMP is used to play the sound instead of JSR.  
  
but there's more to this bug than this. even if the JMP is replaced with JSR the | handler would fail. then there would be no JMP to finish the "| through magic wall" handler and code execution would fall through to next routine where it's checked if there's a rounded object below the | so the | would fall left/right. the handler would determine that the magic wall is not rounded and put a stationary | back on top of it. so now there would be both a falling \ under the mw and a stationary | on top of it. but at least scanning would be fully completed in this case and the coders would have spotted that there's something wrong with the code :)  
  
so i think that the coder thought of not jumping into sounds playing routine but into some other routine which would end handling the current object and continue with the next object. this is what "\ through mw" actually correctly does. the handler is a little bit different there; the sound is played with JSR and then there's JMP to clear the current obj and proceed scanning with the next obj. for some reason, | handler is different: the clearing is done with separate routine and then there's no JMP to finish the routine. The finishing JMP is a wrong jump to the sound playing routine. maybe the handlers were done by different coders or the | handler was later changed for some reason with devastating results :)

# .font: font.text_2
2023-08-11 11:33 nesdori  
# .font: font.text_1
actually, now i have an educated guess what's the full story with this bug:  
  
there's another visual bug with "\ through mw" in bd1 engine where \ is correctly removed from the logic buffer but the screen buffer is updated incorrectly and the space which is supposed to remove the \ is drawn on the wrong coordinates. therefore there's "ghost \" on the top of mw on the screen which isn't really there when the the cave is scanned and ^ can't just run over it but not get an additional \.  
  
they fixed this visual bug in "| through mw" by doing separate clearing routine but at the same time introduced a new fatal one. the new routine overwrote some old code and they just forgot about adding a new jsr call to the "falling \" sound routine. they thought that the sound playing address left from the old code is actually the finishing routine and therefore jumped there. that would explain why the bug is there :)

# .font: font.text_2
2023-08-11 15:22 altermaven  
# .font: font.text_1
"magic wall stops amoeba" was not present in BDCK.

# .font: font.text_2
2023-08-11 21:50 dustin  
# .font: font.text_1
thx 4 the info  altermaven ! :)  
  
 nesdori , while i read your comments, i had a familiar feeling because i often feel it when i read texts from programming experts: on the one hand, i (think i) understand enough to be interested and think this is probably very cool, on the other hand i don't understand enough to feel confident to write an answer :d

# .font: font.text_2
2023-08-12 14:45 DarkStoorM  
# .font: font.text_1
Things like this really make you think if that was "a happy little accident" or an intended feature :D   
Glad to know what the actual story may be!