GSoC Sprite Sheets Shuger
|This page is related to Summer of Code 2010|
|See the list of Summer of Code 2010 Ideas|
|This is a Summer of Code 2010 student page|
|Project: SoC Ideas SpriteSheets|
Shuger - sprite sheet support
I want add sprite sheet support to Wesnoth. The general idea is to assemble multiple small images into few bigger
In my idea of implementation there are two possible sprite formats:
- separate files
- sprite sheet
Current way of managing sprites, each image in a separate file.
wml remains the same.
This format is not for manual editing. It is created from separete files or normal sprite sheet automatically. To generate it special packing algorithms will be used to optimize it's size. This will be the format normally used. Generation should occur at build time uing a custom tool added to build process. It will be possible too run tool manually if someon desires.
Algorithm: 1. Parse wml file created by artist and collect all information about needed sprites for certain unit. 2. Load all needed images, parts normal sprite sheet specified by wml file. 3. Use a rectangle packing algorithm to pack them into as small space as possible. 4. Bake optimized sprites onto new optimized sprite sheet using information from step 4. Write it to a new file. 5. Update wml file with changing all references to optimized version and adding each sprite offset and size information.
example wml frame definition:
[frame] x_position = 32 y_position = 32 x_size = 24 y_size = 24 image="units/elves-wood/archer+female-spritesheet.png" [/frame]
x_position and y_position - position of the sprite in the sheet, in pixels from top left corner(because of the way SDL coordinate system works).
x_size and y_size - optimized sprite size.
Optional algorithm step: Once all other features will be completed additional step maybe added. However it will need to be tested whetever it gives some reasonable gains. Many sprites have image (say 72x72 pixels) where only a part is actually a sprite and the rest is wide transparent border. This doesn't considerably impact image size on disk, because of png compression but is taking significant amount of uneeded memory when loaded into SDL surface (which doesn't use compression). The point of this step is to crop the image by finding a minimal rectangle to fit entire sprite in and then store the size and offset of this rectangle in comparison to original image in order to blit image properly.
When optimizing anything you can never assume anything that's why all things mentioned in this section must be profiled in prototype stage of implementation to see if they bring any considerable gains.
SDL allows RLE surfaces. Typically RLE alogrithms are used to compress images, but SDL RLE surfaces are made for speed not for memory usage. This is going with some additional processsing that's needs to be done during loading. Despite for SDL RLE focus on speed in images like in wesnoth were there are long horizontal strips of the same color(example: transparent border) there is also smaller memory usage.
Proper use of caching may lower memory requiements. Instead of holding spritesheets in memory at all times, only the needed ones should be loaded. This can be implemented by using a caching algorithm to manage what spritesheets to keep in memory an which ones to load/unload.
Because loading an image from hard drive can be slow(disk operations in general then to be very slow) cache can hold currently unused spritesheets in unprocessed format which has the same size as image on the hard drive. SDL supports it (IMG_Load_RW, SDL_RWFromFile, etc).
This may require some changes to Wesnoth cache code. Also while it may seem that uncompressing raw data is performance loss, it's actually not that slow compared to reading from disk which takes most of the time neded to load image completely.
Other game code shouldn't have to concern itself with were the image is(memory/hard drive) so it should fetch them threw a special locator.
Artists cannot be expected and shouldn't be bothered with making spritesheets memory efficient. Therefore during spritesheet loading all sprite frames from current group(ex. elf warrior) will be fetched from their respective sources and put on new generated spritesheet. Special packing algorithm will be used to make it efficient. This problem is algorithmically hard therefore different algorithm should be considered and tested before final choice can be made. One example algorithm is here: http://www-rcf.usc.edu/~skoenig/icaps/icaps04/icapspapers/ICAPS04KorfR.pdf
Important part of making it easy for artists to work with spritesheets are tools. There will be a tool that would allow to generate spritesheets from multiple images and modify or create wml accordingly. It will also allow to update already done spritesheet if needed. It tool will be written in python with simple to use gui(pyQt or pyGTK can be used for this).