I haven't seen this information gathered in one place before, so I thought I'd kick off this thread to share some of the techniques I've used to save rom space. So with no further adieu, here they are...
- keep same-value variable assignments on the same line when possible.
rem ***** do this... timer=0:level=0:deathflag=0:soundindex=0 rem ***** instead of this... timer=0 level=0 deathflag=0 soundindex=0
Since they're on the same line, bB knows it doesn't need to keep loading the 0 value for each assignment.
The savings is fairly minimal (2 bytes for each variable after the first one) but this is an easy technique to use and the savings can add up quickly!
(NOTE: the current version of bB seems to max out at 12 assignments per line. If you use more than that you may run into compile errors. )
- when using bankswitching, try to reduce the number of bankswitching gosubs and gotos.
A regular gosub takes 3 bytes. A bankswitching gosub takes 24 bytes.
A regular goto takes 3 bytes. A bankswitching goto takes 18 bytes.
You should avoid having small utility routines that are bankswitch-gosub'ed from many places. Either move the utility into the same bank as the calls, or change all the bankswitching gosubs to a local gosub that has a common bankswitching goto routine...
rem ***** do this... if lives=1 then gosub utilityjump health=1 gosub utilityjump goto mainloop utilityjump goto utility bank3 rem ***** instead of this... if lives=1 then gosub utility bank3 health=1 gosub utility bank3 goto mainloop
If there's a bank with a lot of utility functions, you can save rom by using on...goto and a temp variable...
rem ***** use this... if lives=3 then temp1=0:gosub enterbank2 if enemies=0 then temp1=1:gosub enterbank2 if gold=1 then temp1=2:gosub enterbank2 goto mainloop enterbank2 goto dispatcher2 bank2 bank 2 dispatcher2 on temp1 goto routine1 routine2 routine3 routine1 rem do stuff return otherbank routine2 rem do stuff return otherbank routine3 rem do stuff return otherbank rem ***** instead of this... if lives=3 then temp1=0:gosub routine1 bank2 if enemies=0 then temp1=1:gosub routine2 bank2 if gold=1 then temp1=2:gosub routine3 bank2 goto mainloop bank 2 routine1 rem do stuff return otherbank routine2 rem do stuff return otherbank routine3 rem do stuff return otherbank
- In a bank-switched game, if you're sure a return is always going to be within the same bank, use "return thisbank" instead of "return". If the return will always be to another bank, use "return otherbank" instead of "return".
In a bank-switched game...
A "return otherbank" statement takes 3 bytes.
A "return" statement takes 13 bytes.
A "return thisbank" statement takes 1 byte.
- If you have a large amount of data with values less than 16, Use nibbles and hex notation to stick the data together
rem ***** use this... channel=songvolumechannel[i]&15 volume=songvolumechannel[i]/16 data songvolumechannel $86, $48, $84, $86 end rem ***** instead of this... channel=songchannel[i] volume=songvolume[i] data songchannel 6, 8, 4, 6 end data songvolume 8, 4, 8, 8 end
- pick variable locations consecutively so you can operate on many objects using a loop
If you're doing a lot of the same operation to a bunch of variables, often it's better to pick the position of variables carefully and use loops...
rem ***** use this... dim monster1x=g dim monster2x=h dim monster3x=i dim monster4x=j for temp1=0 to 3 if monster1x[temp1]>25 then monster1x[temp1]=1 if monster1x[temp1]<0 then monster1x[temp1]=24 next rem ***** instead of this... if monster1x>25 then monster1x=1 if monster1x<0 then monster1x=24 if monster2x>25 then monster2x=1 if monster2x<0 then monster2x=24 if monster3x>25 then monster3x=1 if monster3x<0 then monster3x=24
I've also been able to squeeze a fair bit of ROM through algorithmic improvement and judicious assembly code rewrites, but those techniques aren't really suited to a simple tips thread. I figured I'd still mention it, so you can keep them in mind.
Please post any techniques you've discovered!