[4.5.6] Any Tips on Freeing up More Space in PRG $1F for More Custom Scripts? (Out of range error)

pigeonaut

Member
Hey everyone!

Been trying to free up some space in the PRG $1F so that I can add more custom scripts! I thought I would first share what I have found and then ask you guys what else you recommend.

1. I have been going through this neat guide and shortened some of my own scripts:

2. I have tried this boomerang method: https://www.nesmakers.com/index.php?threads/more-space-for-code-with-bank-boomerangs.4907
And I have tried this bank switching method: https://www.nesmakers.com/index.php?threads/4-5-6-fun-with-bank-switching.6253/

Both are super awesome and I was able to move "stuff" from bank 1C to the empty bank 1D with success! But I was not able to free up space in PRG $1F.

3. Lastly I removed some unneeded scripts out of the scripts/input folder on the bottom left and removed some unneeded ai action scripts. This gave me some more room to add in just a few more extra scripts.

4. This is a very nice explanation of bank switching: https://www.nesmakers.com/index.php?threads/more-space-for-scripts.2172/
5. This is a very nice explanation of banks in general: https://www.nesmakers.com/index.php?threads/the-tower-of-turmoil-cartridge-space.2078/

1605279869353.png
Here is a screenshot of my current memory (I used the nes space checker tool). As you can see, I have a tiny bit left for maybe 1 or 2 more lines of code haha.

I am currently using the metro-vania module and you only start off with about 5% (couple hundred bytes) left in the PRG $1F for your own custom scripts. I started to add in some input scripts from the adventure module and the space filled up very quickly.

Here are my questions:
A. How did games like Megaman and Metroid have so many unique enemy, boss, and weapon types? Wouldn't that have taken a lot of extra scripting?

B. Are all custom scripts, like new ai actions, tile scripts, inputs, all destined to be in $1F as soon as you hit the compile button?

C. Do you guys have any more tips on how we can squeeze out some more memory in $1F for more custom scripts?

Thanks!
 

CutterCross

Active member
A. Commercial NES games don't have to deal with the same amount of bloat NESmaker initially puts on you. There are many routines in NESmaker that are either unnessecary or unoptimized, mostly because it's not designed to do one specific thing. Also taking better advantage of bankswitching helps.

B. No, mostly everything in $1F (that aren't vectors or initialization stuff) is in LoadAllSubroutines.asm. Things like adding more animation frames for objects are automatically stored in $1C for example. You can take a look in there and see if you need any of those routines to be loaded all the time, if at all, and either move them to another bank or get rid of them entirely.

C. If you don't need a routine to always be loaded across bankswitches, don't put it in $1F. Like if you need to do a routine and you aren't already in the middle of a bankswitch, just put it in a different bank. Switch out the bank, JSR to that routine, then ReturnBank once you've returned from the subroutine. MainGameLoop.asm already bankswitches in-and-out bank $18 every frame, so that's prime for dumping extra routines into, for example.
 

pigeonaut

Member
A. Commercial NES games don't have to deal with the same amount of bloat NESmaker initially puts on you. There are many routines in NESmaker that are either unnessecary or unoptimized, mostly because it's not designed to do one specific thing. Also taking better advantage of bankswitching helps.

B. No, mostly everything in $1F (that aren't vectors or initialization stuff) is in LoadAllSubroutines.asm. Things like adding more animation frames for objects are automatically stored in $1C for example. You can take a look in there and see if you need any of those routines to be loaded all the time, if at all, and either move them to another bank or get rid of them entirely.

C. If you don't need a routine to always be loaded across bankswitches, don't put it in $1F. Like if you need to do a routine and you aren't already in the middle of a bankswitch, just put it in a different bank. Switch out the bank, JSR to that routine, then ReturnBank once you've returned from the subroutine. MainGameLoop.asm already bankswitches in-and-out bank $18 every frame, so that's prime for dumping extra routines into, for example.
Thanks so much for the feedback!!! I was able to add some more scripts into my game!!!!! Here is what I did:

So to test this I tried to put a jumpingScript into one of my AI behaviors. That gives me the "out of range" error because my 1F bank is full. I Then did the following:

1. Took everything out of the jumpingScript and put it into another custom script called doJumpingScript.
2. In Nesmaker I went to project settings/script settings. Scrolled down to SubRoutines and added a new script define by pressing 'Add' at the top.
3. Entered the following information in the screenshot:
1605287088530.png
(For the script I put in the path to my "doJumpingScript")

4. Went back to my empty "jumpingScript" and added the following code:

Code:
SwitchBank #$1D ;; I chose 1D because it was completely empty. 18 worked for me too
    JSR doEnemyJump
ReturnBank

5. Went to System/BankData/ and opened Bank1D.asm and added the following:
Code:
doEnemyJump:
    .include SCR_DO_ENEMY_JUMP
RTS


Now my game compiles with no errors!!! But my enemy is not jumping but I believe that is a logical error on my part as I'm quickly testing a script.

Did my bank switching procedure make sense or am I interpreting your feedback wrong and I will run into some issues down the line?
 

Sukotto42

Member
This worked great for me, and got me back to being able to compile again. I have hit one bug with it, though - I tossed my selectable weapon input script into bank 1D, and the input script does the bankswitching there. however, now if I am holding down a direction while attacking and then continue to hold the direction down, it doesn't re-animate the player object, just returns to idle state. I assume this is due to bank switching, but I'm not fully sure how to approach rectifying it.

should I just try to work out putting all my input scripts into 1D, or...?
 

Sukotto42

Member
I just re-read @CutterCross’ mention about how maingameloop switches in and out of Bank $18 every frame, so before I try getting any fancier, I’ll throw it there instead of $1D and see what happens.
 

Sukotto42

Member
I just checked an older build and realized I never noticed this behavior was also happening before bankswitching! Completely unrelated. Which is sort of(?) nice. Bank $18 works great.
 

Sukotto42

Member
It's been a while since I last attempted bankswitching. Just tried a number of things to move HandleInputReads from LoadAllSubroutines into $18 and failed spectacularly every time. It seemed to make more sense to me before as an input script, but trying to switch this to $18 in a similar fashion has so far just crashed my game, even when it compiles. I'm pretty sure I'm either just missing something, or that is a very bad script to switch out to a different bank.
 
Top Bottom