It is considered "bad practice" to use r1 for anything else than addresses. The game will never do that, so in only very
exceptional cases should you need to store it and load it back later. The game nearly always reassigns a value to r1 right before using it to load/store a value to/from another register. We don't really know the consequences of using r1 for values rather than addresses, but we avoid doing so in case.
This is a big no. Load opcodes require a delay opcode to allow properly loading the value.
Else what is going to happen? Let's say the value in r2 was 0x0008476A.
lbu r2,0x38f9(r3) <- Starts loading 0x04 from 0x801938F9
andi r2, r2, 0x007F <- performs andi r2, 0x0008476A, 0x007F because the lbu wasn't done loading the value into the register.
This only applies to loading, not storing; so this affects lb/lbu/lh/lhu/lw. This is a console bug, and proper emulators will bug if you do that as well.
Same thing here. lbu r1,0x0025(r3) is in a branch's delay slot, and r1 will not be done loading if the branch returns true.
Worst case scenario, if you don't have anything "useful" to add to a load/branch/jump delay slot, just put a nop
there. Yes this will lengthen your hack, but this is necessary if you want your hack to work on all consoles/emulators.
I'd suggest reading or re-reading the Coding Standards Sticky