The interval between sprites on the same scanline is 3 cpu cycles. That's a single 6502 instruction, the write to that register. How do you do any kind of load or compare instruction along with that to decide whether to display that sprite?
The answer was to copy that stream of instructions to RAM ahead of time, and replace each write to a missing invader with a no-op. The code is here if anyone wants to see (the "inv3" demo): http://dos486.com/atari/
Even this is easier said than done: there are only 128 bytes of RAM in the entire machine, and that has to suffice for global variables and stack memory in addition to storing modified code like this!
Transfer Alternate Increment (TAI), Transfer Increment Alternate (TIA), Transfer Decrement Decrement (TDD), Transfer Increment Increment (TII) - pretty much x86 'rep movsb', except not great at 6 cycles per byte (~160KB/s). For contrast 5 years older 80286 already did 'rep movsw' at 2 cycles per byte. 6 years later Pentium did 'rep movsd' at 4 bytes per cycle. Nowadays Cannonlake can do 'rep movsb' full cachelines at a time at full cache/memory controller speed.
It would be fun to reconfigure one as a high speed 6502.
There were programmers in other divisions making royalties off of their games. Tod Frye famously got $700K or so for his terrible version of 2600 Pac-Man (it was terrible not because he was a bad programmer, but because marketing decided that 2K of ROM had to be enough, and he was smart enough to pull off a miracle . . . of sorts).
Also, the OP apparently doesn't know how to unroll loops, which is the first thing you do to your game's hot spots. (Never had to resort to self-modifying code).