What "technique" is Notch using?

When I was watching Notch develop a game for a competition, I noticed that his textures/sprites are all gray on file, but in-game they are coloured? I’ve been trying to figure out what that technique is called. Could someone tell me if they know?

Thanks.

In Minecraft, they are coloured, except for particles, I don’t think theirs any name for it, his just colourizing the images.

in LWJGL, you can set the colour of an image before rendering it, then it will change the colour of it.

His basically just setting a different colour to the different colours on the sprites.

e.g. most of his games that are not Minecraft, the sprite sheet is pink. all colours that are pink are then set to fully transparent.

When he sets the image, he would cycle through the pixels of the image, changing all the pixels that are coloured a certain colour to another colour.

EDIT: added some stuff

Okay. The game he was developing when I was watching was “MiniCraft” I believe.

Yeah, read the last 2 lines before the edit, I added what I think he did for that.

I think that sounds pretty interesting. Is it performance efficient or just to skip colouring the textures?

Im not to sure on performance, if their is, its going to be like 1ms difference lol.

He uses the character drawing as the zombies too just recoloured, this would save him having to copy recolour the image, (if I remember right, the characters are made of 2 or 3 colours) so he only has to copy and paste the code, and change the colour the pixel is point 2.

Yeah that makes sense, I guess it’s nothing to go for if you’re not going to be using a lot of the same textures.

yeah, maybe someone else may have a different input on reasoning why it may be better.

It is for flexibility purposes - so you don’t have to create the same sprite multiple times, you just reuse the same sprite texture and re-color it to however many colors you like. I personally use a custom “Color” that accepts integers for r,g,b,a values of 0,0,0,0 to 255,255,255,100 respectively. We simply load up a “white” sprite and color it to whatever we wish at runtime.

Some other awesome things you can do is create a “color” interpolator, where you can linearly interpolate from one color to another at runtime for awesome effects, very handy for complex particle systems.

For reference purposes, as far as the GPU is concerned, it is an extremely fast operation, using glDrawElements and a glColorPointer I notice a 2FPS difference on a 15,000 sprite test (66FPS colors off) vs (64FPS colors on). That 2FPS could also be the fact that an extra buffer needs to be created for each sprite, so it could very well be a CPU bottleneck in which case no difference in render speed.

PS - here are some images - is this what you’re describing? thats 15,000 sprites, one version colors turned off, the other colors turned on. 69 FPS colors off, 68 FPS colors on. Colors chosen randomly.

DrHalfway – did you optimize for grayscale by specifying less vertex attributes to the shader? Enabling and passing 4 versus 8 attributes per vertex might make for a more significant difference.

{x, y, u, v} vs {x, y, u, v, r, g, b, a}

It took me a while to grok Minicraft’s color system while doing my scala port – Notch isn’t big on comments. It’s kind of clever and nice for dynamically colored stuff, but I’d say for most games it isn’t worth it, especially not the way he packs in the whole 4-color pallette into a single int.

I think the reason he does it that way is because he probably needed something like that for his earlier games and got really good at it, so he finds it easiest to use that system and it does have a few benefits. (Can make textures a little bit more random if he wanted to, etc)

Really, it’s just whatever works for you imho.

As far as i can remember:

He has the sprites drawn in a 8x8 grid, colored in a 3-color grayscale
When drawing, he has a code that replaces that 3-color pattern for another one of his choice.

In shorts, you might want to use this method if you are planning on having the same sprite in several different color patterns. Otherwise, just color your sprites directly in the image.

@DrHalfway: Minicraft has a 160x120 screen, with 24x24 (scaled up 3 times) tiles. One layer of sprites for the world, one for the items, and one for the npcs
That’s 19200 pixels for the screen and 576 for a tile. Which is 34 sprites for a layer, at most, rounded up, or 102 sprites for the whole game.

Of course handling pixel-arrays is slower than lwjgl. But seeing 15k sprites being recolored in 1 frame worth of performance, is awesome.

I find Notch’s version of per-pixel changing rather limiting. For one thing, with the way he implemented it, you’re limited to a maximum of 256 colors (I think it’s actually 216, but I’m not 100% sure). On top of that, you’re kinda limited to using very few different shades of colors in each sprite, otherwise you’d have to specify a dozen or so colors for each sprite, which can get annoying pretty easily (having to remember which shade of gray goes with which color, finding the color you want to change, etc). Another point is re-sizing. Everything rendered is placed inside a pixel array somehow connected** to a BufferedImage the size of the screen as it woud be in 1:1 scale. Only when the BufferedImage is rendering does it’s scale multiply by three. So basically, scaling is restricted because the dimensions of the BufferedImage are in 1:1 scale, not 1:3 scale.

So yeah. I find it much better to just color the sprites in your SpriteSheet, and forget about changing colors in your code.

**Notch gets the pixels of a BufferedImage with “int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();” and any changes he makes to the array automatically get reflected in the BufferedImage. If someone could explain why this is, that would be great as I’ve been wondering for a while.

If this really is the case… Then intresting :smiley:
And then it’s like this:

Do you know what a pointer is? A pointer is (actually) an int/long, which “points” to a position in memory. Usually you use them to “find” Object instances. for example:

MyReference ref = new MyReference("This is the known constructor");

in which case the constructor would “return” a pointer to newly allocated memory.

In java almost everything is a pointer. So actually everything exept byte, short, char, int, long, boolean, float, double.
So int[] is actually a pointer to a specific point in memory. And the int[] you get returned is a pointer pointing directly at the buffer array used by the BufferedImage, which also means, that this is JUST the array used to render the pixels for the BufferedImage.

And actually this is only a guess ;D But It seems to be like that.

Hmm… interesting. I wonder why getRGB() doesn’t do that, then. Would save you having to use setRGB() afterwards. Anyways, back on topic I guess, sorry for hijacking this thread. :smiley:

Depending on engine setup we use either packed color or raw, there is about 3FPS difference between the two. Packed color basically packs the rgba component into a single 32 bit float and passes directly, non packed uses 4 32 bit floats for rgba.

So packed looks like this, where c is the color as a 32 bit float

{x, y, c, u, v}

And unpacked

{x, y, r, g, b, a, u, v}

The above example is a bit slow, those 15k sprites are 15k Dynamic GameObjects moving around, so a full transformation matrix is computed for each one and transformed before rendering. We use specialized rendering for particles and static (non moving) GameObjects which skips alot of the expensive transformations for faster rendering. Same technique though.

jhallenberg,
Watch video #2 onwards from this thread here.