Okay, so my (backward-incompatible) idea for a dynamic sprite system:
Instead of getting an upload slot every frame, and uploading stuff once you get your slot, you get a slot as part of your init routine and keep it until your sprite dies ("until your sprite dies" has some complexity I will explain later, but ignore it for now)
Then, instead of uploading stuff for your sprite every frame, you wait until you have something to upload and then put a pointer in your slot. When V-blank rolls around, it gets uploaded, and that pointer gets cleared.
Since you keep your slot, this means you can keep using the same old OAM tiles until next time your graphics change. For some sprites that might be every frame, for some it might be every 4 or 8 frames, for some even less. (For an example, imagine something like a dynamic version of Chargin' Chuck, that would only need to upload when its pose changes). In comparison to dynamic Z's 30fps mode, this is sort of like letting every sprite choose its own framerate.
Hopefully the reduction in upload frequency would be enough to make ditching the buffer work without black bars.
As for "until your sprite dies", it would have something like a shared subroutine %GetDynamicSlot() (or whatever). The patch would have two tables, one for the slot pointers, and one for the slot owners. When you get a slot, it puts sprite index ($15e9) + 1 in the list of owners. Every frame, the patch loops over the list of slot owners, and if one of them died ($14c8,x = 0) it clears the allocation.
Here is a rough sketch of how the code might go. (there's stuff to deal with like maybe the tables would have to be in bank $7f that im not thinking about here)
Code
NMIstuff:
ldy #!max_slots-1
.loop:
; check if anybody has a claim
ldx !dynamic_owners,y : beq .next
; if somebody has claim, check if they're alive
dex
lda !14C8,x : beq .free_slot
; if they have a claim and are alive, check if they uploaded anything
sty $00 : tya : asl : adc $00 : tax
lda !dynamic_pointers,x : ora !dynamic_pointers+1,x : ora !dynamic_pointers+2,x
beq .next
; imagine there's upload code here (it would upload to a target based on Y)
stz !dynamic_pointers,x : stz !dynamic_pointers+1,x : stz !dynamic_pointers+2,x
bra .next
.free_slot:
stz !dynamic_owners,y
.next:
dey : bpl .loop
rtl
Code
;GetDynamicSlot.asm
; this routine returns either carry clear (no slots available),
; or carry set and slot index in A
; keep the slot index in a table so you can translate it to an OAM index someday
ldy #!max_slots-1
.loop:
lda !dynamic_slots,y : beq .found
dey : bpl .loop
.didnt_find:
clc
rtl
.found:
txa : inc : sta !dynamic_owners,y
tya
sec
rtl
The basic idea here is to save V-blank time by uploading a lot less, the slot reservation system is just a way to achieve that. If nobody likes this idea I still would very much like to reduce the upload frequency by whatever other means are available
The biggest issue with this is that it seems like most of the dynamic sprites on the site are designed in a way that they would change their graphics very often (look at me I'm a Yoshi's Island piranha plant and I rotate all the time!), in which case they would be uploading almost every frame anyway and ditching the buffer would still risk black bars.
Another issue is that if a slot-owning sprite dies and a new sprite spawns in it slot on the exact same frame, the slot will be considered owned by the new sprite and won't be cleared until the new sprite dies. There are ways to make it leak less often (although I can't think of a 100% way), but I'm not sure this is a huge problem.
I think you could make this use a buffer as well but it might be really weird and involve lots of uploads for things that didn't change in which case the whole point is defeated
This idea should be compatible with other proposed ideas (changing the size of slots, making it possible to choose where the slots are)
I don't really have super high hopes for this proposition, since it requires a rewrite for sprites, that rewrite has to be well-thought-out for the benefits to appear, and also for a lot of sprites this might not even be beneficial since they change graphics all the time anyway.
but i asked lx5 whether i should post my weird heterodox idea and he said "post" so if you dont like it blame him but i dont mind if it gets ignored really since im already using not using dsx