KCD Storm Documentation
- 1 Installation and setup
- 2 Description
- 3 General Controls
- 4 Operation Mode
- 5 Input XML
- 6 Further usage
- 7 Rule-files
- 7.1 Selectors
- 7.2 Operation
Installation and setup
Before you can execute any function, the tool requires:
- Properly set up DB.
- Select an existing DB scheme
- Properly set Input XML file in correct format
The purpose of Storm is to support and execute vast but easily manageable set of rules which setup various game-critical data on NPC souls. That is roles, schedules, stats, characters etc.
Pressing the key indicated in the [square brackets] execute the listed function.
Beware of overwrites! Files and rules are interpreted and executed in the order listed in the definition files. If any two rules affect the same property the last rule overwrites the previous one.
You can switch between additive and generative mode.
Additive mode – only adds new entries in to the DB. Is faster but is incapable for deleting entries.
Generative mode – rebuilds all relevant DB tables. Is slower.
By pressing [i] you can find the path to the input XML. This is a mandatory setting and the tool remembers it.
Storm files can be stored anywhere but normally they are stored under ../Data/Libs/storm and respective subfolders. It is recommended that the subfolder reflect the naming and structure of tasks as defined in Input XML files.
Example: all quest-related role rules should go under ../Data/Libs/storm/roles/quests while the task group is simply named roles and handles all rules under ../Data/Libs/storm/roles and its subfolder.
XML input file does not contain any rules. It is a simple XML file which contains paths to all other files that contain the actual rules. The file structure must be as follows:
<common> //any globally applicable rules. They are always executed by storm
//any number of files with global rules .. .. </common>
<task name="..." class="..."> //groups tasks of similar nature. For example roles, schedules etc. Enables storm to execute only this particular group of rules. The tool does not support subtasks. “Class” defines the name of this task group.
//any number of files (rule-files) containing rules of this group’s nature .. .. </task>
You can create custom classes but you should have the need. Standard task groups (classes) are:
- abilities – contain rules which set up stats and skills to souls
- characters – contain rules which set up characters to souls. Used mainly for generic NPCs as custom-named NPCs have their character set in Swift
- hobbies – contain rules which set up hobbies (for FUN manager) to souls
- names – contain rules which override UI names of NPCs which are normally determined by character. Example: shop guard have random generic guard characters but their names are overridden to spell “Shop Guard”
- reputations – contain rules which override reputations of NPCs towards player which are normally determined by faction setting. Example: Skalitz people from game intro have reputation of 0.5, but Henry’s father is set to 1, the highest possible.
- roles – contain rules which set up roles and metaroles to souls
- schedules - contain rules which set up daycycle schedules to souls
If you specified the DB branch and Input XML, Storm allows you to perform any singular task.
- Confirm settings by pressing [a]
- If all went well, you can choose any listed option. Press [r] to access list of tasks.
- Select a task for evaluation. Storm will check the results of the rules in this task against DB data and will list the resulting changes. You can commit these changes to DB by pressing [c] or discard them with [d]
This usage is reserved for testing purposes when you need to make some quick changes.
Storm is also used by the data builder. This execution runs all the tasks in generative mode will overwrite anything you have changed manually in DB or by using Storm as described above.
A rule-file is a simple XML file which contains rules that you want to apply. A rule-file will be executed when it’s properly included in the Input XML file.
A rules-file can contain any number of rules.
A rule consist of two parts – soul selection, and operations.
Selection utilizes selectors. Selectors are a set of constraints which select the proper set of souls to be affected. Selection section can hold any number of selectors (the default operation is AND and is implicit).
Operations section can hold any number of operations which are applied to the selected souls one by another.
The basic rule-file structure must be as follows:
<!DOCTYPE storm SYSTEM "!storm.dtd">
<rule name="... "> //name which is unique in the scope of this file
TRUE for soul with set character.
TRUE for soul with set faction.
TRUE for soul with any valid hobby.
<hasAttribute stat="vision" minValue="8" maxValue="12" />
<hasAttribute skill="weapon_sword" minValue="8" maxValue="12" />
TRUE for soul within specified value boundaries in the specified stat or skill. You can use minValue without maxValue and vice versa.
Skills and stat value range from 0 to 20.
See DB tables “soul” and “skill”. NOTE: DB table “stat” lists only stats which are visible in game UI.
<hasCombatLevel min="2" max="3" />
<hasCombatLevel value="1" />
TRUE for souls with combat level within specified boundaries of equal to value.
Combat level ranges from 0 to 6.
<hasFaction ID="1" />
TRUE for souls belonging to specified faction ID ( see Db table “faction”).
<hasGender ID="1" />
<hasGender name="male" />
TRUE for souls with specified gender (see DB table “gender”).
<hasHobby ID="1" />
<hasHobby name="repairFence" />
TRUE for souls with specified hobby (see DB table “gender”).
<hasLocation name="location_Sazava" />
TRUE for souls belonging to a faction which is linked to the specified location.
<hasName name="regexp" />
TRUE for souls whose name matches the specified regular expression.
<hasNameNumberModulo divisor="3" result="1" />
Soul names of more generic NPCs are usually numbered – bandit1, bandit2 etc. This selector takes that number, applies modulo, and if the result of this operation matches the specified result value, the soul is selected. Good for selecting every other NPC from a name-group.
<hasPerk ID="1" />
<hasPerk name="perk" />
TRUE for souls which have the specified perk (see DB table “perk”).
<hasRandomValue min="0.2" max="0.5" />
Each soul is dynamically assigned a random value. TRUE for souls which happen to have the value within specified boundaries.
<hasRole ID="1" />
<hasRole name="HENRY" />
TRUE for souls with specified role.
<hasScheduleItemCount minCount="2" maxCount="5" />
TRUE for souls whose count of “activities” in their daycycle schedule is within specified boundaries.
TRUE for souls with a shop. This is specified in DB table “shopkeeper”
<hasSocialClass ID="1" />
<hasSocialClass name="townsman" />
TRUE for souls with specified Social Class.
<hasSoulCrimeRole ID="1" />
<hasSoulCrimeRole name="soldier" />
TRUE for souls with specified crime role.
<hasSuperfaction ID="1" />
<hasSuperfaction name="Civilians" />
TRUE for souls with specified superfaction.
<hasVoice ID="1" />
<hasVoice name="chrisClarke" />
TRUE for souls with specified Voice. (name is from voice_technical_name in DB table “voice”)
You take any number of selectors and combine them using logical operations – AND, OR, XOR, NOT
<hasGender name="male" />
<hasRole name="HENRY" />
Selects all souls which have a shop OR are males but do NOT have the role HENRY.
You can simplify repeated usage by defining a new custom selector and specifying its name.
A simple custom selector is created like this:
<hasGender gender="male" />
You can then use this custom selector in any rule.
A custom composite selector containing more selectors requires specification of “mode” which defines the logical operation. This means that one custom selector can handle only one logical operation. Examples:
<customSelector name="isFromNorthWest" mode="or">
<hasName name="tal_.*" />
<hasName name="mrh_.*" />
<hasName name="sam_.*" />
TRUE for any soul whose name begins with prefix tal_, mrh_, or sam_.
<customSelector name="isNotTest" mode="and">
TRUE for any soul who is a male and has a shop.
Custom operations can be defined similarly to custom selectors.
<addRole name="SMLOUVANI_(MUZ)" />
<addRole name="BRIBE" />
<addMetarole name="BRIBE" />
Adds a set of roles required for the NPC to be bribe-able.
<addPerk ID="1" />
<addPerk name="perkName" />
Adds a specified perk to the soul (see DB table “perk”)
<removePerk ID="1" />
<autolearnPerks reliability="1" />
Add all perks to the soul which have the flag “autolearnable” set in DB for which the soul has high enough skill/stat requirements.
<setAttribute stat="stat" value="10" />
<setAttribute stat="stat" minValue="10" maxValue="12" />
<setAttribute skill="skill" value="10" />
<setAttribute skill="skill" minValue="10" maxValue="12" />
Sets a skill or stat to exact value or a random value within specified boundaries.
See DB tables “soul” and “skill”. NOTE: DB table “stat” lists only stats which are visible in game UI
For the list of stats see hasAttribute selector
<modAttribute stat="stat" mod="2" />
<modAttribute stat="stat" minMod="-2" maxMod="4" />
<modAttribute skill="skill" mod="2" />
<modAttribute skill="skill" minMod="-2" maxMod="4" />
Takes the actual value of the stat or skill and modifies it by adding or subtracting a specified value or a random value within specified boundaries. NOTE: you can get out of valid value range!
<clampAttribute stat="stat" minValue="0" maxValue="20" />
<clampAttribute skill="skill" minValue="0" maxValue="20" />
Clamps the specified attribute.
<removeSkill ID="1" />
<removeSkill name="skillName" />
Removes specified skill.
<setGenericCharacterNamePattern pattern="GENERIC_MAN_.*" />
Generic like sas_guard1, sas_guard2 etc. need some character to have a voice. A set of GENERIC CHARACTERS (GENERIC_GUARD1, GENERIC_GUARD2) were created for this purpose. There is always higher number of generic souls than generic characters. This operations assigns any character that fits the regular expression.
The characters Storm task does this in the end:
1) Storm takes all the souls which should be affected
2) Storm assigns these souls into location-determined clusters (locations is taken from faction setting)
3) Storm assigns the characters (which define voices) to these souls in such a way that voices are as evenly distributed as possible.
<addHobby ID="1" mass="10" />
<addHobby name="hobbyName" mass="10" />
Assigns a hobby with specified priority to the soul. The name attribute value is taken from hobby_pretty_name column from DB table hobby
<removeHobby ID="1" />
<removeHobby name="hobbyName" />
Removes the specified hobby.
Removes all hobbies
<setiName ID="1" />
<setiName name="bandit" />
Overrides NPC’s UI name by setting it to a string from the DB table “soul_ui_name”. Normally the UI name of a NPC is determined by character.
Sets individual reputation to its faction’s reputation. If the souls doesn’t have a faction it will cause an error!
<setReputation reputation="0.5" />
Set individual reputation to specified value. Value ranges from -1 to 1.
<addRole ID="1" />
<addRole name="ROLE_NAME" />
Assigns specified role to the soul.
<removeRole ID="1" />
<removeRole name=" ROLE_NAME " />
Removes specified role from the soul.
Removes all roles from the soul.
<addMetarole ID="1" />
<addMetarole name="METAROLE_NAME" />
Adds specified metarole to the soul.
<removeMetarole ID="1" />
<removeMetarole name="METAROLE_NAME" />
Removes specified metarole to the soul.
Removes all metaroles for which the souls has no roles.
<addScheduleItem start="06:30" scatter="00:30" activity="dota" />
Adds an activity to soul’s daycycle schedule from specified time onwards. Optional scatter attribute randomizes the start time by specified +- value.
Clears the souls daycycle schedule. Cleared daycycle schedule defaults to dummyWait (=stay in idle) behavior for the entire day.
<removeScheduleActivity activity="work" />
Removes all instances of specified daycycle activity from the daycycle schedule.