The answer to the problem is sprite offsets. By default, graphics imported into a project from an image file will have no offset stored (effectively they have offset 0,0).I've put my sprite into my WAD/PK3 and I have put it inside the correct markers/folder and I've done everything you guys told me but when I play the game I can't see my sprite (or my sprite appears in the floor). The actor is there; I can pick it up/bump into it (etc) but I can't see it.
The offsets of a sprite in Doom relate to the position that the sprite will be drawn. With objects that stand in the game world, a point half its width and at height 0 is important; that's where images are drawn from. Perhaps an image...
On the left, the red box shows the position and size of the actor. The width (radius) and height values are defined in the DECORATE or ZScript definition of your actor. However, the sprite has offsets 0,0 and so is positioned below and to the right of the actor. Having offset 0,0 means that the image is drawn downwards and to the right of the middle-bottom of the actor. In other words, it's in the floor.
On the right is the intended situation: actor and sprite of similar size and in the same position.
It is worth emphasising that the the physical position of the actor (red box) can be quite different to visual position (green box) of the graphic/sprite due to its offsets. That's why you might be able to bump into your actor even if you cant see it.
So, how does offset 0,0 look in game?:
OMG my kewl rad suit is in the ground and off to one side. That's not what I want.
Hardware (OpenGL) renderer:
OMG OMG my sprite isn't even there. (It is, you just can see it.)
In both cases, the actor is present and in the right place. Why is there a difference between software and hardware? Software can render sprites below the floor. In fact, most of the original sprites have offsets that put the bottom of the sprite slightly below the floor. This is probably a deliberate decision to try and make them look as if they are not standing on tip-toes etc.
Here is an example of somewhere that it can be seen quite easily. Doom2 MAP02 using the software renderer:
However, hardware (OpenGL) cannot render things under the floor so they just get cut off. Hardware would cut off the toes of the zombieman and the bottom of the health potions (GZDoom has sprite-clipping options in its menu to compensate for this). If the sprite is completely below the floor (offset 0,0 for example), you won't see it at all. There's more on this in the old infographics at the end of this post.
So, How Do We Fix This?
You need a tool that can modify offsets. There are a number of options here but Slade is probably the most commonly used one. Forum thread: viewtopic.php?t=24955
Load your WAD/PK3 up in Slade and select your graphic. I've cropped the images for forum spacing sanity.
There's my sprite in all it's glory (thanks Mars3D) but look at the offsets below it: 0,0. See also how its top left is at the centre of the crosshair? When Slade is in sprite mode, the crosshair is centred on the middle, bottom of where the actor would be (remember my very first image?).
See also the button to the right of the word "Auto"? We can use that to generate our sprite offsets or we can enter them manually by typing in the boxes that currently say 0 (or by using the little arrow scrollers beside them).
So, let's press that button:
Here we are, and we have some options. Generally, for an item standing in the world, you'll want to use the "Monster" or "Monster (GL-friendly)" options. The other options are very useful, but not what we are talking about right now. What's the difference between the two "Monster" options? Remember what I said about sprites tending to have their bottom few pixels below the floor? That's how "Monster" sets things up. Remember how I said hardware cannot render things below the floor? "GL-friendly" positions the sprite so that nothing is below the floor.
Good offsets are typically an X value of half the sprite's width and a Y value that is the same as its full height for "GL-friendly" or 3 or 4 pixels less than its full height for "Monster"-like offsets.
I picked Monster (GL-friendly):
My graphic is 34x57 and Slade auto-chose offsets of X17, Y57 for me. This is fine for a nice, symmetrical sprite. See how the suit is now standing on the crosshair and centred on it in the X direction? Perfect!
Save your file and test.
Here is the file with the above offsets in game:
Yay! Success. Note, nothing is different in these images versus the earlier ones other than the sprite offsets. That's all that was wrong.
So, those are the basics...
If the graphic is an asymmetrical one (e.g. with a monster standing off to one side while firing) you may want/need to adjust the X value to make the image look more centred on the centre line of the Slade crosshair. Slade has no way of knowing if your graphic is asymmetrical so it cannot compensate for that. If you are using automatic sprite offsets in Slade, it will centre the sprite. Even with asymmetrical images, the automatic values give you a good starting point for you to then tweak the offsets as you see fit.
As an example from DOOM2.WAD, the revenant can be seen to skip around a bit while swinging his arm. Consider this image of the revenant punch attack. The offsets are those found in the IWAD (i.e. the ones that id software set.):
As you can see, the revenant's body is way over to one side compared to the centre line.
Perhaps offset's something like this would have been more suitable:
DO NOT MODIFY YOUR IWAD If you want to modify sprites from your IWAD, extract them to a PWAD. Modify them there and then load the PWAD when you play.
Projectiles tend to have different offsets (they tend to be centred on the crosshair in Slade (offsets of half their width and half their height are typical)).
Arctangent wrote:I should point out that the way projectiles are offset is actually pretty dumb. Projectiles don't magically extend their vertical hitbox from their "center," so putting the center of the spirte at y0 means that half of the sprite is in the hitbox, half of it isn't, and there's possibly quite a bit of hitbox that has no sprite as part of it.
I imagine the reason why projectiles are offset like that in the base games is to help make them appear from the proper height and to make it harder for them to block the player's vision after launch. In ZDoom, that's not exactly necessary since you can change the offset of the projectile itself, however.
Weapons are quite different (and outwith the scope of this tutorial).
Slade can also be very useful for setting up large numbers of sprites and comparing consecutive animations. Because the crosshair is always centred in the same place, you can see how your sprite will look as it cycles through its various frames by selecting consecutive images.
e.g. here's how the player sprite looks using the Doom2 offsets it was given by id.
Very nice. Arguably he could be slightly more to the left but the two firing frames line up perfectly.
and here's how it looks after I deliberately gave PLAYF1 a bad X offset (I moved it right by 1 unit).
In this case, in game the player would look as if he was jiggling around a little as he fired his weapon.
And, for completeness, I may as well post a couple of ancient infographics that I made a long time ago that help illustrate the difference between Monster-like and GL-friendly-like offsets (and a couple of other things too, such as relation to actor size):