Welcome to the Undertale Yellow Wiki! If you wish to interact with the wiki community, ask Undertale Yellow questions or even talk about datamining or modding, the best place to do so is over at our Discord server!
Tired of seeing the old wiki in search results? You can install the Indie Wiki Buddy or Wiki.gg Redirect extensions to fix that!
Technical:Palette Shader
If you ever got into modding Undertale Yellow and wondered why some sprites turn red when you change them, this is a brief technical explanation of the phenomenon.
Sprites for various characters, including Clover, Ceroba, Martlet, Mail Whale and Mo, are applied something internally called a palette shader. A shader in computer graphics is a piece of code that modifies what's being drawn on the screen as it is being drawn, usually to apply special effects such as lighting. In Undertale Yellow, developers decided to, instead of creating entirely new sprites when characters enter new areas, they swap their color palettes using a shader so that they more fit the given area, such as Snowdin, Dunes caves, and Steamworks. This helped the developers not have to swap palettes on characters which visit multiple areas manually by duplicating sprites, but by just applying a shader.
Assumptions[edit | edit source]
- You have the tool for viewing sprites and code of Undertale Yellow.
- You know how colors are represented on computers.
- You have an image editor and know how to use it to pick and change colors.
Color palettes[edit | edit source]
There are 6 color palettes defined in Undertale Yellow:
Palette index | Location | Characters | Indexed by channel |
---|---|---|---|
0 | Snowdin | Clover and Mail Whale | Green (1) |
1 | Dunes caves | Clover and Mail Whale | Green (1) |
2 | Steamworks | Clover and Mail Whale | Green (1) |
3 | Steamworks | Ceroba | Red (0) |
4 | Dunes caves | Martlet | Red (0) |
5 | Steamworks | Mo | Red (0) |
These colors palettes are visible as lines horizontal rows in the sprite spr_final_palette
. You can see which objects are using which palette index and are indexed by what channel by searching for palette_index =
and scr_load_palette_shader(
, respectively.
Algorithm[edit | edit source]
The shader takes as input two arguments:
palette_index
: Palette to use (corresponds to Palette index in the table above)color_vect
: Color channel to index (corresponds to Indexed by channel in the table above)
This is what the shader does using these arguments as input:
- takes a pixel from the sprite being shaded
- selects one of the channels from that pixel (red, green or blue channel)
- picks a row from the
spr_final_palette
sprite based onpalette_index
- picks a column from the
spr_final_palette
sprite based on the previously selected channel from the current pixel - replaces the current pixel with the pixel in the picked row and column of the
spr_final_palette
sprite.
Example[edit | edit source]
To illustrate this better, you can open in an image editor a regular sprite of Clover (spr_pl_down_0
), next to it a screenshot of Clover inside Snowdin, and finally the spr_final_palette
sprite. In this case, you are looking at the first row of the table above as a reference, because your location is Snowdin and your character is Clover. This is what you'll see:
- We take a pixel from the top of Clover's hat. It has the value of (61, 18, 14) (the red channel is 61, green is 18, and blue is 14, on a scale from 0 to 255).
- We select the green channel because during Clover's shading the value of
color_vect
is 1 (you can see this by searching forscr_load_palette_shader
and see what argument it is invoked with in the object you want to shade). The value we have is 18. - We pick the 1st row of the sprite, because
palette_index
is set to 0. - We pick the 19th column of the sprite, because the value we previously picked was 18. Basically, we just picked a pixel at (0, 18).
- This pixel has a value of (51, 51, 82). If you take a look at the corresponding pixel on the Snowdin screenshot of Clover's sprite, you will see that it also has a pixel value of (51, 51, 82). Hooray!
So, how can I fix my sprites being red?[edit | edit source]
Your first option is to just disable the shader if you don't find it useful. Look for shader_on
in the code, and set it to 0 on specific objects whose sprites you changed. You'll have to either live with your sprites not having a matching palette in some areas, or implement a different mechanism for changing sprites in different areas.
Your second option is to follow the above algorithm to update the palette that's causing you issues. Basically, extract the colors you used in your sprite, pick the palette-swapped colors, then for each of the colors of your new sprite select the value of the channel that's being used for indexing the palette, and in that row and column of the palette sprite set the new color you want to be used. If you didn't use too many colors, this shouldn't take too long.