In this article we will be looking at a concept called “Composite Sprites”, and how it can be used to implement composite characters in RPG Maker. This article is solely focused on coming up with the specifications and design that the script will be built on.
It goes through an overview of what we want to accomplish, and the steps involved to arrive at a solution that seems feasible to implement.
Composite Sprites is an established concept. For example, if we look at the Torque2D wiki, they define a composite sprite as
a sprite by name that is a composite of multiple other sprites "inside" it. These sprites can be placed in any location and can be of any size, orientation, blending, sort-point, scene-depth, etc.
You’re basically grouping multiple sprites together so that you can control all of the sprites together rather than having to figure out how to synchronize each separate sprite. For example, suppose you have a circle and a square beside each other. If we group them together, we can then move both sprites together, allowing us to preserve their relative positions without having to worry about moving each sprite individually. Moving the whole group 5 units to the left would move each sprite 5 units to the left.
The idea of grouping objects together is not unique to game development or graphics. Many applications allow you to take multiple, separate objects and group them together.
Composite Character Sprites
Suppose you had two equip slots: one for a weapon, and one for your armor. If you had 10 weapons and 30 pieces of armor, and you wanted your character’s appearance to reflect what they are currently using or wearing, you have 341 possible combinations to choose from, including no weapon or no armor, or both). If you needed to draw 341 different sprites for one character, you will probably scrap the idea. And this is a very simple case where you have two equip slots. Add another slot, and you have even more possibilities to consider. Drawing each complete sprite is not a scalable solution at all, both in time and in file size.
The fundamental idea behind composite characters is to have the game engine generate these sprites for you by composing different sprites together to form your character sprite. All you have to do is provide the pieces and tell the engine when to use which piece, and everything should work out.
Now, instead of drawing thousands of sprites, all you need is to draw each piece of equip separately.
Composite sprites come in handy here because your character is composed of multiple sprites, and when the character moves, all sprites need to move in-sync as well.
Creating the Requirements
Since we’re making something ourselves, we have control over everything, including what we want the script to do. Let’s start by considering only armors.
- Allow users to choose which image to use for each armor.
- Build a sprite based on all of the armors that the character is wearing
- Cache the sprite somewhere to avoid having to rebuild the sprite everytime we need to use it
- Rebuild the sprite whenever an armor is changed
These requirements are the bare minimum to have a working script. Additional requirements may come up later on, but for now this is where we start.
Identifying the Constraints
- Character sprites must conform to a particular specification (3 rows, 4 columns)
- You can use one spritesheet per image (VX standard) or hold 8 sheets per image (Ace standard)
These are the default constraints. Other than that, there isn’t much to worry about at this point, though once we start looking at code that might be a different story.
If you are using scripts that don’t follow these specs, then you will need a patch since I’m designing a solution based on the default specs.
Designing a Solution
We start with user input, since that’s the most important part of this script. Let’s look at a few possible solutions. We will then look at the relevant classes involved for handling the sprite.
Suppose we have a “Silk Robe” armor. When an actor puts on the robe, the sprite should be updated to show the robe. This suggests that we can note-tag the “Silk Robe” to specify which robe sprite to use.
<composite sprite: "silkrobe.png">
If you had one actor in your whole game, and only your actor uses composite sprites, then this solution is good enough. If you had multiple actors, as long as every actor that can wear the robe has the same body proportions, then the solution also works.
However, if you have different actors with different proportions such that the same robe sprite doesn’t fit all of them, then you will need to be able to specify which image would be used with which actor.
Given the issue presented above, you may be thinking let’s just tag the actor then. We’ll just specify images for every equip for that actor, and if the actor wears something with no image assigned, then we assume there is no image.
<composite sprite: a1 "silkrobe.png"> <composite sprite: a2 "leather_armor.png">
We use a compact item-string identifier, so “a1” means armor ID 1, and “a2” means armor ID 2. We then specify the image to use for that armor.
This isn’t too bad: you control which images would be used for each armor. However, from a usability perspective, what if I wanted to know which image was used for a particular armor? I’d have to go through every actor and figure out which one they are using. Wouldn’t it be easier to just pull up the armor, find the note-tags for composite sprites, and then see all of the ones that are used?
Adding Actor ID to Armor Notetags
So rather than having each actor specify which image to use for each armor, let’s do the reverse: have the armor specify which image to use for each actor.
<composite sprite: 1 "silkrobe1.png"> <composite sprite: 2 "silkrobe2.png"> <composite sprite: 3 "silkrobe1.png">
Maybe actor 2 requires a different image for the same robe. From here, we can quickly see which actor will be using which image. You could come up with questions for this as well: what if we want to know which armors have images for a certain actor? We’ll have to go through each armor and determine whether they have an image for that actor. But I believe this will be a much rarer use case, because what value does the question have? What you are concerned with is which image will be displayed.
Using a Spreadsheet
For those that absolutely must query how many equips have an image for a given actor, there is the possibility of using a table to set up your images, with armor ID’s on one side and actor ID’s on the other, and the intersection represents which image will be used. Just look up actor 1, and then go across your table and find the specific armor, and you’ll know your image.
This solution would address the issues that I’ve raised, and it would arguably be easier to maintain as well.
Regardless of the input format, the data will need to be parsed and stored somewhere for quick access. There are three intuitive places to store this
- Store it in the Actor. You could have a hash where the key is the armor ID and the value is the image. Whenever you need the image for a specific armor, you could just access the hash.
- Store it in the Armor. Now the key is the actor ID and the value is the image. Given an actor ID, you would return the appropriate image.
- Store it in a separate class. Rather than having actors or armors handle this information, we create a completely separate class that will manage all of this for you. Whenever you need an image, you will tell this manager object which actor you have, and which armor it’s wearing.
If you have a different option, you can describe it in the comments. These are the ones that seem most easiest to maintain and extend (for example, if you want to have composite images with weapons).
I will go with a combination of all three options, creating a class called the CompositeManager that will take care of anything related to sprite composition. Everything else just needs to communicate with it by providing it information.
Assuming we have all of the data provided to the engine and our CompositeManager knows which actors need which images for which armors, we still need to figure out how the composition will be performed. For the most part, the final sprite will be composed of multiple layers of sprites, each representing a different piece of armor. Suppose you had the following armors:
There is usually some sort of order to how they should be put on
- Socks are drawn under Boots
- Pants are drawn over Socks
- Pants may be drawn below or above Boots
- Shirt is drawn under Jacket
- Shirt may be drawn below or above Pants
- Jacket is drawn over Pants
Basically, there are situations where certain armors are drawn below or above other armors. Indeed, you can achieve different types of appearances depending on how you layer them and how each sprite is drawn. This suggests that we need to add an additional requirement to our data: layer order. The order would be an integer. Higher numbers mean they will be placed above lower numbers. This allows you to control how the layering will be performed (and also saves me from having to figure out a perfect order that will be suitable for your sprites, for every project in the universe).
So once the layering is determined, all that’s left to do is to just start with the character’s body and start adding on layers one at a time from lowest to highest. Once the composed sprite is created, you can just return that and have the engine use that to draw your character.
Our sprite is composed of multiple layers, each layer representing a different piece of armor. However, this means that if your actor had no armor, we would have no sprite. Or your sprite might be missing a head or body. Therefore, actors need to have default sprites to work with. This could be the sprite that you assign to your actors in the database, or it could be composed of separate “no armor” images that you specify which would be the default sprite to use if no armor is specified.
If you would like to specify default sprite for each equip slot, this will start to become more complex because at this point, our design does not take into consideration equip slots (and it certainly doesn’t take into consideration what happens when you have two body gear slots or 2 headgear slots).
For simplicity, we will assume the character you select for the actor is the default sprite. We can look at equip-slot-based defaults later on.
This is not required, but it would be useful to do. Whenever your character needs to be rendered on the screen, an image is required. This image can be loaded from disk, or in our case, generated by our CompositeManager. This composite sprite is not stored on disk – though it can be if needed. However, we can probably just store it in memory.
When the composite sprite is generated, we can use the Cache module to store our composite and find a way to retrieve it whenever we need the character’s sprite. It isn’t too clear how it might be done at this point, but it’s something to keep in mind during development.
At this point we have a design for the script and it sounds like it should function correctly, so we can proceed to implement it. We’ve determined how users will provide input, how the data will be loaded and stored, and how the engine will use this data to generate the correct images.
Spread the Word
If you liked the post and feel that others could benefit from it, consider tweeting it or sharing it on whichever social media channels that you use. You can also follow @HimeWorks on Twitter or like my Facebook page to get the latest updates or suggest topics that you would like to read about.