Originally posted by eddyhazardI've been trying to use chatGPT to write some logic that wont allow mario to touch enemies and using asar to compile it, but It's been very challenging to find the correct collision stuff without crashing the game.
Yeah, even if by some miracle you get Asar to compile whatever ChatGPT hallucinates, this won't work. To use GPT (or any other LLM for that matter) to generate code for such a niche usecase will not work well, what with not being enough material to train to begin with.
Now then, for where you could begin looking. This is complicated by the fact different sprites can use different, specific interaction routines. In the simplest case, we have the sprites which use "default interaction", such as Koopas or Piranha Plants, which share an interaction routine which begins at ROM location $01A83B. Skipping below the routine for when Mario has a star or is interacting with a carryable sprite, we have this code block.
CodeCODE_01A897: A9 14 LDA.B #$14
CODE_01A899: 85 01 STA $01
CODE_01A89B: A5 05 LDA $05
CODE_01A89D: 38 SEC
CODE_01A89E: E5 01 SBC $01
CODE_01A8A0: 26 00 ROL $00
CODE_01A8A2: C5 D3 CMP $D3
CODE_01A8A4: 08 PHP
CODE_01A8A5: 46 00 LSR $00
CODE_01A8A7: A5 0B LDA $0B
CODE_01A8A9: E9 00 SBC.B #$00
CODE_01A8AB: 28 PLP
CODE_01A8AC: E5 D4 SBC $D4
CODE_01A8AE: 30 36 BMI CODE_01A8E6
What this does in simple terms is see whether Mario touched the top or the bottom of a sprite. That last line branches is Mario is touching the bottom, where the code does some extra checks to see whether to hurt Mario. We could change this branch to always jump no matter where Mario is contacting the sprites:
If we now check $01A8E6, we see another branch.
CodeCODE_01A8E6: AD ED 13 LDA.W $13ED
CODE_01A8E9: F0 0E BEQ CODE_01A8F9
This makes sure Mario isn't sliding and branches if he isn't. If you want Mario to also get hurt with sliding on an enemy, you would change this to always branch as well.
Finally, this last block.
CodeCODE_01A8F9: AD 97 14 LDA.W $1497 ; \ Return if Mario is invincible
CODE_01A8FC: D0 1D BNE Return01A91B ; /
CODE_01A8FE: AD 7A 18 LDA.W RAM_OnYoshi
CODE_01A901: D0 18 BNE Return01A91B
CODE_01A903: BD 86 16 LDA.W RAM_Tweaker1686,X
CODE_01A906: 29 10 AND.B #$10
CODE_01A908: D0 07 BNE CODE_01A911
CODE_01A90A: 20 30 AD JSR.W SubHorizPos
CODE_01A90D: 98 TYA
CODE_01A90E: 9D 7C 15 STA.W RAM_SpriteDir,X
CODE_01A911: B5 9E LDA RAM_SpriteNum,X
CODE_01A913: C9 53 CMP.B #$53
CODE_01A915: F0 04 BEQ Return01A91B
CODE_01A917: 22 B7 F5 00 JSL.L HurtMario
Return01A91B: 60 RTS ; Return
If you want Mario to outright get killed and don't care about him being on Yoshi and such, you'd change this to only jump to the kill routine and then finish. To do so:
Codeorg $01A8F9
JSL $00F606 ; There was contact. Kill Mario.
RTS ; Stop.
Our patch then would be:
Code; This patch makes sprites with default interaction kill Mario when touched.
org $01A8AE ; always act as if Mario touched below the sprite, to check if kill him.
db $80
org $01A8E9 ; bypass slopes.
db $80
org $01A8F9 ; actually hurt Mario.
JSL $00F606 ; There was contact. Kill Mario.
RTS ; Stop.
Then you'd have to take care of every special sprite which DOESN'T use default interaction, such as Wigglers. This is more tedious and will definitely require more work. If you want to check, I recommend getting a disassembly (such as
all.log or
Thomas' disassembly) and looking for where a custom interaction routine is run. In all.log you can find those as lines which are JSR.W MarioSprInteractRt or JSL.L MarioSprInteract and then followed by a BCC or BCS.