# How Pigmentation Works

The pigmentation system uses a combination of five factors to alter the colours of creatures and any agents in the world.

These factors are Red Tint, Green Tint, Blue Tint, Colour Rotation and Red/Blue Swap.

The Tint factors will specify the RGB colour of the agent only if used on a grey background (128,128,128), otherwise they act by darkening and lightening the specific colour channels of the agent.

If tint has a value of 128 then the colour will remain unchanged.
A tint of more than 128 will lighten that channel by the amount over 128 it is. For example, a Red Tint of 138 will lighten the red channel by 10.
A tint of less than 128 will darken that channel by the amount under 128 it is.

Rotation moves the colours on an imaginary colour wheel.
A value of 128 means 'do not rotate' and leave the colour as it is.
For rotation values greater than 128 the colour wheel is rotated in the direction R->G->B.
Rotation values less than 128 rotate the colour wheel in the direction R->B->G

Swap works on the Red and Blue channels by allowing you to specify an amount of swap that occurs between these two.
A value of 128 means 'do not swap' and will leave the colour as it is.
A swap value of less than 128 makes the colour more red.
A swap value of greater than 128 makes the colour more blue.

For those of you who like to see the specifics, here's the scheme presented as pseudo-code:

```define proc Bound(value)
if (value < 0) value = 0
if (value > 255) value = 255

define proc Tint(red,green,blue,rotation,swap)
if (red == green == blue == rotation == swap == 128)
return defaultcolours
endif

if rotation >= 128
absRot = rotation-128
else
absRot = 128 - rotation
endif
invRot = 127-absRot

if swap >= 128
absSwap = swap - 128
else
absSwap = 128 - swap
endif
invSwap = 127-absSwap

redTint = red-128
greenTint = green-128
blueTint = blue-128

foreach colour in 16bit colour table excluding 0,0,0
tempRed = RedValue + redTint;
tempGreen = GreenValue + greenTint;
tempBlue = BlueValue + blueTint;

Bound(tempRed)
Bound(tempGreen)
Bound(tempBlue)

if (rotation < 128)
rotRed = ((absRot * tempBlue) + (invRot * tempRed)) / 256
rotGreen = ((absRot * tempRed) + (invRot * tempGreen)) / 256
rotBlue = ((absRot * tempGreen) + (invRot * tempBlue)) / 256
endif
swappedRed = ((absSwap * rotBlue) + (invSwap * rotRed))/256
swappedBlue = ((absSwap * rotRed) + (invSwap * rotBlue))/256

SetColour(definedcolour to (swappedRed,rotGreen,swappedBlue))
if definedcolour ==0 SetColour(definedcolour to (1,1,1))
next

endproc
```