Skip to content

PixelPalette

Extends Resource. Read from the plugin's source on every build.

A palette: a name and a list of colours, saved as a .jcpalette. You make and edit palettes in JamChip’s palette editor. A game uses one to show a sprite in other colours, leaving the sprite itself unchanged.

Set one as the palette of a PixelSprite2D, PixelSpriteTexture or PixelSpriteFrames, and each colour of the sprite’s own palette is drawn as this one’s colour at the same place. Or hand two to a document’s recolor, which writes the change into the drawing.

Example: the slime in red, then back to its own colours:

var slime: PixelSprite2D = $Meadow/Slime/Sprite
slime.palette = PixelPalette.load_palette("res://examples/art/slime_red.jcpalette")
slime.palette = null

Properties

palette_name

@export var palette_name: String = "Default"

The palette’s name, as JamChip’s Palette section shows it.

colors

@export var colors: PackedColorArray = PackedColorArray()

The colours, in order. A sprite shown in this palette maps by place: its first colour is drawn as the first here, and so on. Set whole in game code, or one swatch through set_swatch, every node wearing the palette redraws on the next idle frame: the setter says so with Resource.changed, which PixelSpriteTexture and PixelSpriteFrames listen for.

Methods

mapping_to

func mapping_to(other: PixelPalette) -> Dictionary

What each colour here becomes in other, by place, as a Dictionary from colour to colour: the first to other’s first, and so on, for as many as both have. A colour listed twice here takes the later mapping. This is what a node’s palette applies as it draws, and what a document’s recolor writes into the drawing; empty when other is null.

set_swatch

func set_swatch(index: int, color: Color) -> bool

Sets swatch index, counted from 0, to color, and every node wearing the palette redraws. Use this, or set colors whole, rather than writing colors[index]: GDScript writes a packed array’s element without the property’s setter, so nothing would hear it. False for an index out of range; the colour already there changes nothing.

ramp_between

func ramp_between(first: int, last: int, hue_shift := 0.0) -> bool

Refills every swatch strictly between first and last, counted from 0, with a ramp from one to the other, as palette ramp --between does: PixelPaletteMaths.fill_between. The two named stay. False, and nothing changed, for a pair out of range or with nothing between.

nudge_swatches

func nudge_swatches(indices: PackedInt32Array, lightness := 0.0, chroma := 0.0, hue := 0.0) -> void

Moves each swatch in indices, counted from 0, in OKLCH, as palette nudge does: PixelPaletteMaths.nudge. An index out of range is passed over.

regenerate

func regenerate(locked := PackedInt32Array(), seed := 0, spread := 360.0) -> void

New hues for every swatch not in locked, the same for the same seed, as palette mutate does: PixelPaletteMaths.regenerate.

sort_swatches

func sort_swatches(by_hue := true) -> void

The swatches sorted by hue, or with by_hue false by brightness, as palette edit --sort does. A sprite wearing the palette maps by place, so its colours move with the sort.

load_palette

static func load_palette(path: String, cache_mode := ResourceLoader.CACHE_MODE_REUSE) -> PixelPalette

The palette at path, or null when nothing is there or it is not a palette. The instance Godot already has loaded, unless cache_mode asks otherwise, so a palette set on several nodes is one resource.

Example: a skin chosen by name, or the sprite’s own colours when there’s no palette by that name. A game would read the name from the player’s settings; here it’s written in:

var skin := "gold"
var sprite: PixelSprite2D = $Player/Sprite
sprite.palette = PixelPalette.load_palette("res://art/%s.jcpalette" % skin)

JamChip, by GlitterSnack. MIT licence. Built from the source on every merge. Its artwork and screenshots are made with JamChip.