Palette

Palette post thumbnail image

Under construction

Almost any video game sprite or background you will ever encounter to the present day relies on a form of lossless compression utilizing a color table (palette). OpenBOR is no exception, and provides a variety of tools, options and features to help you build colorful games with minimal resource use.

Model Palettes

In OpenBOR each entity on screen is drawn from one of an unlimited number of 8bit color palettes defined in its model text. The first cell in each palette is the transparent color. The most common choice for the transparent color is Red 255 Green 0 Blue 255, sometimes known as “magic pink”, but you can use any color you like To reiterate: The color value does not matter at all. In fact, OpenBOR replaces whatever the RGB value is with 0, 0, 0 anyway (see tip below). The color in the palette’s first cell is always the transparent color, no matter what that color is.

When creating sprites for the model, each sprite must have an identical palette. Once all the sprites have a matched palette, you can then create alternate color sets by copying the palette and changing the value of one or more color cells.

Tip: Avoid RGB black (0,0,0) in your sprite colors. OpenBOR treats black as transparent for some specialized elements (ex. subscreens). In fact, the first color table entry is always replaced with RGB black on load. Moreover, any unused colors in the table also have a value of RGB 0,0,0 (this is universal and has nothing to do with OpenBOR). Therefore using black could result in unwanted transparency or incorrect color mapping. Use RGB 1, 1, 1 for black instead – it is nearly impossible for human eyes to discern:

While only black matters in OpenBOR, it’s a good rule of thumb to avoid border colors in any sprite engine:

  • RGB White 255, 255, 255
  • RGB Red 255, 0, 0
  • RGB Green 0, 255, 0
  • RGB Blue 0, 0 255
  • RGB Black 0, 0, 0

Using palettes

Once your sprites and palettes are ready, use the following commands to load them into your model and use them in game.

Palette

palette <path>

#default
palette <path to first frame>

The default palette (palette 0) for model. Accepts an image, an .act palette file, or none (see below). If you omit this command, OpenBOR will assign a model palette from the first frame of the first animation.

If none, there is no model level palette at all. Every sprite uses its own palette. Use this option carefully, as it increases memory use and disables any palette swapping for the model.

Alternate Palette

alternatepal <path>

#default
Not defined.

Loads an alternate palette. Use this command as many times as you like to add multiple color options for the model (palette 1, 2, …). Otherwise identical to Palette.

Hidden Map

hmap <first> <last>

#default
Not defined.

If defined, hides palette indexes first through last from player selection. Use this when you want to add palettes for effects like freezing or burning that you don’t want the able player to choose.

Special Indexes

Special indexes are a set of predefined IDs you can assign a palette index. You may then reference these indexes by name in attack boxes. For example, if an entity with palette.burn.index 2 is hit with an attack that contains attack.map.index burn, the entity switches to palette 2.

Unless otherwise noted they are only applied when deliberately referenced (i.e Burn attacks don’t trigger burn palette without an attack.map.index)

  • palette.burn.index
  • palette.freeze.index – Applied automatically when entity is hit by attack with freeze effect.
  • palette.ko.index – Applied automatically when entity is defeated depending on ko.type.
  • palette.ko.type – When to apply ko palette.
    • “instant” – Palette applies as soon as entity takes a killing blow.
    • “finish” – Palette applies when entity completes death or fall animation after defeat.
  • palette.shock.index

Global Map

globalmap <binary>

#default
globalmap 0

Allows entities spawned form model to use the global palette used for backgrounds. Not recommended unless you really know what you are doing. Uses might include entities that are part of the scenery and level palette switching is in use (see below).

  • 0 – Entity has independent palette.
  • 1 – Entity uses global palette.

Global Palettes

Stage objects (background, layers, panels, and entities with globalmap enabled) share a global 256 color palette. The global palette is normally taken from the current background image, meaning each level may have its own palette. You may also load additional palettes for use by script or the level palette command.

Optionally, layers may have independent palettes. This is done automatically if a layer image uses a different palette than the background image.

palette <path> <a1> <a2> <a3> <a4> <a5> <a6>

Level header command. Loads an alternate global palette.

  • path – The path to an image file or an .act palette file.
  • a1 – If true (1), enable optional alpha 1 transparency for layers. Costs 384 bytes of memory.
  • a2 thru a6 – Identical to a1, except for Alpha modes 2 thru 6 respectively.

Setpalette

Setpalette <index>

Level design command (see level design). Switch global palette to index.

Script

Colorset

mixed x = get_colorset_property(void <colorset object>, int <identifier>); 
mixed x = <value>;

set_colorset_property(void <colorset object>, int <identifier>, x);

Colorset is a group of properties that house the colorset references and configuration properties an entity uses to switch palettes. Colorset properties are accessible through the get_colorset_property() and set_colorset_property() functions.

ConstantTypeDescription
COLORSET_PROPERTY_BURNIntegerBurn palette index.
COLORSET_PROPERTY_FROZENIntegerFreeze palette index.
COLORSET_PROPERTY_HIDE_ENDIntegerLast palette hidden from player selection.
COLORSET_PROPERTY_HIDE_STARTIntegerFirst palette hidden from player selection.
COLORSET_PROPERTY_KOIntegerKO palette index.
COLORSET_PROPERTY_KO_CONFIGInteger* openborconstant(“KO_COLORSET_CONFIG_INSTANT”) – Assume KO palette immediately on defeat (0 hitpoints).

* openborconstant(“KO_COLORSET_CONFIG_INSTANT”) – Assume KO palette after death animation completes.
COLORSET_PROPERTY_SHOCKIntegerShock palette index.
ConstantTypeDescription

Palette Property

int color = get_palette_property(void <palette>, int <color index>, int <color component>);

set_palette_property(void <palette>, int <color index>, int <color component>, int <value>);

Get or set the individual component values of a palette entry.

  • Palette: Pointer to a palette.
  • Color Index: The position in palette to get or edit. For example, to get the fifth color, you would pass 4 for the color index.
  • Color Component: The property to access. See table.
ConstantTypeDescription
openborconstant("COLOR_COMPONENT_ALPHA")IntegerAlpha color component. Currently this is unused and does nothing at all.
openborconstant("COLOR_COMPONENT_BLUE")IntegerBlue color component.
openborconstant("COLOR_COMPONENT_GREEN")IntegerGreen color component.
openborconstant("COLOR_COMPONENT_RED")IntegerRed color component.
ConstantTypeDescription

This example gets the green value of the 20th color table entry.

void palette = {some table pointer};

int color = get_palette_property(palette, 19, openborconstant("COLOR_COMPONENT_GREEN"));

This example sets the 16th color table entry to pure red.

void palette = <some table pointer>;

set_palette_property(palette, 15, openborconstant("COLOR_COMPONENT_RED"), 255);
set_palette_property(palette, 15, openborconstant("COLOR_COMPONENT_GREEN"), 0);
set_palette_property(palette, 15, openborconstant("COLOR_COMPONENT_BLUE"), 0);

Tips:

  • There’s no native “default” for color table values in memory, but if desired you can make one using the palette copy, load, and create functions.
  • Native color tables exist at the model level, not the entity level. IOW, any changes made to a palette affect all entities from that model and palette. However, nothing stops you from pointing a single entity to your own “mixer” palette.
  • If you want to make a persistent palette edit, try saving palette data to to a table using Filestreams.

Copy Palette

int result = copy_palette(void <target palette>, void <source palette>);

Accepts pointers for target and source palettes. Copies (overwrites) all RGBA data to target from source. Returns 1 (success) or 0 (failure).

Load Palette

int result = load_palette(void <target palette>, char <path>);

Accepts pointer to target palette and path for palette file in pack data. Copies (overwrites) all RGBA data to target from the source file. Source may be an .act or 8bit .png file. Returns 1 (success) or 0 (failure).

Tip: It is advisable to keep any file reads outside of active gameplay.

Create Palette

void result = allocate_palette();

Creates a new blank (all values 0) palette in memory and returns the pointer.

Remove Palette

/* Allocate memory and create palette */
void result = allocate_palette();

/* Destroy palette and free the memory. */
free(result);

Use free(void <object>) to remove a palette from memory. Be careful you don’t delete a native palette or leave a dangling pointer.

Legacy

The following commands are depreciated and provided for documentation purposes only. Any erroneous results from using them are your responsibility.

Remap

remap <path 1> <path 2>

#default
Not used.

Create an alternate color set by remapping by pixels. Requires two identical images with identical palettes that are then color swapped by pixel. Path 1 is the default color set, path 2 is the new alternate. Note this means that not only must all the model’s sprites conform to a single palette, that palette must also include the colors for every remap you wish to create.

Komap

komap <index> <type>

#default
Not used.
  • index – Same as palette.ko.index.
  • type – Same as palette.ko.type.

Fmap

fmap <index>

Same as palette.freeze.index.

Related Post