# 1 MILLION+ COLORS WITHOUT PALETTE CHANGE (technically)

**URL:** https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304
**Category:** Show & Tell
**Tags:** art
**Created:** [December 31, 2025, 8:42pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304 "2025-12-31T20:42:09Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)
#### Post date: [December 31, 2025, 8:42pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/1 "2025-12-31T20:42:09Z")

</div>

this is not fully completed yet, but this is a simple brightness simulator using rgb colors. it never changes the palette during run time, palette is: “#000000”,“#330000”,“#660000”,“#990000”,“#CC0000”,“#FF0000”,“#003300”,“#006600”,“#009900”,“#00CC00”,“#00FF00”,“#000033”,“#000066”,“#000099”,“#0000CC”,“#0000FF”

> **[shared: GPU brightness](https://arcade.makecode.com/S01838-37500-47724-12131)**
>
> Made with ❤️ in Microsoft MakeCode Arcade.

i am using this to create a game with more than 16 colors. If anybody uses this dont make the screen big because it will lag like crazy. also make sure to pre “dither“ your images, or lag will come.

---

<div class="post-metadata">

### Author: ![Cybercube](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/cybercube/32/34628_2.png) [@Cybercube](https://forum.makecode.com/u/Cybercube)
#### Post date: [January 1, 2026, 9:26pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/2 "2026-01-01T21:26:02Z")

</div>

You can use titlemaps as seen here

> **[Gpu colors](https://arcade.makecode.com/S53502-36378-83573-31002)**
>
> Made with ❤️ in Microsoft MakeCode Arcade.

And by changing the screen size.  
You can also use the colors extension to change the brightness of the rgb colors.

---

<div class="post-metadata">

### Author: ![redSprite](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/redsprite/32/34262_2.png) [@redSprite](https://forum.makecode.com/u/redSprite)
#### Post date: [January 1, 2026, 9:33pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/3 "2026-01-01T21:33:53Z")

</div>

I don’t understand most of this  
Very impressive I’ll give you that

---

<div class="post-metadata">

### Author: ![Cybercube](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/cybercube/32/34628_2.png) [@Cybercube](https://forum.makecode.com/u/Cybercube)
#### Post date: [January 2, 2026, 9:16pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/4 "2026-01-02T21:16:16Z")

</div>

Here’s a better example

> **[Gpu colors](https://arcade.makecode.com/S53502-36378-83573-31002)**
>
> Made with ❤️ in Microsoft MakeCode Arcade.

---

<div class="post-metadata">

### Author: ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)
#### Post date: [January 2, 2026, 9:21pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/5 "2026-01-02T21:21:39Z")

</div>

Also i get the importedImage variable through anything that turns an image into raw rgb (im using Photopea), and use this c++ code:

```cpp
#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <string>
#include <algorithm>

struct Color {
    int r, g, b;
};

std::array<Color, 16> PALETTE = { {
    {0x00,0x00,0x00},
    {0x33,0x00,0x00}, {0x66,0x00,0x00}, {0x99,0x00,0x00}, {0xCC,0x00,0x00}, {0xFF,0x00,0x00},
    {0x00,0x33,0x00}, {0x00,0x66,0x00}, {0x00,0x99,0x00}, {0x00,0xCC,0x00}, {0x00,0xFF,0x00},
    {0x00,0x00,0x33}, {0x00,0x00,0x66}, {0x00,0x00,0x99}, {0x00,0x00,0xCC}, {0x00,0x00,0xFF}
} };

// ---------------------
// Closest palette color
// ---------------------
int closest(int r, int g, int b) {
    int best = 0;
    long bestDist = LONG_MAX;

    for (int i = 0; i < 16; i++) {
        int dr = PALETTE[i].r - r;
        int dg = PALETTE[i].g - g;
        int db = PALETTE[i].b - b;
        long dist = dr * dr + dg * dg + db * db;

        if (dist < bestDist) {
            bestDist = dist;
            best = i;
        }
    }
    return best;
}

// ---------------------
// rgbToNumberArr (C++ version)
// ---------------------
std::array<int, 9> rgbToNumberArr(int r, int g, int b) {
    double R = r, G = g, B = b;
    std::array<std::string, 9> pattern;

    auto toHexByte = [](int n) {
        const char* hex = "0123456789ABCDEF";
        n = std::max(0, std::min(255, n));
        std::string s;
        s += hex[(n >> 4) & 0xF];
        s += hex[n & 0xF];
        return s;
        };

    auto decode = [](const std::string& code) {
        char c = code[0];
        int v = std::stoi(code.substr(1), nullptr, 16);
        if (c == 'R') return Color{ v,0,0 };
        if (c == 'G') return Color{ 0,v,0 };
        return Color{ 0,0,v };
        };

    // Generate 9-pixel channel pattern
    for (int i = 0; i < 9; i++) {
        char channel = 'R';
        double value = R;

        if (G >= R && G >= B) { channel = 'G'; value = G; }
        else if (B >= R && B >= G) { channel = 'B'; value = B; }

        pattern[i] = std::string(1, channel) + toHexByte((int)value);

        if (channel == 'R') R -= r / 9.0;
        if (channel == 'G') G -= g / 9.0;
        if (channel == 'B') B -= b / 9.0;
    }

    // Convert to palette indices
    std::array<int, 9> out;
    for (int i = 0; i < 9; i++) {
        Color px = decode(pattern[i]);
        out[i] = closest(px.r, px.g, px.b);
    }

    return out;
}

// ---------------------
// MAIN: RAW -> number[x][y][c]
// ---------------------
int main() {
    const int WIDTH = 144; // <-- set your width
    const int HEIGHT = 81; // <-- set your height

    // Load RAW file
    std::ifstream file("image.raw", std::ios::binary);
    std::vector<unsigned char> bytes(
        (std::istreambuf_iterator<char>(file)),
        std::istreambuf_iterator<char>()
    );

    if (bytes.size() != WIDTH * HEIGHT * 3) {
        std::cout << "ERROR: RAW file size does not match WIDTH*HEIGHT*3\n";
        return 1;
    }

    // Convert to pixel array
    std::vector<std::vector<Color>> pixels(HEIGHT, std::vector<Color>(WIDTH));
    int idx = 0;

    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            pixels[y][x] = {
                bytes[idx++], // R
                bytes[idx++], // G
                bytes[idx++] // B
            };
        }
    }

    // Convert to GPU tiles: number[x][y][c]
    std::vector<std::vector<std::array<int, 9>>> number(
        HEIGHT, std::vector<std::array<int, 9>>(WIDTH)
    );

    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            Color c = pixels[y][x];
            number[y][x] = rgbToNumberArr(c.r, c.g, c.b);
        }
    }
	

    std::ofstream outFile("output.txt");
    if (!outFile.is_open()) {
        std::cout << "Failed to open output.txt\n";
        return 1;
    }

    outFile << "let importedImage: number[][][] = [\n";

    for (int x = 0; x < WIDTH; x++) {
        outFile << " [\n";

        for (int y = 0; y < HEIGHT; y++) {
            outFile << " [";

            for (int c = 0; c < 9; c++) {
                outFile << number[y][x][c];
                if (c != 8) outFile << ", ";
            }

            outFile << "]";
            if (y != HEIGHT - 1) outFile << ",";
            outFile << "\n";
        }

        outFile << " ]";
        if (x != WIDTH - 1) outFile << ",";
        outFile << "\n";
    }

    outFile << "];\n";
    outFile.close();

    std::cout << "Wrote output.txt successfully.\n";

    return 0;
}

```

note that you will need to change the PALETTE variable if you have a different palette in your makecode project

---

<div class="post-metadata">

### Author: ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)
#### Post date: [January 2, 2026, 9:29pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/6 "2026-01-02T21:29:12Z")

</div>

yes but if i do tilemaps i cant do the dithering to anything, and im trying to make… Celeste? actually i may do tilemaps theres a chance

---

<div class="post-metadata">

### Author: ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)
#### Post date: [January 2, 2026, 9:30pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/7 "2026-01-02T21:30:22Z")

</div>

northern lights (test):

> **[shared: northern lights](https://arcade.makecode.com/S83564-25686-23478-03455)**
>
> Made with ❤️ in Microsoft MakeCode Arcade.

---

<div class="post-metadata">

### Author: ![Rune](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/rune/32/18951_2.png) [@Rune](https://forum.makecode.com/u/Rune)
#### Post date: [January 8, 2026, 6:20pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/8 "2026-01-08T18:20:54Z")

</div>

Yo that’s crazy! I tried to do something like this once, but I never got an actual image.

---

<div class="post-metadata">

### Author: ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)
#### Post date: [January 16, 2026, 5:53pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/9 "2026-01-16T17:53:48Z")

</div>

I have one question:  
should I post what I am doing every now and then, or should I work until it is completed?

---

<div class="post-metadata">

### Author: ![Rune](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/rune/32/18951_2.png) [@Rune](https://forum.makecode.com/u/Rune)
#### Post date: [January 17, 2026, 3:23am UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/10 "2026-01-17T03:23:38Z")

</div>

Every now and then, I love seeing halfway done projects.

---

<div class="post-metadata">

### Author: ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)
#### Post date: [January 24, 2026, 3:10am UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/11 "2026-01-24T03:10:46Z")

</div>

made Madeline’s walk animation, and the hair (not part of the animation because Celeste does hair physics) though the hair doesnt have the exact physics in this example. if the project lags, open the code and at the top read the comment

> **[shared: madeline + incorrect hair](https://arcade.makecode.com/S15448-67317-16188-10023)**
>
> Made with ❤️ in Microsoft MakeCode Arcade.

---

<div class="post-metadata">

### Author: ![Danny\_Devention](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/danny_devention/32/30134_2.png) [@Danny\_Devention](https://forum.makecode.com/u/Danny_Devention)
#### Post date: [January 25, 2026, 2:34am UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/12 "2026-01-25T02:34:27Z")

</div>

Hey I’m making a Fnaf 6 Style game and I was curious if its possible to integrate Salvage sections with this extension?

I just saw it and thought “You know that looks like that style could transfer over fairly well” Just because the salvage sections are gonna have a more realistic art style, and there also gonna have pre-rendered assets.

Of course I’m not asking you to do it for me, I’m just curious on if you think something like that could work with this extension.

---

<div class="post-metadata">

### Author: ![British\_Dog](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/british_dog/32/34353_2.png) [@British\_Dog](https://forum.makecode.com/u/British_Dog)
#### Post date: [February 10, 2026, 10:14pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/13 "2026-02-10T22:14:09Z")

</div>

@VoxelMaster64 what Danny’s tryna say is we can figure out the mechanics, but would it be possible to use this extension for the visuals of a salvage section like that from Fnaf 6? we just need a greater understanding of what this is capable of.

---

<div class="post-metadata">

### Author: ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)
#### Post date: [February 12, 2026, 3:01am UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/14 "2026-02-12T03:01:13Z")

</div>

:ᗡ I completely forgot about this!!

what I was going to say:

if this helps, these are explanations of things in “madeline + incorrect hair“:

> **Explanation of entire project**
>
> format of each “rgb pixel” is a number[] of size 9, each number is a palette index:  
> the palette is 000000, 330000, 660000, 990000, CC0000, FF0000, 003300, 006600, 009900, 00CC00, 00FF00, 000033, 000066, 000099, 0000CC, 0000FF, basically rgb with 6 evenly spaced brightnesses, 00, 33, 66, 99 CC, FF  
> one image in this format is number[x][y][c]  
> hair is generated using verlet rope (i think)
> 
> > **GPU.ts**
> >
> > > **class CelesteGPU**
> > >
> > > the custom GPU to handle number[]’s
> > > 
> > > > **constructor(scale: number)**
> > > >
> > > > inits the gpu  
> > > > scale - the scale of each visual pixel
> > > 
> > > > **colorsToTile(colors: number\\\[\\\])**
> > > >
> > > > converts a number[] (visual color) into an Image based on palette indexes  
> > > > colors - the input visual pixel to convert  
> > > > returns a 3x3 Image
> > > 
> > > > **clear()**
> > > >
> > > > “clears” the screen, or makes every fb[x][y] equal to [0, 0, 0, 0, 0, 0, 0, 0, 0] (clear pixel)
> > > 
> > > > **render()**
> > > >
> > > > “renders” the sreen, or turns each fb[x][y] into an Image (using colorsToTile()) and draws it
> > > 
> > > > **loadFromCelesteData()**
> > > >
> > > > converts allColors, allTiles, and tilemap0 into number[][][], and sets fb to that
> > > 
> > > > **shuffle()**
> > > >
> > > > “shuffles” each visual pixel of fb (using shuffleTile(colors))
> > > 
> > > > **shuffleTile(colors: number\\\[\\\])**
> > > >
> > > > “shuffles” colors using the fisher yachts algorithm
> > > 
> > > > **setPixel(x: number, y: number, c: number\\\[\\\])**
> > > >
> > > > sets fb[x][y] to c  
> > > > x - color to set at x  
> > > > y - color to set at y  
> > > > c - color to set to
> > > 
> > > > **drawImage(img: number\\\[\\\]\\\[\\\]\\\[\\\], x: number, y: number)**
> > > >
> > > > “draws” and image to fb, similar to Image.prototype.drawImage(Image, x, y)  
> > > > img - image to draw  
> > > > x - image top draw at x  
> > > > y - image top draw at y
> > > 
> > > > **drawOpaqueImage(img: number\\\[\\\]\\\[\\\]\\\[\\\], x: number, y: number)**
> > > >
> > > > “draws” every pixel in img except the clear pixels to fb, similar to Image.prototype.drawImage(Image, x, y)  
> > > > img - image to draw  
> > > > x - image top draw at x  
> > > > y - image top draw at y
> 
> > **hair.ts**
> >
> > > **class Madeline**
> > >
> > > an “entity”, helps simplify things
> > > 
> > > > **constructor(x: number, y: number)**
> > > >
> > > > inits Madeline  
> > > > x - Madeline’s x position  
> > > > y - Madeline’s y position
> > 
> > > **class HairNode**
> > >
> > > helps simplify verlet rope
> > > 
> > > > **constructor()**
> > > >
> > > > inits the HairNode
> 
> > **loading.ts**
> >
> > > **scaleImage(src: number\\\[\\\]\\\[\\\]\\\[\\\], scale: number)**
> > >
> > > scales a number[][][] by scale  
> > > src - source number[][][] to scale  
> > > scale - scale size  
> > > returns a scaled number[][][]
> > 
> > > **rgbToNumberArr(r: number, g: number, b: number)**
> > >
> > > converts rgb color to a visually accurate number[]  
> > > r - color’s r valus  
> > > g - color’s g valus  
> > > b - color’s b valus  
> > > returns a visually accurate number[]
> > 
> > > **class PNGData**
> > >
> > > helper class
> > > 
> > > > **constructor(w: number, h: number, x: number, y: number, data: string)**
> > > >
> > > > inits the PNGData  
> > > > w - width of png  
> > > > h - height of png  
> > > > x - x offset of png (used to trim the image used to compress png’s even more)  
> > > > y - y position of png (used to trim the image used to compress png’s even more)  
> > > > data - pixel data of png
> > 
> > > **loadPngAnim(PNGs: (string | number)\\\[\\\]\\\[\\\])**
> > >
> > > loads an array of png’s into IMGs  
> > > PNGs - array of PNGs to load
> 
> > **main.ts**
> >
> > > **game.onUpdateInterval(50, function() {})**
> > >
> > > verlet rope physics  
> > > sets fb to IMGs[n] based on how many times it has triggered
> > 
> > > **game.onPaint(function () {))**
> > >
> > > renders to the screen using CelesteGPU.prototype.render()
> 
> hope that helps 😃

> **what I'm saying now**
>
> I have never played fnaf, so I may watch a playthrough to understand the graphics better.
> 
> Right now, one visual pixel is a 3x3, and a number[] (NOT a number[][]) (should always have a size of 9) resembles it. visualPixel[n] is a palette index. the gpu also has a shuffleTile() function to randomly shuffle a given number[]
> 
> the gpu’s render() should be in game.onpaint(). it renders the screen, using colorsToTile() (number[] → Image)
> 
> gpu.fb is a number[][][] and stores the screens pixels, and gpu.fb[x][y] is a position on the screen, returning a visual pixel (number[])
> 
> drawImage draws a number[][][] (same thing as render() but with an input to render rather than fb) and drawOpaqueImage() draws everything in the image OTHER THAN the black tiles ([0,0,0,0,0,0,0,0,0])
> 
> just please note that nothing in the project is an “extension”, it’s just that they are made in different files. I made this for king\_bob, and it has everything in one file: [https://arcade.makecode.com/S90433-28001-45589-11727](https://arcade.makecode.com/S90433-28001-45589-11727). note that huge screens (like 300x300 or bigger maybe) can slow things down alot, especially gpu.shuffle() (shuffles the INTIRE gpu.fb). to speed things up, make sure to parse each number[][][] into an Image.
> 
> BTW, I have some c++ code used to export my png’s into something I can copy+paste into makecode, but I don’t know anything about getting it on github. how do I do it on a way that people can easily use it?

---

<div class="post-metadata">

### Author: ![British\_Dog](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/british_dog/32/34353_2.png) [@British\_Dog](https://forum.makecode.com/u/British_Dog)
#### Post date: [February 12, 2026, 5:37pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/15 "2026-02-12T17:37:44Z")

</div>

what if I linked base game with all the coding complete (with placeholder assets) and linked the real assets so from there you could adapt them? the game doesn’t use a ton of assets (less then ten) so I don’t think it would be that hard. unless it is.

---

<div class="post-metadata">

### Author: ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)
#### Post date: [February 13, 2026, 5:53pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/16 "2026-02-13T17:53:36Z")

</div>

if you mean that I turn an image file (I don’t know what files types work, but png does) into a number[][][], I could do that. I’m also trying to get my new c++ converter (well technically its copilot’s) on github so everybody can use it

---

<div class="post-metadata">

### Author: ![British\_Dog](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/british_dog/32/34353_2.png) [@British\_Dog](https://forum.makecode.com/u/British_Dog)
#### Post date: [February 13, 2026, 7:12pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/17 "2026-02-13T19:12:06Z")

</div>

yeah that’s what I meant. I’ll link em here once I’m done.

---

<div class="post-metadata">

### Author: ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)
#### Post date: [February 15, 2026, 12:32am UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/18 "2026-02-15T00:32:01Z")

</div>

> **[GitHub - cpplus/png-to-makecode: converts an image file into a makecode...](https://github.com/cpplus/png-to-makecode)**
>
> converts an image file into a makecode number\[\]\[\]\[\]

---

<div class="post-metadata">

### Author: ![Gl125371](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/gl125371/32/29131_2.png) [@Gl125371](https://forum.makecode.com/u/Gl125371)
#### Post date: [February 15, 2026, 10:02pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/19 "2026-02-15T22:02:53Z")

</div>

Can you turn this into an extension?

---

<div class="post-metadata">

### Author: ![VoxelMaster64](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/voxelmaster64/32/32075_2.png) [@VoxelMaster64](https://forum.makecode.com/u/VoxelMaster64)
#### Post date: [February 16, 2026, 4:31pm UTC](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304/20 "2026-02-16T16:31:41Z")

</div>

yes, I can try, though first I want to finish an audio exporter

[Next page](https://forum.makecode.com/t/1-million-colors-without-palette-change-technically/41304.md?page=2)
