A summary of what we germans learned so far about Drakensang-Modding
This is kinda lengthy, use it as a tutorial, trying to read that whole posting at once may cause insanity.
1. The Files
- Everything but graphics and sound can be found within two files: static.db4 and locale.db4 in the folder Drakensang\export\db\
Those files are standard SQLite databases, we use the SQLite Browser to view/edit them. And a commandline SQLite tool and a batchfile to hand on mods to users and install them on their PCs. (Feel free to dissect any of my mods to see how things are done and take from them whatever you need for your own mods, no need to ask.)
LOCALE.DB4 contains the text, and only text. Makes translation quick and easy.
STATIC.DB4 contains all game Data, Items, Archetypes, Scripts, Dialogues (sans actual text) you name it, you'll find it there.
GAME.DB4 is a bit mystic, we assume it is just a template used to create savegames, it has basically the _Template* tabs from Statics.db4, renamed to _Instance*. Changes in Static.DB4 override these default settings so modders don't need to worry too much about this file.
*.DSA files in the savegames in the My Documents folders are SQLite databases as well. Actually they are modifications of game.db4. Thus the savegames reflect structures from static.db4, this means many things you can realize as a permanent mod in static.db4 can also be done just as savegame-modification in the savegame.dsa
Art resources can be found in the *.NPK files within the drakensang main folder, the NPKs (Nebula Package) are similar to Bioware's HAKs or ERF files.
There is a tool to extract those files in the Nebula2 SDK. I've put the tool in a separate download: NPK-Unpacker just start the batch-file to extract all the NPKs in a new folder.
The Drakensang\export folder works like Bioware's override, simply put a modified file from the extracted NPK into the same directory structure within Drakensang export, and Drakensang will use it.
2. The Tools
- SQLite Browser - The essential modding tool to view and edit the databases.
http://sourceforge.net/projects/sqlitebrowser/ - SQLite3 Commandline Tool - Required to install your mod on the user's PC
http://www.sqlite.org/download.html - NPK-Unpacker - Essential to anything art-related.
http://nebuladevice.cubik.org/ - The full Nebula2 SDK
http://mods.jo-ge.net/dsa4/dl/nnpktool.zip - Just the NPK-Tool - N2Tool The tool for extraction and modification of N2-Files
http://mods.jo-ge.net/dsa4/afdz/n2tool.zip - Drakensang Blob Tool - Useful for advanced modding (unless you like byte-swapping and using hex-editors) http://mods.jo-ge.net/dsa4/dl/blobtool.exe
- A good text editor
PFE - Small and Functional
http://www.lancs.ac.uk/staff/steveb/cpaap/pfe/
or Emacs - versatility incarnate (complexity too)
http://www.gnu.org/software/emacs/
3. Modifying Art
General Info
- Textures are DDS. These files can be opened with Photoshop and Gimp with the right plugins. (Anyone didn't know?)
- NS files link animations textures and meshes and are created by an exporter plugin for Maya there is no alternative, so I think creating new models is out of question.
- The NPKs contain a lot of junk from development that is no longer used by the finished game. Don't let them fool you. Modifying the single NS files in the Mensch_F folder for example has no effect, Drakensang only uses the combined Mensch_F.NS
Texture-replacing, GUI-changes
- Textures usually have a name similar to the object-name used in static.db4, so look for the original object first, to learn the texture's name.
- Once you've extracted the NPK-Files, and modified some of the textures, simply put the modified file into the same sub-folder structure within Drakensang\export, and it will work like Bioware's Override folder.
- For example my No Map Marker Mod simply consists of two dds files that when put into Drakensang\export\textures\map will remove the quest-location markers from the map.
New models (e.g. new or retextured armor in addition to existing ones)
- While weapons are in separate N2-files, models for armor etc. are organised by N2-collections that can be found in the export\gfxlib\characters\ folder. Player-characters for example use the files female.n2, male.n2 and dwarf.n2.
- N2-Dateien link meshes, animations and textures. Using the N2Tool one can ad new entries that point to different textures.
- For this you need to copy an extracted version of the respective N2-collection-files to the folder export\gfxlib\characters (if not already happened) The small separate N2 files from the sub folders of the "characters" folder aren't used by the game.
- For more see: [Tool] N2TOOL - Retexturing and more...
4. Database Modding
General Info
- First of all, make a backup of STATIC.DB4 and LOCALE.DB4, right now. You'll need it.
- Second, you can make your life much easier by first loading STATIC.DB4 into the SQLIte browser and then use File/Export/Database to SQL-File.
The file created is a plain text file, you should open it with emacs, PFE or a similar programmer's text editor that uses a fixed pitch font and does not reinterprete ASCII codes >128 as UTF8 and has no problem with large textfiles (i.e. DO NOT USE WINDOWS NOTEPAD)
This file is full of SQL commands that when executed will recreate Static.db4, We use it mainly as store for templates: you need a new weapon, simply search for Template_Weapon, pick any weapon, change the first entry ID and copy the entire line into the SQLite-Browsers "Execute SQL" prompt, click on Execute Query and you just made a new entry. Advanced modding also requires this file to search/copy the identificators (The blocks of binary-clutter are blobs (binary large object)) - Once you're done with your mod extract the database again, search the SQL-textfile for the lines that contain your changes and copy them into a static.sql file.
This file together with the sqlite commandline tool and the installation batch is all that is needed to install a mod. - For a documentation of the SQL-commands look here: http://www.sqlite.org/lang.html
- Do yourself a favor and make a clean sweep once your mod is finished. Restore the pre-modding backups and install your mod with the batch file, this way you may notice problems like forgotten lines before releasing the mod, and unintended changes you made for testing or by accident won't affect your game.
Item Modifications Part 1: Changing existing weapons (e.g. make all those daggers a bit better)
- Make up your mind about the item's category first then browse the templates (conveniently the names of the database tables are in english)
_Template_Weapons would be the table to change, just play with the values, the changes you make here are active at once for items in areas you haven't visited yet.
The other items (including merchant inventory) are stored in your savegame. ( _Instance_Weapon in this case.) You need to repeat the changes there
If your changes can be summarized with a simple algorithm (like "+1 damage for all daggers"), you can automatize them with a SQL-command entered in the SQLite-Browser's "Execute SQL" tab:- Code: Select all
UPDATE _Instance_Weapon set WpW6plus = WpW6plus +1 where TaAttr='TaDolche';
Character modifications (e.g. new archetypes or savegame editing)
(In savegames replace "_template" with "_instance", everything else is the same.)
- TDE has a couple of upper limits that are dependent on the character's starting abilities, to realize this, Drakensang has three identical tables that define the characters:
- _Template_PC contains the stats of your NPC companions when you first meet them. In Savegames the last entry of _Instance_PC is the player character.
The other two tables define the Archetypes:- _Template_Backup contains the character's base stats for the rules, those are the minimum stats when you choose to redistribute your skillpoints in chargen, and these values +3 +Level are the maximum value a skill or spell can ever have throughout the game (for Attributes and HP/AP the max is starting value +50%)
_Template_PC_CharWizard contains the default values the character has in Chargen, the difference between these values and the values in _Template_Backup are the skillpoints you can redistribute in the "Expert Mode"
_Template_PC and _Template_PC_CharWizard have additional columns that hold the inventory and quickslots. - To add new archetypes simply create a new line, If you did what I recommended above, just open your text file with the sql commands, search for _Template_PC_Charwizard select the entry of the character most similar to the one you want to create just change the ID (first entry) for now and copy the line and execute it in the SQL-Browser, repeat it with _TemplateBackup and start to change the new entries.
- Alternatively, you can modify an existing entry, and in the final stages of modding change the ID so that it will be added from the SQL file.
- If you forget to change the first entry (ID) you won't get a new archetype but modify the existing one.
- The Archetype ID can be used to enforce a new 3-character page in the Char-Selection (like the switch from Thorwalians to Amazon).
- There are separate archetypes for male and female characters, so you can make a strong male and a wise female or make them completely different.
To add another dwarf/zwerg, you first need to add a new archetype with both genders or your new dwarf won't appear in Chargen. Generally any single-gender archetype must be followed by two genders or there will be no new page in the archetype-selection. - A bug/oversight in the SQLite Browser prevents it from modifying the IN(tuition) column. Simply use SQL code in the Execute SQL tab to modify that entry:
- Code: Select all
UPDATE _Template_Backup SET 'IN'=14 WHERE rowid=5;
Item Modifications Part 2: New items (e.g. Characters that start the game with the vorpal dagger of vengeful slaying)
Once you made a new Archetype he may also need special gear...
- Create a new line in _Template_Weapons, _Template_Armor or whatever type of item you want to create. You know already the fastest way to do this. Modify the new item.
- Now go to _Template_PC_CharWizard. At about 15% to the right, you'll find the columns SetupStorage and SetupEquiped, there you can add your new item's id, items are separated by a semicolon here, just look how it was done for the original archetypes.
- You can also create just the new item save static.db4 and then open a savegame and add the item to your current character.
- Finally you can open _DSA_LootTables and add the item to chests or NPC inventories, problem is that most stuff is in german there...
Item Modifications Part 3: Magic items with new effects.
You want new magic item but the effect you have in mind doesn't exist yet? It should be quite simple for Radon Labs, not so simple for us, though..
- Have a look at _Template_Jewelry, there is a PermanentEffect column, this is where you can add a ST+1 Effect for a ring of strength.
- In _Template_Statuseffects you find the values you can use there. You can add a new value here give it a new name etc.
- _Scripts_StatusEffectScripts finally takes care of how the effect is realized. And the first thing you see is a mess of chars. Don't worry, your database isn't broken, these are blobs - binary data. Problem is, the SQLite Browser can't handle them correctly and tries to display them as UTF8.
These binary entries are called GUIDs, they are 128-Bit unique identifiers for lines in _Scripts_Statements. Best work with two SQLite Browsers open now, one shows _Scripts_StatusEffectScripts, the other _Scripts_Statements.
You can copy the binary entries and paste them into the search window of the SQL-Browser, but you need to search with "contains", since the binary data is crippled when you copy it.If it doesn't work try to delete a few chars. A more reliable way is described below, for now let's just see how things actually work. - Let's see how a Ring of Phex actually works.
- Ingame it adds DE+1 (FF+1 in german)
- Action - "what shall I do?"
- Begin - (Identificator of line 1's GUID)
- Action - "how shall I do it?"
- Begin - (Identificator of line 3's GUID)
- Code: Select all
ModifyAttribute modifier="FF +1" actionSelection="script";- Code: Select all
WaitAction duration="1" permanent="true" actionSelection="script";
Obviously it's in _Template_Jewelry, but no ring of Phex there... Modding needs some detective work after all...
How would a german developer call the ring alternatively? "ring_de" maybe, but he's german after all, so "ring_ff" Of course you could also look at your inventory in a savegame once you have one...
ring_ff has a PermanentEffect "PeFF1"
Now we open _Scripts_StatusEffectScripts and search the ID "PeFF1" which can be found in line 70.
Next we copy the contents of the field StatusEffectOnStartRef and use the search function to search _Scripts_Statements for a line that CONTAINS this in the StatementGUID.
Line 2551 is the right one, when you look at it now you see in StatementContent the other variant of a GUID-blob: hexadecimal data separated with dashes, which I'll call "Identificator" from now on.
This identificator points to the next line of code, which seems to be obsolete since this line is always the line above the one we just found, but given the structure of a SQL database you can't rely on this.
Better safe than sorry, RadonLab thought, as you can see, the StatementBlockGUID of Line 2551 and Line 2550 is identical, and this value is the value in StatusEffectOnStartBlock from _Scripts_StatusEffectScripts
StatusEffectOnTriggerRef and StatusEffectOnTriggerBlock in _Scripts_StatusEffectScripts point in the same way to lines 2552 and 2553.
script-statements always come as such a double-pair.
So now have a look at the StatementContent of Line 2550 (what shall I do?):
And line 2552 (how shall I do it?):
Plain and simple, this way you can use any column-name from _Template_Backup and add or subtract any value. - Action - "what shall I do?"
Okay, we know now how to change the Ring of Phex into a Ring of pickpocketing +20 but how can we add a completely new effect?
This is where the usability of the SQLite-Browser ends. When you try to change a field with binary data, the field's type will change from "blob" to "string" and Drakensang will crash.
Also, the Identificator in Line2 needs to be the correct GUID of Line1 or Drakensang will crash
Also, the links to the GUIDs in _Scripts_StatusEffectScripts need to be 100% correct or Drakensang will... I think you get it..
You need to work with SQL statements from now on. And you need to be able to convert the GUID-blobs into identificators
I won't go into details here about how the identificators are constructed, the explanation fills a full page in the german forum. Just get my Drakensang Blob Tool:

Download
Three variants of the same thing:
Identifikator (I'm not going to make an "english" version and just put a "c" in there) copy the Identificator "a34f80f1-acf2-4cea-9cbd-a08e9a51d3ba" from line 2551 and paste it into the Identifikator box of the Blob tool. The other boxes are updated automatically.
GUID-blob (HEX) The binary variant in hexadecimal notation which can be used by SQL-statements when put in X'' the Identificator from above corresponds to the GUID-blob X'F1804FA3F2ACEA4C9CBDA08E9A51D3BA'
GUID-blob (ANSI)The binary variant interpreted as ANSI characters, resulting in a mess of chars. Looks a bit different than in the SQLite Browser, and here there are always 16 chars... Copy the contents of this box and search for it in your SQL-text-file:
et violá: 'ModifyAttribute modifier="FF +1" actionSelection="script"; ' the converted identificator indeed points to the SQL-code that creates our line 2550
You also can go to the sqlite-browser, open the Execute SQL tab and enter
- Code: Select all
select rowid FROM _Scripts_Statements WHERE StatementGUID =X'F1804FA3F2ACEA4C9CBDA08E9A51D3BA'
So step-by-step now:
- You begin with creating an item and make up a new name for a StatusEffect
- Create a new entry in _Template_Statuseffects, of course you need the ingame-text as well.
- Create a new entry in _Scripts_StatusEffectScripts, use hex-notation and best only vary the Id's you're using in your mods by a few bytes, to make GUIDs you can remember use leetspeak - this is where it came from.
- Create the entries in _Scripts_Statements, for line 2 and 4 use the GUIDs defined in _Scripts_StatusEffectScripts. By now you should have a concept as of how the GUIDs of lines 1 and 3 should look like,
- Use the Blob-tool to convert the GUIDs to identificators and add them to Line 2 and 4
- Add your script into line 1 and make sure line 3 contains WaitAction duration="1" permanent="true" actionSelection="script"; (unless you want to try something different)
- That's about it, you have a new item with a new status effect and can add it to your character. If Drakensang crashes upon equipping the item, check and double-check the GUIIDs and Identificators.
For my mods I use this concept (only the last two bytes vary):
- Code: Select all
GUID of the entry in _Scripts_StatusEffectScripts: 4d445f5fAFFEDADA057A7E0DDD01FFFF
StatementBlockGUID of lines 1 and 2: 4d445f5fAFFEDADA057A7E0DDD0101FF
GUID of Line 1 _Scripts_Statements ("Action"): 4d445f5fAFFEDADA057A7E0DDD01010A
GUID of Line 2 _Scripts_Statements ("Begin"): 4d445f5fAFFEDADA057A7E0DDD01010B
StatementBlockGUID of lines 3 and 4: 4d445f5fAFFEDADA057A7E0DDD0102FF
GUID of Line 3 _Scripts_Statements ("Action"): 4d445f5fAFFEDADA057A7E0DDD01020A
GUID of Line 4 _Scripts_Statements ("Begin"): 4d445f5fAFFEDADA057A7E0DDD01020B
Finding and modifying dialogue scripts. (i.e. "Hey you're a cute one! Here, have a priceless artifact.")
That artifact you just created may be too powerful to put them into an archetype's equipment and editing savegames is lame. So let's get our new item as a gift from a nice NPC.
- First find a situation ingame where someone could give you the item, and remember what he said in that dialogue.
- Code: Select all
select rowid from _Story_DialogTakes WHERE TakeGUID=(select TakeGuid FROM _Story_DialogTakes WHERE TakeLocaID=X'30C7875CA35EE14A93F5781CCF5B8993');- Code: Select all
select rowid FROM _Story_DialogActions WHERE TakeGUID=(select TakeGuid FROM _Story_DialogTakes WHERE TakeLocaID=X'30C7875CA35EE14A93F5781CCF5B8993');- Code: Select all
ShowTutorial tutorialId="DialogTutorial" actionSelection="script,quest,dialog";- Code: Select all
'CreateEntity category="Jewelry" templateId="MY_COOL_ITEM" how="spawnInStorage" entity="Hero" number="1" actionSelection="script,quest,dialog";- Code: Select all
UPDATE _Story_DialogActions SET ActionContent=ActionContent||'CreateEntity category="Jewelry" templateId="MY_COOL_ITEM" how="spawnInStorage" entity="Hero" number="1" actionSelection="script,quest,dialog";' WHERE TakeGUID=(select TakeGuid FROM _Story_DialogTakes WHERE TakeLocaID=X'30C7875CA35EE14A93F5781CCF5B8993');- Code: Select all
INSERT INTO _Story_DialogActions select TakeGUID,'CreateEntity category="Jewelry" templateId="MY_COOL_ITEM" how="spawnInStorage" entity="Hero" number="1" actionSelection="script,quest,dialog";' FROM _Story_DialogTakes WHERE TakeLocaID=X'30C7875CA35EE14A93F5781CCF5B8993';
Then open Locale.db4 in the SQLite Browser and search LocaText for that line.
For the example let's use the very first line in the game, when the guard stops you with "Hold there..." (or whatever); the line we're looking for is 6800
In LocaID we have another identificator: 5c87c730-5ea3-4ae1-93f5-781ccf5b8993 copy it and use the Blob-Tool to convert it to hex (30C7875CA35EE14A93F5781CCF5B8993 in this example) and use this Hex-GUID in the following SQL-queries:
This will return the line in _Story_DialogTakes (1110 if everything was correct so far.) Where all the structural data abpout the dialogue line (conditions, speaker etc.) is located. This is just a check, if this would return no line there is something wrong with the LocaID you used.
Returns the line of the script (if one exists) this returns 100 - so there is already an action Script for this line of dialogue. If there were no result, we could simply create a new one.
Now go to line 100 in _Story_DialogActions, the Actioncontent is:
And yes this line actually opens a tutorial. Now all that is left to do is add our script to the existing one.
I cheated and looked at existing scripts to actually come up with this. category="Jewelry" comes from _Template_Jewelry in which our item can be found. "MY_COOL_ITEM" is the ID we gave the item in _Template_Jewelry and "Hero" is the PC, if you type "pc_rhulana" there, she will get the item.
This SQL-query will append your script-code to the existing one:
If you just were to create a new enty or overwrite an existing one, you'd use:
Have a look at my Ring of Witchcraft as an example for creating a new item with a new effect and adding it to a dialogue.
Of course you should modify the text in Local.db4 as well so that the NPC actually says that he gives you something, but that should be a piece of cake by now.
Edit:
- June 18/09: Figured out a much easier and reliable way to find/modify the scripts linked to dialogue-lines.


