Community > Your scripts

Ways to think about sprites for character customization

(1/2) > >>

One thing that I've been musing about for a while involves different methods of rendering a custom player character. I'm not overtly familiar with Lua yet, so I'll try instead to talk instead in loose conceptual terms.

Problem: Let's say that you're making an RPG where the main character can be customized - this can include articles of clothing, but also skin tone, hair, gender, faces. Maybe you can even swap out different outfits throughout the game as well, for either cosmetic or plot-specific reasons.

How do you approach this? I have a few thoughts.

Solution 1: Paint a lot of different versions of the same character
If you have the time and energy, this is probably fine. But it's labor-intensive, and a headache if you have to incorporate potentially many animations. It's really jarring for the player to try to pick up a rock, only to have your blue cape turn into a red one, because you're using a fallback animation.

Solution 2: split body parts into components
This is probably less crazy than option 1, in the sense that you're just splitting up pieces and making the game engine re-assemble them on-the-fly. Suddenly your green-girl-haired elf head can be placed on top of a suit of armor, without the need to explicitly build out every permutation of the player's sprite. This still creates a lot of components to graft together, and it could still lead to janky-looking animations, but it could ultimately reduce some work with creating art assets. The tradeoff is that you'll also have to track the custom body pieces that the player set, and keep them.

The other weird thing is that a "hero" would basically be an object consisting of several sub-objects held together a certain way. This would take some trial-and-error to get to render correctly.

Solution 3: use hardware acceleration to color parts of sprites for you
I'm not sure how proven this idea is, but maybe we can reduce the amount of unique body components sprites you have to draw by using the GPU to render color values as parts of sprites. Maybe you actually just have transparent hair styles, for example, and various hair-shaped colored backgrounds could be dynamically rendered behind them. If you do it right, it could look fairly convincing, and allow you to set a bunch of custom color values on a limited set of generic body pieces, assuming you combine this with Solution #2

Anyway, this is where my train of thought is right now. I realize that I'm not actually providing any scripts here, but I'm curious as to whether other creators have come up against this challenge yet, and what their thoughts might be on how to approach the issue. Maybe by kicking around a few ideas, we can come up with some actual scripts.

I'd say that #2 is the best approach for this. For this you'd use hero:create_sprite(). As for rendering correctly, it would probably be easiest to make all the pieces the same size (e.g. 16x16 if that's the size of your hero) with transparent pixels where not used (and the sprites would all have the same origin). That way you wouldn't have the alignment issues.

Solution #1 could work, but as you said, all the possible permutations quickly become complicated. I'd only recommend using this method if you were only swapping out the outfit in its entirety and not dealing with subcomponents.

This is especially complicated for the hero. Let's say you had 5 possible subcomponents (hat, face, shirt, pants, boots) with 3 variants for each. That makes 15 complete sprite sets you'd have to create, and you'd need to account for all the poses as well, including the use of various items. The hero has a lot of them, so you'd have a ton of sprites to make in the end.

Solution #3 is possible with shaders that were just introduced in Solarus v1.6. Seem like more effort than it's worth to me. I suppose if you were strictly dealing with palette swaps, then it might not be too bad.


--- Quote from: llamazing on April 03, 2019, 02:12:18 am ---Solution #3 is possible with shaders that were just introduced in Solarus v1.6. Seem like more effort than it's worth to me. I suppose if you were strictly dealing with palette swaps, then it might not be too bad.

--- End quote ---

I think it's also possible by drawing a surface of a particular color and using a blend mode.


--- Quote from: alexgleason on April 03, 2019, 02:47:13 am ---I think it's also possible by drawing a surface of a particular color and using a blend mode.

--- End quote ---

Eeesh, while it is technically possible using a surface with a blend mode, you'd be much better off doing it with a shader.

So with the add blend mode you could change purple (127, 0, 255) to magenta (255, 0, 255) by adding 128 to the red component. But you cannot change purple to red using the add blend mode because it would require subtracting blue. The multiply blend mode allows you to reduce color values, i.e. multiply the blue component by 0 to result in 0. But now you're doing 2 different blend mode operations, and you'd have to figure out the correct colors to add and multiply on a pixel by pixel basis. So really it would just be as much work as creating individual sprites, but really twice as much effort because you'd need to create an "add" and "multiply" overlay unique to each sprite.

On top of that, you can't draw a surface onto a sprite directly; you'd have to draw it on the screen. So you could use transparent pixels on the blend mode surfaces anywhere where the hero sprite is not present, but if another entity were obscuring the hero then you'd have to account for it, which would not be pretty. Not to mention there would be further complications if the hero sprite used any semi-transparent pixels.

A shader is definitely the way to go here, where you could fairly easily change all pixels of any one particular color to any other specific color, and the same transformation would be applicable to all sprites in the set. Plus it has the advantage of being able to apply a shader to an individual sprite rather than to the screen. The hardest part would probably be setting up the data tables to define all the possible palette swaps.

I've been in the initial phases of thinking about this exact problem, for a project I'm thinking about taking on. I also think we'd need a general approach to this in order for Solarus to successfully branch out to more traditional RPGs.

I agree that #2 seems like the best option, possibly combined with #3 for palette swaps. That option is actually similar to the philosophy behind the Universal LPC Character Generator Project ( This uses a base character sprite and then simply layers each of the armor/weapon components on top at a set location (based on the location of the armor/weapon sprite sheet relative to the character sprite sheet, so transparent pixels like llamazing said).

If you're able to combine #2 and #3, the number of sprite sheets required wouldn't be too bad. You'd need a base sprite sheet for each "race" appearance (like the LPC project has Orcs, Skeletons, and the rest are human-like) which you could color-swap with shaders. Then you'd need a sprite sheet for each armor and weapon type, but those could be applied to any of the base sprite sheets for a large number of combinations. These could also be color swaps with shaders if needed.


[0] Message Index

[#] Next page

Go to full version