This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Thoughts on doing a platformer...

Thoughts on doing a platformer...
by on (#38191)
This is all still in the thought process, but this is what I was thinking for doing such a game.

I want to have a bunch of rooms that are connected, but no scrolling is involved. If you can exit the edges you are in a new room.

The rooms themselves, I was thinking of having definitions for each one. Some examples would include:
-The obvious one, an array of the 16x16 tiles that make up the room.
-The tiles themselves would have some definitions like what type they are (floor, passable, spike, lemon), what attribute #, and what four 8x8 tiles are needed to draw it.

My thoughts for doing something like this would be like this:
Code:
gameRoomArray:
.dw room_01, room_02, ...

room_01:
.dw SomeTileNameToLoadIntoCHRRAM ;Something here to specify if some new graphic tiles may come into play to draw the room
.dw giveControl  ;Events
.db $01,$01,$02,$03,$02,...  ;The tiles that draw the room

room_02:
.dw SomeTileNameToLoadIntoCHRRAM
.dw bossEntrance  ;Events
.dw giveControl
.db $01,$01,$02,$03,$02,...  ;The tiles that draw the room

tileSetArray:  ;Various areas of the game may have different graphics and thus a different tileset...
.dw tile00Definitions, tile01Definitions, ...

tile00Definitions:
.db $00 ;Passable
.db $00 ;Attribute 0
.db $00,$01,$02,$03 ;The four tiles to draw it.  Top left, top right, bott left, bott right...

tile01Definitions:
.db $01 ;Solid
.db $01 ;Attribute 1
.db $10,$11,$12,$13 ;The four tiles


-Things like events that would occur in the room, if applicable. After drawing the BG, it would check for if it's a special room like a boss room. The boss may have events for its entrance and such. If no event takes place, then control is simply given back to the player.

Anyway, this is my proposed plan. I just wondered if what I'm thinking is reasonable or if there's anything that looks seriously wrong with it.

Thanks.

by on (#38193)
Quote:
I want to have a bunch of rooms that are connected, but no scrolling is involved. If you can exit the edges you are in a new room.

That's exactly how the game I'm developping does it. I have a 4 bytes header that specify the numbers of screen to all four direction, 0 means no screen is connected. This allow non-linear levels as well.

Quote:
-Things like events that would occur in the room, if applicable. After drawing the BG, it would check for if it's a special room like a boss room. The boss may have events for its entrance and such. If no event takes place, then control is simply given back to the player.

I've taken the path to not do any differences for bosses rooms (exept that the player can't go back because no screen is connected), and the boss' AI programm will handle everything needed. This don't mean my path is the correct one tough, as there is no correct or uncorrect path.
Re: Thoughts on doing a platformer...
by on (#38201)
That seems like a reasonable plan.

Anyway, unlike modern processors the 6502 prefers structures-of-arrays rather to arrays-of-structures. For the most part at least.
This means that you'd store those meta-tile definitions (for instance) as separate arrays for the collision type, color attributes, component tiles, etc. Even to the point of splitting up 16-bit fields into separate arrays for the high and low bytes. That way you can index the fields of up to 256 meta-tiles directly without 16-bit pointer arithmetic.

by on (#38202)
Yes, but it's often more annoying to do so than to just shift the index a few times right.

Also I use a byte to say the attributes of a 4x4 block and another to say if the blocks are passable or not (instead of using a whole byte per 2x2 metatiles which seems a waste)

by on (#38203)
Bregalad wrote:
Yes, but it's often more annoying to do so than to just shift the index a few times right.
If the whole structure is smaller than 256-byte bytes then that's often the right choice, especially if you can premultiply the indices. But with something like meta-tiles you'd typically need to set up and deal with zeropage pointers, something that is both slow and inflexible.

I have this cute little tool to interleave structures. But there's no denying it gets annoying at times.
Quote:
Also I use a byte to say the attributes of a 4x4 block and another to say if the blocks are passable or not (instead of using a whole byte per 2x2 metatiles which seems a waste)
And you're worrying about the difficulty of dealing with SoA swizzling. Picking out the right the right two bits out of the array for a specific meta-tile would be beyond messy.
Personally I'd pack those attributes into another status field instead if I was short on space. But then I'd probably find easier ways to squeeze out bytes first, say by compressing the map ;)

by on (#38204)
Yeah, interleaved data is definitely the way to store things, I'd say. Tokumaru once said that it's not a good idea to design things for ease of readability by the programmer, but by the computer, which I completely agree with. Interleaved data allows for the program to read it quickly and easily with using the same amount of data, just in separate arrays. Though it is kind of a headache to read if you need to change something. That's why you have conversion apps, though.

by on (#38206)
Celius is right, I'm definitely one that prefers to work with "structures of arrays"/interleaved data. This is entirely up to you though. Once you start coding the routines, you'll see that the data is a bit harder to handle when you access it through calculated pointers and shifted indexes. And of course, this is slower too.

The only situation I can see someone favoring this design is when they lack supporting applications to convert the data. Since the data has to be written by hand, the person who's doing it will want maximum readability.

Your design seems simple enough, so you might get away with it. Since there is no scrolling, all the heavy metatile access will happen when the player enters a new room, and I don't think anyone will notice a couple of blank frames while the program is rendering it.

by on (#38214)
tokumaru wrote:
I don't think anyone will notice a couple of blank frames while the program is rendering it.


Yeah, I was thinking of having maybe a 6 frame delay or so to get in the appropriate CHR RAM, draw up the BG and write the attributes. I guess I'll see if that's enough for the game. :)

by on (#38226)
I'm not sure how much delay is acceptable when switching screens without annoying the player. 6 frames sounds pretty decent.

by on (#38232)
Keep in mind the NES screen is 256x240, so your room dimensions will actually be 16x15. Assuming uncompressed room data, that's an extra 16 bytes to do whatever with.

by on (#38251)
BMF54123 wrote:
Keep in mind the NES screen is 256x240, so your room dimensions will actually be 16x15.

And a status bar will make it even smaller. Zelda uses 16x11 cells per screen.

by on (#38254)
6 frames definitely sounds fine and unnoticeable. I'll have a similar delay in my game when changing rooms, though each room is a collection of screens.

About screen size, it's good to keep this in mind, but if you're working on a larger room size, it saves you time to not deal with 256x240 screens, but 256x256 screens. In the non scrolling case though, you would want to use the 16 bytes for something else.

Oh, and you'll also have SUCH AN EASIER TIME programming everything if it doesn't involve scrolling, as you can have everything active on one screen and you can keep a copy of the screen in RAM and not have to worry about checking if things aren't on screen, and you can also use 8-bit coordinates to keep track of everything instead of 16-bit. Just thought I'd mention.

by on (#38255)
Well I've never see a programm to split arrays into multiple arrays. I agree it could be good to split arrays if it really increase performance. A 3-byte saving or a 3 clcok cycles per frame saving is probably not worth the trouble, tough.
Also you'd want to find a average solution. Making the programm extremely optimized is good, but then it will be a headache to change whathever after the initial write of the programm, and that's NOT a good thing AT ALL (I'm experiencing it).
Writing unoptimized and soppy code in the only goal to make it 100% structured, flexible and easily modifiable is a bad idea on a console with low CPU power as it could take much too long to perform things.

In fact when I blank the screen or I often add an additional delay because it looks stupid if there is only a few frames of delay. It looks unnatural and I dislike it. It makes the game look like a pirate chineese which is not a good thing. A delay of 0.5 sec to 1 sec is good make the game look professional and fluid. A very long delay would be terrible of course.

Quote:
Oh, and you'll also have SUCH AN EASIER TIME programming everything if it doesn't involve scrolling, as you can have everything active on one screen and you can keep a copy of the screen in RAM and not have to worry about checking if things aren't on screen, and you can also use 8-bit coordinates to keep track of everything instead of 16-bit. Just thought I'd mention.

Yes, tough the 8-bit is a BAD IDEA. I just come from out of 3 weeks of total nighmare converting my whole game engine to use 16-bit coordinates and I had a very hard time doing that (considering the number of times I had routines whenre I pass a coordinate in A and the other in Y or something like that was not possible any longer).
I did that because it makes movement more fluid to works with more bits (I use the middle 8-bits for screen position, lower 4-bits for fine position, and reserve the upper 4 for further scrolling). Also I'll be able to port it to the C64 which use 9-bits for horizontal sprite positionning.
I'll warn anyone : DO NEVER only use 8-bits for coordinates, you're going to regret that. I guess I just had to mention that.

I use maps of 8x6 blocks (a block is 32x32 pixels), but I'll have to change all maps to make them 10x5 if I port the game to the C64 because of different resolution. The only way to keep them 8x6 would be to place the status bar on the right which would look terrible (especially when scrolling).

by on (#38257)
Oh yeah, sorry, I was forgetting precision bits. In my game, I'll also be using 24-bit coords: 8 High (defines which screen it's on), 8 Low (defines pixel it's on) 8 precision. Precision bits are essential in a platformer, because without them, you can only move something at an integer number of pixels a frame. If you use precision bits, you can move like 1.5 pixels a frame, which really makes a huge difference. It's also important for things like gravity and acceleration/deceleration.

But you don't have to use AS MANY bits for coords was really what I meant to say.

by on (#38260)
My advice is to go for 8-bit precision if at all possible. Not having to bother with 16-bit coordinates everywhere makes so many things so much easier that it's not even funny. A fractional fixed-point byte beneath the screen coordinates occasionally comes in handy as well, but there's no need to burden all objects and algorithms with it when only some of them care. Besides, you can often fake sub-pixel movements in other ways. Personally I like to keep a set of "frame counter mod n" variables handy for such things.

Granted, sometimes 8-bits simply isn't enough. With the clipped display being 248 pixels wide already there simply isn't enough wiggle room to smoothly move 16-pixel objects out of screen easily, and that's surely necessary for horizontally scrolling games even if you might get away without it in single-screen designs. Still, even scrolling games rarely need to deal with off-screen pixels. Not by more than a couple of tiles anyway. So instead of introducing a bunch of extra precision on top of the normal eight bits it's often enough to simply add a ninth bit, and keep the former LSB together with the fixed-point fraction in another byte.
That way a single byte is still enough for most tasks, like collision detection or fast-moving bullets, even if it cannot address odd pixels. And putting together a real pixel position for, say, the sprite position is only a matter of a single shift. For a scrolling game the question still remains whether to keep the coordinates screen-relative, or have them be world-relative and let the nine bits wrap. Either way is potentially problematic and the best choice likely depends on the genre and how you interact with the background map.

By the way, if the benefits of a SoA layout is still somewhat unclear then consider how you'd deal with a list of game actors and their properties (assuming that the array is larger than 256 bytes, but that ought to be true for most any game.) How would you access the property fields to write general game logic? How do you move from one actor to the next? What about following a pointer? And what happens if you need to work with two actors simultaneously?

by on (#38264)
Quote:
Well I've never see a programm to split arrays into multiple arrays. I agree it could be good to split arrays if it really increase performance. A 3-byte saving or a 3 clcok cycles per frame saving is probably not worth the trouble, tough.


You'd just write a small console app yourself to do it. Not a big deal.

I wouldn't consider that difficult to read or understand. Interleaving arrays should be the norm. I wouldn't consider it in the "optimizing" phase of coding writing, but more from the start. It's just a natural order and access of data on an 65x.

by on (#38270)
I'm for interleaving data, and I don't see why you wouldn't unless you were using 128 pointers and not 256. Let's see here... Here is some sample code of loading a pointer in an un-interleaved array to a Temp Address.

lda PositionInArray
asl a
sta TempAddL
lda #$00
adc #>PointerList ;If the position in array is more than 128, the carry will be set, thus adding 1.
sta TempAddH
clc
lda TempAddL
adc #<PointerList
sta TempAddL
ldy #0
lda (TempAddL),y
sta TempAdd2L
iny
lda (TempAddL),y
sta TempAdd2H

That's one way you could get a pointer out of the array. Though you could modify it if you force the array to start at a specific location and save time. But to me, that's a big shindig. Why do that when you can do this:

ldx PositionInArray
lda PointerListL.w,x
sta TempAddL
lda PointerListH.w,x
sta TempAddH

That's so much less dinking around! There aren't any INXs or shifting/adding at all. It's simply load and store. I see no reason good enough to do it the other way.

by on (#38272)
To be fair though this particular example can be optimized a bit even with non-interleaved arrays.

With branches (25 cycles):
Code:
   lda index
   asl
   tay
   bcs +

   lda list+$000,y
   ldx list+$001,y
   bcc ++

+  lda list+$100,y
   ldx list+$101,y

++ sta data_ptr+0
   stx data_ptr+1


Or a preinitialized list pointer (32 cycles):
Code:
   lda #<list
   sta list_ptr+0
   .
   .
   .
   lda index
   asl
   tay
   lda #>list
   adc #0
   sta list_ptr+1

   lda (list_ptr),y
   sta data_ptr+0
   iny
   lda (list_ptr),y
   sta data_ptr+1

Then again you often have to deal with more complicated lookups than that. Not to mention that code size/complexity and register pressure/restrictions are significant drawbacks of manual pointer arithmetic. Besides, I'll go for the optimization over simplicity pretty much every time on the 6502 ;)

My tip is to abuse your macro processor and write yourself a simple interleaving tool to take care of this for you. Then at least you won't have to go through the error-prone process of spreading out and maintaining interleaved tables. Come to think of it I wouldn't mind a bit of direct assembler support for this kind of thing. I believe I could modify ACME's incbin directive to take an interleave factor easily enough.

by on (#38275)
True, there are several optimizations that you could do like the one shown. But you know, this:

ldx Index ;4
lda PointerListL,x ;9
sta TempAddL ;12
lda PointerListH,x ;17
sta TempAddH ;20


Takes a lot less time. Yes, yes, I'm sure you know. Oh, and you could snap it to start on a page boundary, and use ZP indexes, so it would take:

ldx Index ;3
lda PointerListL,x ;7
sta TempAddL ;10
lda PointerListH,x ;14
sta TempAddH ;17

3 cycles less. Though it's really not that much different, it's 30 cycles if you do this 10 times. And 20 even if you can't use a ZP index. Though it would in probably a lot of occasions be less cycles if you didn't snap the arrays to page boundaries, it's safe to assume it's going to take 5 cycles for the LDA PointerListL, x rather than 4.

by on (#38299)
Quote:
My advice is to go for 8-bit precision if at all possible. Not having to bother with 16-bit coordinates everywhere makes so many things so much easier that it's not even funny. A fractional fixed-point byte beneath the screen coordinates occasionally comes in handy as well, but there's no need to burden all objects and algorithms with it when only some of them care. Besides, you can often fake sub-pixel movements in other ways. Personally I like to keep a set of "frame counter mod n" variables handy for such things.

No, no, no. This is crap, I experienced it. 16-bit is flexible and is the way to go regardless if you scroll or not. Unless you want to rewrite everything when you do a game that scrolls or port your game to another system with higher resolution, it's way better to use 16-bit cords.

Celius wrote:
That's so much less dinking around! There aren't any INXs or shifting/adding at all. It's simply load and store. I see no reason good enough to do it the other way.

Well, it's true that in that particular case, the second version is much more optimized takes less bytes and less time. Yet, most of my game engine's code looks rather like your first example. I bet I could optimize a lot of things I haven't yet, I'd have to look for it.
Probably just because it's easier to have a line of 4 bytes for each metatiles than to have 4 arrays with one entry per metatiles. And the array is less than 256 bytes so no [¨],Y needed so it woud just save 2 ASL instructions to split the array. I could do that after I wrote all the metatiles of the game if I feel like it but meh... (but there is other things that metatiles like that too).

However, I've been optimizing stuff for about 2 years and make very slow progress to the project (because when I lack ideas I improve what alredy exists). If I do it forever my game will never be released, and I don't want that to happen. Yet it's true that maybe I should split some arrays, after all this isn't that long doing it by hand or with a small programm (but writing it would probably take longer than doing everything by hand unless I have really big arrays).

by on (#38305)
Bregalad wrote:
No, no, no. This is crap, I experienced it. 16-bit is flexible and is the way to go regardless if you scroll or not. Unless you want to rewrite everything when you do a game that scrolls or port your game to another system with higher resolution, it's way better to use 16-bit cords.
I won't deny that switching from eight to sixteen bit precision throughout the game halfway through the project would be nasty. But then adding scrolling to a game fundamentally changes large parts of the code, beyond just the coordinate system. And believe me, the hardware differences between the NES and a C64 are large enough to make direct ports of anything but the simplest of games virtually worthless.
Don't waste too much time trying to accommodate features you might potentially need in the future, or limit the code in order to be compatible with other hardware you might wish to port to. That kind of programming is simply too restrictive for 6502 games wanting to make good use the hardware, not to mention time consuming.
The best advice I can give is to design your game ahead of time, and try to stick to it. Study other games to see how the handle things, figure out what the tricky hardware bits are and write prototypes, sketch out little dummy routines for doing common tasks with the system you're envisioning before deciding anything, and last but not least don't go overboard with the fancy features (not that I've ever managed to follow that last bit of advice myself.)

By the way my current C64 shooter project uses 8-bit x coordinates for the most part despite the 320-pixel wide screen. This is handled by using the trick I mentioned earlier of shifting up the coordinates by one bit.

Bregalad wrote:
Probably just because it's easier to have a line of 4 bytes for each metatiles than to have 4 arrays with one entry per metatiles. And the array is less than 256 bytes so no [¨],Y needed so it woud just save 2 ASL instructions to split the array.
Right. The problems come when you need to store additional attributes (say, collision or palette data) for the meta-tiles or when you need more than 64 of them. Anyway, I don't know what you're doing with the unused bit-pairs (palette attributes perhaps?) but you might get away with storing the tiles premultiplied instead.

Bregalad wrote:
Yet it's true that maybe I should split some arrays, after all this isn't that long doing it by hand or with a small programm (but writing it would probably take longer than doing everything by hand unless I have really big arrays).
Feel free to use my tool if that would help. Properly integrated into your makefile/build script it shouldn't be too intrusive.

Occasionally it might be inconvenient or just plain impossible to shuffle external files around, usually when referencing labels defined inside of the ROM itself, but I've found that with a bit of macro abuse you can at least avoid any repetition and keep the structures together. I don't know what your assembler of choice is but in ACME you might try something like this:
Code:
       !macro list .field {
       +def label0,73,%00,.field
       +def label1,14,%01,.field
        +def label2,91,%10,.field
       +def label3,22,%11,.field
       }

       !macro def .ptr,.color,.attrib,.field {
       !if .field = 0 { !byte <.ptr }
       !if .field = 1 { !byte >.ptr }
       !if .field = 2 { !byte .color }
       !if .field = 3 { !byte .attrib }
       }

ptr_lo +list 0
ptr_hi +list 1
color  +list 2
attrib +list 3

by on (#38313)
Put this code in a new ASM file in a totally different folder:

Code:
lda #$60
sta SaveAddH
lda #$00
sta SaveAddL
lda #<List
sta TempAddL
lda #>List
sta TempAddH
lda #HoweverManyArrays
sta NumberOfArrays
sta NumberOfArrays2     ;One will be decremented, and one will stay the same.

lda #SizeOfIndividualArrays
sta NumberOfBytesPerArray
sta NumberOfBytesPerArray2
jsr Interleave
....

Interleave:
 ldy #0
 sty ZTempVar1
-
 lda (TempAddL),y
 sta (SaveAddL),y
 clc
 lda TempAddL
 adc NumberOfArrays
 sta TempAddL
 lda TempAddH
 adc #0
 sta TempAddH
 clc
 lda SaveAddL
 adc #1
 sta SaveAddL
 lda SaveAddH
 adc #0
 sta SaveAddH
 dec NumberOfBytesPerArray
 bne -

 inc ZTempVar1
 lda #>List
 sta TempAddH
 lda #<List
 clc
 adc ZTempVar1
 sta TempAddL
 lda NumberOfBytesPerArray2
 sta NumberOfBytesPerArray
 dec NumberOfArrays2
 bne -
 rts


This will interleave the data for you and put in in SRAM starting at $6000. Though you have to copy/paste the un interleaved array into a new document and put the "List" lable above it, and you have to change "HoweverManyArrays" and "SizeOfArrays" to whatever you want.

I haven't tested it yet. I think it should work though. Oh, and you have to make definitions for these:

SaveAddH
SaveAddL
TempAddL
TempAddH
NumberOfArrays
NumberOfArrays2
NumberOfBytesPerArray
NumberOfBytesPerArray2
ZTempVar1

Probably ZP variables. Since it's a different program that does nothing but interleave data, size/time taken/wasting ZP doesn't matter.

EDIT: Okay, I tested it, and it works. You can use my tool too, if you'd like:

http://www.freewebs.com/the_bott/Interleaver.rar

Go into "ByteDefs.asm", and change:

Code:
   .DEFINE SizeOfIndividualArrays 8
   .DEFINE NumberOfIndividualArrays 3


To whatever you want. As you can see, it's currently set up to make 3 8-byte arrays, where each byte in each array is every 3rd byte in the uninterleaved one. And in "List.asm", like it says, insert your data there. Then all you have to do is click "game.bat" and it'll make it for you. Run the game, and X out of it after the "Hello World" comes on screen, and your data will be saved to SRAM!

by on (#38323)
Hey folks. I've played around with it and have managed to get somewhere.

I basically have it, right now, loading in a room data and grabbing various material from it, such as what to load in CHR RAM, what palette to use, etc.

Here are two screens for now:

http://img253.imageshack.us/img253/4981/12kn7.png
http://img523.imageshack.us/img523/2018/13ug5.png

by on (#38325)
Sivak wrote:
Hey folks. I've played around with it and have managed to get somewhere.

I basically have it, right now, loading in a room data and grabbing various material from it, such as what to load in CHR RAM, what palette to use, etc.
Hey, that's actually pretty neat for a few days work! Any idea what you want to tackle next?

Celius wrote:
Okay, I tested it, and it works. You can use my tool too, if you'd like: http://www.freewebs.com/the_bott/Interleaver.rar
Whoa.. I can see the value of native drawing and composing tools, I can even sympathize with all those C64 coders refusing to work with cross-assemblers, but running basic data-processing tools on a bloody NES is just hardcore.

by on (#38326)
doynax wrote:
Hey, that's actually pretty neat for a few days work! Any idea what you want to tackle next?


Right now I want to tackle why the music engine that works fine in my other game is suddenly being randomly erroneous...

by on (#38332)
About the bug, it could probably just be a little typo somewhere, so once you find it, it'll eliminate all your problems. Nice progress though! I'm currently working on object code in my game.

doynax wrote:
Whoa.. I can see the value of native drawing and composing tools, I can even sympathize with all those C64 coders refusing to work with cross-assemblers, but running basic data-processing tools on a bloody NES is just hardcore.


Well, I don't have a very large background in programming. I've programmed for the NES for 3 years now, and a little QBasic. I don't quite understand how to interact with files in modern day programming languages, though I plan to educate myself a lot more and learn about that kind of stuff. So I use what I know to make programs like this, and it's easy for small things like data interleavers. Though I'll have to learn more in order to make things like a level editor and all that stuff, and also I'll be able to design a better interface once I have that kind of knowledge.

by on (#38341)
Celius wrote:
Well, I don't have a very large background in programming. I've programmed for the NES for 3 years now, and a little QBasic. I don't quite understand how to interact with files in modern day programming languages, though I plan to educate myself a lot more and learn about that kind of stuff.
Sounds a lot like my own background actually, except in my case I started tinkering with assembly language when QBasic just wasn't fast enough to handle action games on my 386.
Anyway, I strongly recommend that you get better acquainted with a high-level language even if you only intend to write NES games (and there's certainly nothing wrong with BASIC if that's what you're already familiar with.) I have a tendency to write dozens of useful little tools for any project I work on. That includes everything from sine-table generators, to graphics converters, to packers.
Perhaps their most important use however, and what I made extensive use of when writing my 3D thing, is to easily prototype complicated systems and algorithms without having to get bogged-down with the intricacies of 6502 assembly and the NES hardware. Furthermore a reference implementation is invaluable when debugging any number of problems.

by on (#38389)
Quote:
16-bit is flexible and is the way to go regardless if you scroll or not.


I'm working on a GBA platformer (that scrolls in 8 directions) and was rolling over porting it to NES in a stripped-down form. Instead of doing 16-bit arithmetics every time you deal with object coordinates, how about 8-bit coordinates and an accompanying page variable?

Init the objects page location and coordinates on that page
When coordinate byte wraps around, inc or dec page location. When you need absolute coordinates, use (256*page-1)+coordinates

This mainly applies to objects. I'd still use 16-bit vars for scrolling.

Is this worth trying? I'm not very experienced in NES coding outside a demo that doesn't scroll and displays 'RED BLUE YELLOW' in those colors.

by on (#38404)
This is not a bad idea, in some cases. This might save you a good amount of time if you're dealing with lots of objects.

However, for precision bits, I don't think this is a good idea. Most objects are going to move to a new pixel almost every frame. Moving to a new 256x256 chunk happens a lot less often though. So you'd probably want to use your method for something like that instead of using it for things like precision bits.

One way you could do it is:

Code:
clc
lda XCoordL
adc #5
sta XCoordL
bcc +
inc XCoordH
+


If you're dealing with absolute addresses, that optimization would save you 7 cycles if you weren't increasing the high byte. For ZP, it would save you 5, but that's still good. It would take one cycle less if it wraps around for ZP variables than a 16-bit addition would. It would take two less for an absolute 16-bit addition. Very good in some cases.

But this assuming that you're doing 16-bit 8-bit addition, meaning you're adding an 8-bit number to a 16-bit number.

Also, you might have some problems if you're dealing with signed numbers. Lots of people prefer to add a negative number instead of subtracting a positive one. I like doing this myself. This example I don't think would work for that though.