With ca65, you have the notion of modules and scope which help a lot for managing access to symbols.
I don't go as far as to separate all function in it's own file but usually I separate by their responsibilities. If I have something related to the view, it will go in the ViewManager.asm, for sound, SoundManager.asm etc. If one module contains a sub responsibility but share some of the variables, I will not create a new module but create a different file called ViewManager.metasprite.inc and include it. This avoid exporting variables just for that specific part and make the main file smaller.
For ZP variable usually I use zp in front of them but nothing for normal ones. I try to give command for label like Tokumaru but in the past I may have not followed that rule well so I will have to clean up the code someday. Inside a module, my function are always preceded with sub so if I see a function call with sub, I now it was a call from that module. Then when a module is exported, I create a scope inside the H file. So when I need to use the init method from the view, I don't need to call it subViewManagerInit , which would "pollute" the namespace inside the VienManager module but only do so when I export it. So inside ViewManager, you call subInit but outside it , I create a scope so I can call it this way: ViewManager::Init.
To do this, ca65 allow you to export name under a different one. For example, inside the view manager, you export the method this way:
Code:
.export __subViewManagerInit := subInit
Then inside my header file (ViewManager.h) I will define my scope this way:
Code:
.import __subViewManagerInit
.scope ViewManager
Init = __subViewManagerInit
.endscope
Now I can call it like an object. Usually I will put some inner scope for variable too.
I use struct to define the location of item in memory to avoid using magic numbers for position. If the position of an item change, only the struct is affected, not the code.
Another thing I started recently is to rename my temp variable in the .proc scope to make the code easier to read. Usually what you use the temp variables is either for paramters or local temp variable but if your variable are called Param1, param2, param3, temp8bit etc, you lose the meaning of the usage of that temp variable compared to higher level language. Since I decided to give up for now my stack based parameter for my current project, I had to make a new naming convention. This is how I ended up doing it:
Code:
.proc subPutEntityInOam
;---------------- Parameters definitions ----------------
.scope Param
entityPosX = zpParam1 ; X coordinate
entityPosY = zpParam2 ; Y coordinate
entityDir = zpParam3 ; Which direction entity is facing
entityAdr = zpParam4 ; Adress of data, uses zpParam5 too
.endscope
.scope Local
centerSprite = zpTemp8Bit ; Use 1 temp8Bit for center or sprite retrival
entityMetaSpriteAdr = zpTemp16Bit
.endscope
;---------------------------------------------------------
So if I want to use a parameter, I will do Param::entityPosX. It will be quite clear in the code what is the value inside. Same thing for the local variable Local::entityDir. If someday I have some code that could conflict by using the same temp variable, instead to have to code all the code, I only have to scan the definition at the top.
And when it times to set the parameter, I will do this:
Code:
lda #$00
sta subPutEntityInOam::Param::entityPosX
The code document itself. I want to set the paramter entityPosX for the subPutEntityInOam function. It does make names longer but once the code is working, hwo many time will you change this? And how easier will it be to debug it in 6 month? That's the advantage, for maintenance.
I may have other things but this is what comes to mind when I code with ca65. My way of doing things changed a lot in 1 year. I always try new things when I have time to make my code simpler to maintain, the thing many people tends to forget not only for hobby but in the professional world too.
Edit:
About source control, the subject of this thread ( ^^;; ), I don't use it for now. I usually make a backup of the complete project for a specific day before doing some edit to it.