A sprite.png will be automatically created if one is not present. This is used to load sprite data into memory. The .png is cut up into 8x8 grids of pixel data, which represent sprite graphics in memory. Since sprites are simply references to color id, the system will attempt to parse the .png data, match those colors to what exists in the system or color map, and then store them in memory in a compressed format.
Let’s take a look at a sample sprite.png. Here you can see we have two UI screens laid out next to each other as a 512x240. If all of the sprites were used, we should have 1,920 sprites:
Since PV8 only supports 8x8 sprites, the importer will automatically cut up these sprites to the correct size. From there, it will also remove repeating sprites to optimize the amount of space they take up in memory. Here is what the sprites will look like after being imported:
As you can see, the importer automatically optimizes the sprites.png leaving us with 480 sprites, which is a 75% reduction. It’s also important to note that, by default, transparent space is ignored and converted to the system’s default mask color. PV8 doesn’t store transparent colors. Internally, the masked color is ignored when the sprite is drawn to the display. However, you can use transparent colors when importing sprites, or use your own mask color and simply change the color settings so the system knows what color to mask out.
As each 8x8 sprite is imported, it is being analyzed against the maximum number of colors per sprite. An 8x8 sprite can have a maximum of 64 unique colors, but most system templates limit this value. The reduced number of sprite colors is a hallmark of classic 8-bit systems and their own memory limitations around drawing sprites to the display. As a sprite is parsed, if it contains more colors than are allowed, it will be replaced with the mask color. It’s also important to note that, if the project is archived and the sprites are optimized during that process with more colors than are supported, they will be saved out with the mask color replying the additional colors.
There are a lot of tricks you can use to take advantage of how the sprite importer works. Since the engine will automatically parse any sprite.png file, you can use this to help optimize your collection of sprites. Once the system has optimized them, it will automatically override the existing sprites.png when you save the project. This is helpful when you are first trying to get all the artwork into the game to use the full design. Once you are happy with it, simply let the engine export the final set of sprites from memory when you archive the game.
Keep in mind that the engine has limits on the number of sprites it can store in memory. While technically the engine can support any .png that is divisible horizontally and vertically by eight, it helps to optimize your art based on sprite pages, which is how the internal system stores and calculates the total sprites available.
A single sprite page is 128x128 pixels, which contains 256 sprites. When you are configuring the system, you can define how many sprite pages the system supports. The maximum number of pages is four, which means there is a potential total of 4,096 sprites. That means you would want to lay out all of your sprites on a 512x512 pixel .png. Here is a breakdown of how sprite pages scale:
The last thing to keep in mind is that, even though PV8 can only support rendering 8x8 sprites, you can still use larger sprites in your game. In order to do this, you’ll need to combine those sprites at run-time. Let's take a look at some sample UI:
Here you can see we have the pagination buttons. In this example, we have a 5x2 grid with a total of 10 sprites:
Some of these sprites repeat or are empty, which helps cut down on the total number of sprites that need to be stored in memory. You’ll see that we have six unique sprites, but we still need nine sprites to render, ignoring the one empty sprite in A2.
Just keep in mind that the system has a limit on the number of sprites it can draw to the display, so the larger your sprites, the less you may have for gameplay in the end. You can also leverage the tile map to gain an additional area to render larger tiles that don’t need to move around the screen.