Simple PCE Lighting Engine v.1 By: Ozzy_98 Overview: This is a document on a simple lighting engine for pallet based systems. While it is designed for PCE\TG-16 system, the basic ideas can be used for any palleted system, or even non-palleted systems where colors can be changed quickly. The lighting engine covers two main parts, the sprites, and the tiles. The light in this engine is fixed at a set, non-moving x\y location, and generally is a per screen basis. This makes it ideal for games like Neutopia and Zelda, but it can be used in others, with a bit more work. This engine has little overhead on the CPU, since most of the work is some simple subtraction, and a pallet shift to match. The biggest strain is on the artwork, as it much be drawn to fit this process, and there is a loss of total colors used per sprite, from 15+transparency down to 7+transparency. Part 1: Sprites Sprites are the first part to the engine, and the most complex. The PCE gives you a total of 256 pallet entries for sprites, but they are broken up into 16 groups, and a sprite is assigned a pallet group. Normally, sprites can share pallets, so sprites 1 and 2 have the same pallet of 16 colors. This sharing can not be done using the lighting engine, as the pallets have to be adjusted depending on distance. So each sprite gets on pallet, giving you a max of 16 sprites at one time. When designing the sprite, you need to pick one color to be the gradient color. This is the main color for the lighting engine, and will change colors depending on the light. This should be the main color of the sprite, covering most of the sprite for best effect. After you pick the main shade, you have 6 other colors you can use. These colors are best used in smaller areas, for highlighting. Once your sprite is done with the 7 colors, you need to make a light mask. Make a 16x16 square, and color is in 9 different blocks, each block a different color. Because it's a 16x16 block, you can not get an even number, so each block will be 5x5, 6x5 or 5x6. You can not use 4x4 blocks, as that would be 16 shades, each sprite is only 15 + transparency. You could use 8x8 blocks, and only use up 4 shades, but the effect is much weaker. Once you have the light map, use a paint program to overlay it on top of the sprite. Then, copy the bottom layer on top of these two layers, so all you see if your sprite. Last step, select all the gradient color from the sprite, and delete it. So now anywhere there was the gradient color, there is now a block from your light map. Now that we have a correct sprite, we can now begin programing. In the program, adjust the pallet so all the blocks on the trident are the same color, so it will look like your sprite is drawn with 7 colors. Then, while running in game, for each color in the gradient area of the pallet, 1~9, check how far away that block is from the light. For example, if the light source is 100,100, and the sprite's top-left hand corner is at 120,120, then the first block, the top-left one, is 20,20 away, or 40 total. The next block, top middle block, would be at location SpriteX+5, so it would be 125,120, or 25,20 away, total of 45. As you repeat this process, you get a higher value for the sections that are farther away. What you do now depends on what works best for the game, but generally, the higher the number from the light,darken the color of that pallet. The closer, make it brighter. By using 1 color split into 9 pallet entries, you cause a shading effect (why I call it the gradient color). The part of the sprite facing the light will be brighter then the part looking away from the sprite. This can even be taken to another level, parts of the sprite that would face the light can be drawn with a shade that normally wouldn';t be in the blocked section. The other colors used on the sprite will also change with the light. Take the distance of the sprite from the light source, and lower the remaining colors all the same amount. This means a sprite farther away from the light source will be much darker then one close up. If more colors are needed, 2 sprites can be overlaid on top of each other, with transparencies to allow each to show. This will let you have 2 gradient colors, and 12 non-gradients. Tiles Tiles are simpler to do then the light source, but are needed to make the sprites look correct. The simplest way to do this, draw all tiles with the same 16 color pallet. This will let you have 16 shades of lighting then, the width of the screen. Because there is a max of 16 shades, and max distance on a 16x14 tiled room is 30, unless the light is dead centered in the room, you can not have each tile a different color, you will need to have it every two tiles. For example, if the light is at 100,100, then it would be on tile 6,7. The tile at 8,9, or x\y of 128,144, is 2,2 tiles away from the light, or 4 blocks total. .For every 2 blocks, we lower the lighting by 1, so this tile should be shifted by 2 pallets away from the lighting. This should be done when you design the maps, since the lights will never move. So if the tile with the light source is pallet 1, then those 1~2 tiles away would be 2, 3~4 tiles away would be 3, ect. This makes a star shaped light on the tiles. Then at run time, each room will have 3 basic values, Overall lighting, drop value, and flicker. Overall lighting is a static value added to the pallets for ALL tiles AND sprites. This means in a very dark or light room, the sprites will be lighter or darker. This over-all lighting will be placed on all pallets one time. when the room is loaded. Drop value is used just for the tiles. It's the amount of how quickly a tile darkens from the light source. For example, a 3, then lower all pallet's rgb values in pallet 1 by 3, 6 in pallet 2, 9 in 3, ect. This can also be done one time, when the room is first loaded. Flicker value is optional. It's a random value that, each frame, is applied to all pallets. For example, a flicker value of 10, each turn it would add 0~9 to the values of each color. The last value should be recorded, and subtracted next turn, so that the room doesn't get brighter and brighter.