Articles on: Scripts

Advanced Lorebook — by Icehellionx

Advanced Lorebook

— by Icehellionx


⚠️The Advanced Lorebook script is a derivative of the original Advanced Lorebook script that was used during testing. This script is kept as a legacy option in case someone is brave enough to fork it and create a new variant!


Icehellionx's v2 version of this script includes guardrails and extra features.




/**

* Advanced Lore Book System
* Fixed by Icehellionx
* Character reveals backstory and world knowledge based on keywords
*/
var forever = 9999;
// 🟢🟢🟢 Your Lore Entries 🟢🟢🟢
var dynamicLore = [
// 🛑🛑🛑 DO NOT EDIT ABOVE THIS LINE 🛑🛑🛑

// === Fantasy/Magic lore ===
{
keywords: ['magic', 'spell', 'wizard'],
minMessages: 0,
maxMessages: forever,
priority: 10,
probability: 0.5,
personality: ', knowledgeable about magical arts and ancient spells',
scenario: ' {{char}} has studied magic for years and can sense magical energies around them.',
triggers: ['knowledge', 'study', 'monster']
},
{
keywords: ['dragon', 'beast', 'monster'],
minMessages: 0,
maxMessages: forever,
priority: 10,
probability: 1,
personality: ', experienced with dangerous creatures and their behaviors',
scenario: ' {{char}} has encountered many mythical beasts and knows their weaknesses.'
},

// === Historical/Background lore ===
{
keywords: ['war', 'battle', 'soldier'],
minMessages: 0,
maxMessages: forever,
priority: 10,
probability: 1,
personality: ', haunted by memories of past conflicts',
scenario: ' {{char}} served in the Great War and bears both visible and invisible scars.',
triggers: ['war', 'battle']
},
{
keywords: ['family', 'parent', 'childhood'],
minMessages: 0,
maxMessages: forever,
priority: 10,
probability: 1,
personality: ', shaped by a complex family history',
scenario: ' {{char}} grew up in a noble house but left to forge their own path.'
},

// === Location/World lore ===
{
keywords: ['forest', 'woods', 'tree'],
minMessages: 0,
maxMessages: forever,
priority: 10,
probability: 1,
personality: ', deeply connected to nature and forest spirits',
scenario: ' {{char}} spent their youth in the Whispering Woods, learning druidic ways.'
},
{
keywords: ['city', 'town', 'street'],
minMessages: 0,
maxMessages: forever,
priority: 10,
probability: 1,
personality: ', street-smart and familiar with urban politics',
scenario: ' {{char}} knows every alley and hidden passage in the capital city.',
triggers: ['street', 'alley']
},

// === Profession/Skill lore ===
{
keywords: ['sword', 'fight', 'weapon'],
minMessages: 0,
maxMessages: forever,
priority: 10,
probability: 1,
personality: ', disciplined in the ancient fighting arts',
scenario: ' {{char}} trained under Master Korin, learning the Seven Sacred Stances.'
},
{
keywords: ['book', 'knowledge', 'study'],
minMessages: 0,
maxMessages: forever,
priority: 10,
probability: 1,
personality: ', scholarly and well-versed in ancient texts',
scenario: ' {{char}} spent decades in the Great Library, mastering forbidden knowledge.',
triggers: ['knowledge', 'study']
},

// === Mysterious/Secret lore (Timing Tested) ===
{
keywords: ['secret', 'hidden', 'truth'],
minMessages: 0,
maxMessages: 15,
priority: 10,
probability: 1,
personality: ', keeper of ancient secrets is a myth',
scenario: ' {{char}} knows the truth about the Sundering, but will not speak about it.'
},
{
keywords: ['secret', 'hidden', 'truth'],
minMessages: 16,
maxMessages: 30,
priority: 10,
probability: 1,
personality: ', keeper of ancient secrets that could change everything',
scenario: ' {{char}} knows the truth about the Sundering, but speaks of it only in whispers.'
}
// 🛑🛑🛑 DO NOT EDIT BEYOND THIS LINE 🛑🛑🛑
];

var lastMessage = context.chat.last_message.toLowerCase();
var messageCount = context.chat.message_count;
var activatedEntries = [];
var triggeredKeywords = [];

// === First Pass: Find direct matches and triggers ===
for (var i = 0; i < dynamicLore.length; i++) {
var entry = dynamicLore[i];
var hasKeyword = false;

if (messageCount >= entry.minMessages && messageCount <= entry.maxMessages) {
if (entry.probability && Math.random() > entry.probability) {
continue;
}

for (var j = 0; j < entry.keywords.length; j++) {
if (lastMessage.includes(entry.keywords[j])) {
hasKeyword = true;
break;
}
}

if (hasKeyword) {
// Add the entry to our list of activated lore
activatedEntries.push(entry);
// If the entry has triggers, add them to a list for the second pass
if (entry.triggers) {
for (var k = 0; k < entry.triggers.length; k++) {
triggeredKeywords.push(entry.triggers[k]);
}
}
}
}
}

// === Second Pass: Find entries activated by triggers ===
if (triggeredKeywords.length > 0) {
for (var i = 0; i < dynamicLore.length; i++) {
var entry = dynamicLore[i];
var isTriggered = false;

// Skip entries that were already directly matched
var isAlreadyActivated = false;
for (var l = 0; l < activatedEntries.length; l++) {
if (activatedEntries[l] === entry) {
isAlreadyActivated = true;
break;
}
}
if (isAlreadyActivated) {
continue;
}

// Check if any of the entry's keywords match the triggered keywords list
for (var j = 0; j < entry.keywords.length; j++) {
for (var k = 0; k < triggeredKeywords.length; k++) {
if (entry.keywords[j] === triggeredKeywords[k]) {
isTriggered = true;
break;
}
}
if (isTriggered) {
break;
}
}

if (isTriggered) {
// Re-run the filter checks for the triggered entry
if (messageCount >= entry.minMessages && messageCount <= entry.maxMessages) {
if (entry.probability && Math.random() > entry.probability) {
continue;
}
activatedEntries.push(entry);
}
}
}
}

// === Final Pass: Sort by priority and apply lore ===
if (activatedEntries.length > 0) {
activatedEntries.sort(function(a, b) {
return b.priority - a.priority;
});

for (var m = 0; m < activatedEntries.length; m++) {
var entryToApply = activatedEntries[m];
if (entryToApply.personality) {
context.character.personality += "\n\n" + entryToApply.personality;
}
if (entryToApply.scenario) {
context.character.scenario += "\n\n" + entryToApply.scenario;
}
}
}

Updated on: 06/09/2025

Was this article helpful?

Share your feedback

Cancel

Thank you!