Skip to main content
gamedev.net
🔒 Locked

Composite sprites

Started by Mayrel 8 replies 4.6k views
Original Post
Mayrel
Mayrel
In many sprite-based games, the appearance of characters changes as their status and/or equipment changes. You can see this in games like Diablo, Baldur''s Gate, Nox, and no doubt many others I don''t own. What I''m wondering is how to compose the different parts of a character''s appearance. Obviously, drawing frames of each possible set of equipment is UltraStupid. It seems obvious that for every piece of equipment, it''s appearance will depend upon the kind of being by which it is equipped, and what that being is physically doing. For a simple example, someone who is standing up looks quite different to someone who is lying down, and so would their armour. Suppose we have:
  • 3 kinds of species: dwarf, human and elf.
  • 4 kinds of headgear: nothing, hat, chainmail coif and helmet.
  • 5 kinds of torsowear: shirt, leather armour, chainmail, platemail and wizard''s robe
  • 3 kinds of legwear: leggings, chainmail leggings and platemail.
  • 4 kinds of shield: none, buckler, small shield and large shield.
  • 5 kinds of weapon: fist, stave, sword, bow, and magical gestures.
  • 10 kinds of action: idling, walking, running, taking damage, dying, being dead, casting a spell, talking, attacking, defending.
The obvious solution is that one needs a rendition of each piece of equipment for each frame of each action for each species. If there are 8 frames per action, that makes 240 frames for each piece of equipment. In this example, that''s a total of 5,040 frames. If each frame shows the character from 8 angles, that''s 40,320 images. If sprites are 32x64 RGBA pixels, then the total size of all that image data is 315Mb. Clearly, image data would need to be cached. It would be reasonable to only load the image data for a particular loadout. With only 5 kinds of equipment, that makes 75Mb of image data. Still quite a bit. I just noticed we can reduce it further by storing the images in 8-bit indexed colour mode, which also lets us specify certain indices as ''personal colours'' or ''team colours''. That''s only 18Mb per character. Which is still quite a bit, but possibly reasonable, as long as we have only a few characters of this level of complexity. So, is this a stupid way of doing things? Is there a less memory intensive method?
hplus0603
hplus0603
You're on the verge of finding out why it takes 30 artists to do anything these days. Creating all that art takes a LOT of time.

That being said: You don't need to draw tiles for the "none" cases, which cuts it down a little. Some actions don't need 8 frames, either, like "being dead". And the base tile can be with nothing/shirt/leggings/none/fist, so you don't need to count those tiles extra; just make sure all the others cover it.

So you get: (3+3+4+2+3+4)*10*AvgFrames == 19*10*AvgFrames or, I would guess, about 1000 frames to draw. This is assuming you don't want to support rotation :-)

A game like The Sims actually stores Z information for each pixel as well, so that, say, walking through a doorway does the right thing.

I suggest looking into 3D.

[edited by - hplus0603 on May 2, 2004 9:58:50 PM]
enum Bool { True, False, FileNotFound };
Mayrel
Mayrel
Well, I do want to support rotation. Otherwise, I can only attack or walk in one direction.

As for 3D: yes. I wouldn''t actually consider drawing 40,320 frames of animation manually. I''d create them in a 3D modeller and have that render the models as appropriate.

However, I don''t want the engine to be 3D for two reasons. Firstly, I simply want to see if I can do it in 2D. Secondly, nVidia is evil -- their graphics drivers cause my USB modem to stop working, so I have to use unaccelerated non-nVidia drivers. For both these reasons, making a 3D engine is not a particularly good idea.
EDI
EDI
I was faced with this same problem a while ago, when working on our game.

out conclusion was,

in order to have 2d characters with lots of changable visual attributes, it is neccisary to.

-use a compositing system
-render induvidual visual components separately
-do lots of post-proccessing on the induvidual components

it is for the last reason we decided to opt-out of using a system where a characters visual aperance can be changed on such a wide level.

here is the example we used to show why it would be hard.

"when rendering a helmet for a character, the helmet would be renderd without the character model, this means that when the helmet is renderd the rear of the helmet would be visible through the front, the image frames would have to be cleaned up later deleting this, so that the helmet could easily be overlayed"

the only way we thought to fix this, would be to keep the character visible, but have it be set to a solid color the same as the bg color, so that the character would occlude correctly, and yet still be able to be clipped out when making the transparent area of the sprite. but we are still testing to see if that is possible with out modeling and rendering software.

Raymond Jacobs,

www.EDIGames.com

www.EtherealDarkness.com

Wyrframe
Wyrframe
Even more importantly, you don''t need all 32x64 pixels for every frame; just the minimum bounding rectangle of the non-transparent pixels in the image, and the X/Y offsets from the "origin" top-left corner. That cuts down massively on both in-memory and on-drive storage.

If you go 8-bit color, you can even probably take advantage of dead-simple Run-Length, Lempel-Zif, or Huffman compression to decrease the on-drive storage, though not the in-memory space. RLE and Lempel-Zif are very cheap and fast compression schemes, so don''t worry about decompression cost.

There''s lots that can be done to reduce it all, as you see.

Although one warning; wouldn''t a dwarf typically be shorter and stouter than a human or elf? You might have difficulty fitting the same leggings on both a dwarf and an elf, for example.
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
Cipher3D
Cipher3D
you ever wonder why Diablo 2, a 2D game, weighs at 1.5 GB? Okay, okay, subtracting cinematics and music, that''s still 1 GB...
I eat heart attacks
Axenation
Axenation
What I would try is for each character, save 2 arrays of bitmap frames, both of the base body. Then load each equipment piece, blit it onto one of the forementioned arrays, and free it from memory. That might be a bit slow though, and the character frames would have to rewritten each time the character changed a piece of equipment.

If you''re worried about actual space of the packaged game, compress the images with a good alogorithm optimized for size (dont worry about speed). Then write seperate executable that umcompresses the data and re-compresses it into something more game usable.

Now I get a cookie!
ZoomBoy
ZoomBoy
You might also remember that not every character on the screen is going to be swappable. It''s just members of the PC''s party.
And the only time it''s going to be swappable is when the characters'' weapon changes, shield changes, or the player goes shopping.
Then build the loading of art for speed. Not much would need to be cached but certainly indexed.
Cipher3D
Cipher3D
There are many ways to reduce memory usage. First and foremost is compression. There are many very good compression techniques out there, not just for 8 bit textures, but for 16, 24, and 32 bit textures as well.

Next, try some creative caching. Almost all well-designed games these days do not hold everything in memory, they do caching. I'm sure Diablo 2 uses caching extensively. Basically, just know what you need, and dynamically load it from the hard disk. The most frequently used textures (i.e. Player) are kept in memory at all times, while rarely used textures (i.e. some key that is only used in one quest) is used ones, then discarded.

Look them up in Google. Search engines are your friend.

[edited by - Cipher3D on May 5, 2004 9:56:48 PM]
I eat heart attacks
Heaven
Heaven
I''ve thought about this very same issue myself quite often over the years, since it''s exactly what I want to include in my game.

Wyrframe hit the nail on the head. If your characters are 32x64 pixels, your weapon and armor frames aren''t going to need to be 32x64 as well. You''ll save a lot more than you think.

Try it. Draw a fully animated character already equipped with a certain item, say sword, shield, helmet, whatever. Then for each frame cut out just enough of the image to cover the item. Helmets will end up taking very little space. Weapons, depending on their size/length will take less but sometimes MORE space than your character. Take a pike for example. It''s going to be a lot taller than 64 pixels. And what if a particular frame calls for it to be at 45 degrees? Heh.

But hopefully you get the idea. Compositing sprites is the way to go in my mind, for a 2D game at least. The amount of variety you get is worth the extra memory requirements for the art.

And finally, I would create my item art by doing what I suggested above: drawing the character with the item equipped and then cutting and pasting to a new image with just the item. That way you avoid clipping issues when you composite. If for example a character''s head is occluding his weapon, the weapon image will have "holes" in it where a wielder''s head would be when animated.

My thoughts.

Take care.
Florida, USA
Current Project
Jesus is LORD!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.