Game Backgrounds

Share graphical tips, notes and queries related to our favourite screen layout and its editors.
Post Reply
Ralf
Rick Dangerous
Posts: 2279
Joined: Mon Nov 13, 2017 11:59 am
Location: Poland

Re: Game Backgrounds

Post by Ralf »

A common 'nesting' of these techniques is to define a set of 8x8 pixel characters (e.g. 256 of them), then define a set of tiles made up of 4x4 characters. An attribute may be fixed for each character, or it may be defined for each character in the 4x4 tile (then the tile data is doubled, but maybe you'd have fewer characters to start with). Then the background is made of a map of those 4x4 tiles. This isn't too hard to expand on-demand, and it makes scenery storage much more efficient - if a little blocky.
Yes, you can have more than one layer of organisation. And it can work both with "map" approach and "objects with coordinates" approach.

Imagine a big tree. You can place it in several locations. But this tree may be a complex object itself that consists of smaller objects that repeat - leaves and branches. The same may be with building or even a human. You can have humans with different heads but reuse the same legs, right? ;)

Instead of storing each leaf of tree on each location independently, you just keep the information that there is a tree and somewhere else you keep the tree definition. It makes everything more complex but it saves memory
Nomad
Manic Miner
Posts: 600
Joined: Thu Dec 28, 2017 12:38 pm

Re: Game Backgrounds

Post by Nomad »

I went with creating backgrounds with slices of 32 x 192 pixels. A whole screen can be created from eight slices. I was not concerned with scrolling so things like compression tools could be used to make the slices manageable. With this in mind quite complex backgrounds could be made up. But that is a lot of work creating the slices.

Still It gives a lot of control and if its uncompressed my guess is its a pretty fast technique (though simplistic.)

The index for each screen is 24 bytes (that gives a 16 bit ID for backgrounds and then you have 8 words to point to slices with some padding).

Here are some screens..

Image

This uses six unique slices to create the screen..

You can see some of the slices are my homage to mailstrom :lol:


Image

Image

These were my test slices from $1 - $10

Even with these limited number of slices you can create quite interesting backgrounds - excuse my potato pixel skills. But I figure a background like you have with mailstrom could have been done with less than 20 slices this way. Still good to have a method that give you much more flexibility/scope for something more impressive.

What I have been thinking to do is use masking so you can just use the technique talked about with building up the screen in layers but that would require more bytes to encode the screen as each layer would require a pass.

Needing another 16 bytes per layer.. But would give greater flexibility in creating the screens. at the expense of encoding length.
Last edited by Nomad on Tue Feb 13, 2018 11:05 am, edited 1 time in total.
Ralf
Rick Dangerous
Posts: 2279
Joined: Mon Nov 13, 2017 11:59 am
Location: Poland

Re: Game Backgrounds

Post by Ralf »

Nice to see you progressing.

32x192 pixel tiles? Rather not seen in real games as it would be ineffective. Please notice that you are storing a lot of the same data again and again - sky, pavement, windows.

Check how much memory you need for your tiles and how much you would need if you did it the same screen with 32x32 tiles.

But just for fun it's absolutely all right ;)
User avatar
Joefish
Rick Dangerous
Posts: 2041
Joined: Tue Nov 14, 2017 10:26 am

Re: Game Backgrounds

Post by Joefish »

It'll be fast, but they'l be a lot of repetition (and big blank bits) within each slice, so it won't be very memory-efficient.

I would suggest a set of 32x8 pixel blocks, then make your slices as a stack of just 24 bytes that point to those blocks. That way each screen is made of 8 slices, and each slice is made of 24 blocks.

And here's a trick for storing those 32x8 blocks. Limit yourself to 64 of them. Then store them as a horizontal row, 256x8 pixels, storing the top pixel row of all the blocks first, then the next pixel row, etc. And start them off in memory at an address divisible by 256. Now you can pick any 32x4 block out of the row with a number 0..252 (i.e. 0..63 x 4). And step down through the pixel rows by adding 256 (i.e. add 1 to the high byte of the address).

Now you pick your slice, look up the 24 blocks that make it up, where each is a byte. That byte is the low-byte address of the start of your 32x8 block, so just combine it with the high byte of the first address. Now copy four bytes from there to the screen. Reset the low byte to the block index and add one to the high byte to get to the next pixel row and copy another four bytes, etc.

Also, if you design your slices to be a bit taller than the screen, by using 16-bit addresses to point to them, you can tweak the address by a byte or two, and the slices will appear higher or lower on the screen than their neighbours, for e.g. different road widths.
Nomad
Manic Miner
Posts: 600
Joined: Thu Dec 28, 2017 12:38 pm

Re: Game Backgrounds

Post by Nomad »

Ralf wrote: Tue Feb 13, 2018 11:01 am Nice to see you progressing.

32x192 pixel tiles? Rather not seen in real games as it would be ineffective. Please notice that you are storing a lot of the same data again and again - sky, pavement, windows.

Check how much memory you need for your tiles and how much you would need if you did it the same screen with 32x32 tiles.

But just for fun it's absolutely all right ;)
Yes I really need to learn more memory efficient techniques, it seems to be a straight trade off in many cases between speed and memory efficiency.

I was thinking to use a bank of microdrives to store the slices (well calling them from the microdrive memory buffer) I would have to test it but I think it would work.. (I was getting desperate :lol: ) But doing it that way makes anything but a lords of midnight style wait while I process the game loop possible. :lol:

One thing I would like to do is learn masking, to be able to do it really well. I think then that will greatly improve what I can do with the screens and reduce the memory required but at the cost of a little processing speed. Still its a nice trade-off to have I think, and it reduces the repetition with the slices.

Doing this really made me appreciate why I need to learn new skills. The modern colour libraries for the spectrum would be the next logical step as monochrome is something probably best left in the past :)
Joefish wrote: Tue Feb 13, 2018 11:07 am It'll be fast, but they'l be a lot of repetition (and big blank bits) within each slice, so it won't be very memory-efficient.

I would suggest a set of 32x8 pixel blocks, then make your slices as a stack of just 24 bytes that point to those blocks. That way each screen is made of 8 slices, and each slice is made of 24 blocks.

And here's a trick for storing those 32x8 blocks. Limit yourself to 64 of them. Then store them as a horizontal row, 256x8 pixels, storing the top pixel row of all the blocks first, then the next pixel row, etc. And start them off in memory at an address divisible by 256. Now you can pick any 32x4 block out of the row with a number 0..252 (i.e. 0..63 x 4). And step down through the pixel rows by adding 256 (i.e. add 1 to the high byte of the address).

Now you pick your slice, look up the 24 blocks that make it up, where each is a byte. That byte is the low-byte address of the start of your 32x8 block, so just combine it with the high byte of the first address. Now copy four bytes from there to the screen. Reset the low byte to the block index and add one to the high byte to get to the next pixel row and copy another four bytes, etc.

Also, if you design your slices to be a bit taller than the screen, by using 16-bit addresses to point to them, you can tweak the address by a byte or two, and the slices will appear higher or lower on the screen than their neighbours, for e.g. different road widths.
Yea the memory inefficiency was me being lazy in building the screen, I should have learned to do masking better and/or clever tile selection. :lol: I should really be learning to do both. Those are some interesting tricks I will need some time to have a play with them and see how it turns out thanks for the tips.

My thinking was because there was no scrolling, I could use compression and just store the tiles slices on something like the microdrive. Then just copy in the tiles as needed to the buffer... But that would still take a lot of space.

I will experiment with all these suggestions, it seems that your 32x8 tile method would produce some nice effects in addition to everything else.

Like I said before with Ralf I need to learn masking properly to really progress now so I will spend time with the books/tutorials and apply them to both your advice and hopefully make something better.

Cheers!
Ralf
Rick Dangerous
Posts: 2279
Joined: Mon Nov 13, 2017 11:59 am
Location: Poland

Re: Game Backgrounds

Post by Ralf »

What do you mean by "masking" here?

Masking, as most people understand it, is generally a technique used when drawing moving sprites, not backgrounds.
Nomad
Manic Miner
Posts: 600
Joined: Thu Dec 28, 2017 12:38 pm

Re: Game Backgrounds

Post by Nomad »

Ralf wrote: Tue Feb 13, 2018 11:38 am What do you mean by "masking" here?

Masking, as most people understand it, is generally a technique used when drawing moving sprites, not backgrounds.
My thought was like with sprite, but to build a background. So that I can just overwrite a screen space with a new tile, but have a transparent part that would not overwrite. and have the mask so that only that part will be written to the screen memory area.

umm..

0 0 0 0 0 0 0 0
0 1 0 1 1 0 1 0
0 1 1 1 0 1 1 0

Like this is the tile i will write over a space

so I don't want the whole thing to be written only a portion that will actually update. So I make a mask.

0 0 0 0 0 0 0 0
0 1 1 1 1 1 1 0
0 1 1 1 1 1 1 0

then use some routine to use this to write the information to the screen memory area and update.

That is my limited understanding of masking.

Because if i just XOR the data the 00 in the tile I am overwriting are going to get 'lost' and it won't look nice. So i need the mask to preserve that.

That way with a limited tile set i could create quite complicated screens. It might be a bit on the slow side because it would take three passes to make a screen background (assuming there are three layers)
But for something where there is no scrolling it might be ok I think. two pass would be pretty nice compromise.
Ralf
Rick Dangerous
Posts: 2279
Joined: Mon Nov 13, 2017 11:59 am
Location: Poland

Re: Game Backgrounds

Post by Ralf »

Okay, I get it. Yes, you can use masked objects on background. First draw background from tiles and then in front of these tiles put some masked objects for more background variety.

It is rarely done but entirely possible.
Nomad
Manic Miner
Posts: 600
Joined: Thu Dec 28, 2017 12:38 pm

Re: Game Backgrounds

Post by Nomad »

Ralf wrote: Tue Feb 13, 2018 12:22 pm Okay, I get it. Yes, you can use masked objects on background. First draw background from tiles and then in front of these tiles put some masked objects for more background variety.

It is rarely done but entirely possible.
Yes that is the plan, to use this method. That way I can use a limited tile set but still make interesting screens without having to use that slice method I show earlier with the memory blow out. :lol:

If I can pick your guys brain, what is the fastest way to do the masking routine?
AndyC
Dynamite Dan
Posts: 1386
Joined: Mon Nov 13, 2017 5:12 am

Re: Game Backgrounds

Post by AndyC »

The fastest way is not to do it. :lol: Generally small tiles can cover a multitude of sins and you can effectively provide pre-combined patterns to construct more detailed backgrounds that appear to have that sort of level of detail (the lampposts in Batman The Movie driving sections for example). Normally you'd want to avoid having to do masking on the background layer unless you're doing parallax.

If not it's really the same as drawing masked sprites with a combination of AND/OR operations to first cut out a hole and then fill in the relevant space. Storing a mask for every background object may also start to eat into your memory usage so you also need to consider being a bit sneaky about that too.
Post Reply