RLE sprite editor tips and tricks
July 18, 2021
Make tiny pixel art sprites in a text format for game jams where you have a limited file or byte size.
RLE stands for Run Length Encoded. It is a way to encode tiny sprites into your games. I read an article by Andrew Berry, where he gave a good explanation about how they work. The idea was so cool that i decided to make a small editor for it.
In this post i will go over each element of the interface and explain how you can interact with it. On desktop you can also slowly hover over each ui element to get a reminder in a tooltip.
The best way to use it, is to install it as a web app from the following url: https://quinten.github.io/RLE-sprite-editor/
The source code can be found on github.
How to use
The canvas all the way on top is the frame preview. It previews the currently selected frame or animation. You can click on this canvas to add a new pixel (like a pencil tool) when there is a color selected from the color keys list (see further). When there is no color selected or the transparent key is selected, clicking on the canvas will remove the pixel (like an eraser). You can also use a fill (paint bucket) tool if you click a second time on the color patch.
On desktop you can also click right and use the context menu to save the frame preview as an image and it will be transparant. So the checkered background isn't included.
Current frame string
Next is an input field with the Run Length Encoded string of the current frame. You can manually edit this string and on key up the pixels in the frame will also change. Manipulating the digits will make the rows of a color longer. Using a non-digit from the color keys list will result in a new color being started in the rows. Any non-digit that isn't in the list or the transparent key ('$' is default) will result in transparent pixels. But to keep things clean it is best to stick to the defined transparent key.
The pipe character '|' is reserved for splitting the frames of an animation. Technically it is also possible to paste a long RLE string with different frames split by pipes in the textfield and the strings will be split over multiple frames after the current frame.
If you draw or erase a pixel on the preview canvas, the string will also be updated.
If you change the width of the frame (see further) there is extra transparency added to the beginning of the string. This can also be a trick to move the sprite in the frame. Keep that in mind because there is no other way to translate the position of the sprite in case you have to.
Sometimes transparant keys next to each other are also detected and merged.
Right below the frame string input are the playback buttons. From left to right: Play animation, Pause animation, Previous frame (and stop), Next frame (and stop). So with these buttons you can play and pause the animation or control which frame is being previewed in the frame preview.
Flip and rotate buttons
The second row of buttons can be used to flip and rotate the current frame. Note that rotating frames which aren't squares (ratio 1:1) can have unexpected results. Flipping them should work fine...
Animation edit buttons
To modify the timeline of the animation there are four buttons. From left to right: Delete frame, Duplicate frame, Move frame up, Move frame down.
The first one removes the current frame, plain and simple. The second one duplicates the current frame, so you can easily adjust it a bit. There is no button to add an empty frame, but you can easily clear a duplicated frame by just removing the text in the input from above.
The last 2 buttons allow you to change the position of the current frame in the timeline. Moving it up/back or down/forward.
The second canvas in the ui is a preview of the sprite sheet or each frame next to each other. Although not clear from the screenshot, it can have multiple rows.
You can select the current frame by clicking the canvas. You can also select a range of frames included in the animation by clicking the canvas a first time to select the start frame and then click the canvas a second time to select the end frame.
In the preview you can see that the frames which aren't included in the animation are the darkest. the ones that are included are a little lighter and the current frame is the lightest.
If you hit the play button and nothing is moving, it might be that you only selected one frame.
When you right click the canvas you can also save the sprite sheet as an image and the tinting will disappear for a moment so it isn't included in the image.
Four small number inputs control the settings of the frames. From left to right: Frame width, Frame height, Horizontal number of frames in spritesheet, Frames per second.
The first 2 are obvious, they control the dimensions of the frame. The third one enables you to have more rows on the sprite sheet by stating the number of frames in a row. So if you add more they will wrap to a next row in the sprite sheet.
The last input is the fps or frames per second. Higher frame rates make the animation faster.
The color keys are displayed as a list. Each list item has four elements.
The round buttons on the right allow you to remove a key. The transparent key cannot be removed, but the button next to it allows you to add a new color.
In the text fields of the color you can put any type of html/css type of color string: hex, rgb, rgba, hsl or even their elegant names (black, white, red, tomato, cornflowerblue, ...)
Also the keys themselves can be changed, even the transparant key. The RLE strings of the frames are updated automatically.
On the far right you have a preview of the color. If you click it, the color will be used to draw on the top preview canvas. The transparent patch will act as an eraser. The first time you click it, it will use a pencil tool. The second click activates the fill (paint bucket) tool.
Finally we have four export options. The first three will copy some text to your clipboard.
You can 'share' your creation as an url. This will also add a hash to the address bar. When you click 'share' you can then also bookmark the current url in your address bar to save a version of your creation. The hash is a base64 encoded string of a json string containing all the data to rebuild your creation in the ui.
The 'string' button copies all the frames as a RLE encoded string (frames separated by pipes '|'), but it doesn't contain any rendering code. When you click 'code' however, you will get a small piece of demo code, which you can then paste directly in your browser console on another webpage or golf into your own game project somewhere. The code itself is not golfed, but kept readable for clarity. I'll leave that exercise to you.
The 'sheet' option let's you download the sprite sheet as a png. You can also do that by right clicking the sprite sheet preview, but on mobile it isn't practical, so i added this button.
You can also import a bitmap (png or jpg). One thing to know is that before you import a sprite you must first set the Frame width and the Frame height (see Frame settings above), otherwise the editor doesn't know how to cut the sprites. You must set the dimensions first, because there is no dialog box appearing afterwards where you can set them.
Also everything that was already there before the import will be gone.
Finally there is a checkbox to enable or disable auto save. Data is saved in local storage, but only one project at a time. There is no ui for saving multiples, but you can easily get around it. By clicking 'share' and bookmarking the url, by adding multiple web app instances to the homescreen on iPhone (each homescreen bookmark has it's own local storage container), by exporting the sprite sheet as png and importing again, ...
Also another useful thing to know is that when you enter the editor by clicking on a shared link of somebody else, the auto save will be disabled by default so it doesn't start overwriting your project.
As you can see the ui is kept very basic, so you can fiddle with it on mobile. However you can already do some useful things with it. If there is anything missing or you find a bug, let me know in the comments or file an issue on github.