Tokens can be used to introduce different colours in almost any element in the game.

See the nwnlexicon tutorial on custom tokens for more information.

Colour Custom Tokens

A subset of custom tokens - you can use <cRGB></c> where RGB is a RGB code but, of course since this isn't simple, it's not in number form but ASCII character reference...very odd (smile)

This means you can use a long ASCII string to find the right "number", eg;

const string COLOR_TOKEN = "                  ##################$%&'()*+,-./0123456789:;;==?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[[]^_`abcdefghijklmnopqrstuvwxyz{|}~~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¡¢£¤¥¦§¨©ª«¬¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþþ";

string GetStringColoredRGB(string sString, int nRed=255, int nGreen=255, int nBlue=255)
{
    return "<c" + GetSubString(COLOR_TOKEN, nRed, 1) + GetSubString(COLOR_TOKEN, nGreen, 1) + GetSubString(COLOR_TOKEN, nBlue, 1) + ">" + sString + "</c>";
}

This function can make a complete string that then could be passed, say, to a custom token for inclusion in a conversation. It can also be used in other text locations (eg; SpeakString, SendMessageToPC, etc.)

A simpler version is available in x0_i0_string.nss

The game uses the <cRGB></c> format internally so it can be used by modders to create any coloured text.

If you want to add these tokens directly into a TLK file you can use webpages such as this: https://colortoken.nwn1.net/

For more information on colour tokens in general see: https://neverwintervault.org/project/nwn1/other/hitchhikers-guide-color-tokens

You can find a more advanced set of scripts for color tokens here: https://github.com/silm/silm/blob/master/mod/nss/includes/inc_colors.n

Having Custom Colour Tokens in Conversations, Journals, and Descriptions

To have a <cXXX> code in a conversation/journal/description you can't input it directly. Instead you need to wrap it in a <CUSTOMXXX> token. To do this have a script like this in the OnModuleLoad:

const string COLOR_TOKEN = "                  ##################$%&'()*+,-./0123456789:;;==?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[[]^_`abcdefghijklmnopqrstuvwxyz{|}~~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¡¢£¤¥¦§¨©ª«¬¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþþ";

string GetRGBCToken(int nRed=255, int nGreen=255, int nBlue=255)
{
    return "<c" + GetSubString(COLOR_TOKEN, nRed, 1) + GetSubString(COLOR_TOKEN, nGreen, 1) + GetSubString(COLOR_TOKEN, nBlue, 1) + ">";
}
 
void main()
{
    SetCustomToken(1000, "</c>");
    SetCustomToken(1001, GetRGBCToken(255, 0, 0));
    SetCustomToken(1002, GetRGBCToken(0, 255, 0));
    SetCustomToken(1003, GetRGBCToken(0, 0, 255));
}

Then in the conversation editor you can do this:

<CUSTOM1001>Hello in red.<CUSTOM1000> Normal text. <CUSTOM1002>Hello in green.<CUSTOM1000> Normal text. <CUSTOM1003>Hello in blue.<CUSTOM1000> Normal Text. <CUSTOM1004>Hello in black.<CUSTOM1000> Normal Text. <CUSTOM1005>Hello in white.<CUSTOM1000>

Ending up like this:

This can be some good code to use for manually doing it (to be updated with a better code when newer patch comes out + some idea about default colours is obtained):

// OnModuleLoad
void main()
{
    SetCustomToken(1000, "</c>"); // CLOSE tag
    SetCustomToken(1001, "<cþ  >"); // red
    SetCustomToken(1002, "<c þ >"); // green
    SetCustomToken(1003, "<c  þ>"); // blue
    SetCustomToken(1004, "<c þþ>"); // cyan
    SetCustomToken(1005, "<cþ þ>"); // magenta
    SetCustomToken(1006, "<cþþ >"); // yellow
    SetCustomToken(1007, "<c   >"); // black
    SetCustomToken(1008, "<c¥  >"); // dark red
    SetCustomToken(1009, "<c ¥ >"); // dark green
    SetCustomToken(1010, "<c  ¥>"); // dark blue
    SetCustomToken(1011, "<c ¥¥>"); // dark cyan
    SetCustomToken(1012, "<c¥ ¥>"); // dark magenta
    SetCustomToken(1013, "<c¥¥ >"); // dark yellow
    SetCustomToken(1014, "<c¥¥¥>"); // grey
    SetCustomToken(1017, "<cŒŒŒ>"); // dark grey
    SetCustomToken(1015, "<cþ¥ >"); // orange
    SetCustomToken(1016, "<cþŒ >"); // dark orange
    SetCustomToken(1017, "<cÚ¥#>"); // brown
    SetCustomToken(1018, "<c† >"); // dark brown
}

Custom Damage Example

You can use a mixture of SetTlkOverride and SetCustomToken to make something like custom damage, eg reusing "Divine" damage since it is generally unresisted can give this:

With this in an OnUsed event of a lever:

void main()
{
    SetCustomToken(100, "</c>");
    SetCustomToken(101, "<cÿ´ô>");
    SetTlkOverride(5593, "<CUSTOM100><CUSTOM101><CUSTOM0> Something Painful");
    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(1, DAMAGE_TYPE_DIVINE), GetLastUsedBy());
    // Reset so usual divine damage looks ok (or go replace divine damage in all scripts with positive damage or something).
    SetTlkOverride(5593, "");
}

You might want Hardcoded TLK Lines to reference some of the games TLK references to override.

Ordering Lists

Anything that orders on the contents of a string - eg the feats or skills in a character sheet - can be made into a custom order using empty colour strings, eg:

<c0000></c>Feat Section 1
<c0001></c>Feat 1
<c0001></c>Feat 4
<c0001></c>Feat 6
<c0002></c>Feat Section 2
<c0003></c>Feat 2
<c0003></c>Feat 3
<c0003></c>Feat 5

Without the colour codes you will get the order "Feat 1, 2, 3, 4, 5, 6 Section 1, Section 2" but with them you get "Feat Section 1, 1, 4, 6, Section 2, 2, 3, 5"