Modding Tutorials: World Data Overrides

Discuss modding questions and implementation details.
Locked
User avatar
Hazelnut
Posts: 2865
Joined: Sat Aug 26, 2017 2:46 pm
Contact:

Modding Tutorials: World Data Overrides

Post by Hazelnut »

Overriding Daggerfall World Data

Links to Sections Introduction
The World Data Override system has been built so that mods can alter and add to the Daggerfall world data after it's streamed from the original data files, but before it's used by the DFU engine. This allows modifications of the gameworld without needing to change the original data files. The override files are json format and much easier to edit than the original binary files, and targetted sections of world data can be changed, while the remainder is unaltered. This also avoids the issue of these files being copyrighted by Bethseda, and the DFU model is to require the original files without modifications.

I know this tutorial is more of an info dump and is not easy to read & comprehend, but please do read it. I've tried to write down what I know in the best way I can and have spent hours doing this when I would much rather have been coding and solving problems. Making overrides will require effort, time and understanding. The more you're pushing the boundaries of what's already been done before, the more you will need to understand the data structures and the code that uses them - so you are aware of the various constraints and can problem solve to reach a solution. I'll help as much as i can, but I don't know everything and my answers will often involve me reading through code and figuring stuff out so you may need to be patient. (Hint: queries with all relevant detail and context provided, and demonstrating the effort taken to understand and solve yourself will always get a response :geek: )

What is World Data?
By world data I'm referring to the data that defines the locations of the Daggerfall game world. All the coloured pixels that you see on the games travel map and select as destinations to fast travel to. Basically towns, villages, dungeons etc. These locations are merged into the world terrain, which is a completely different system where a TerrainSampler uses the classic heightmap data to generate the terrain of the world. This terrain is not something that can be altered by the world data system discussed here. DFU basically flattens the terrain to place a locations' exterior and paints over the texture tiles of the terrain with texture tiles defined in the world data.

Much of the DFU code relies on the world data being as expected. There are constraints on what you can change without breaking DFU, so care needs to be taken to change the world data only in ways that DFU expects. Following existing patterns in the classic data is the safest way to ensure this. For newcomers I would recommend starting with building overrides as they're the easiest to work with and the most useful. (see the last section of this guide "Altering an existing town building")

Background info (must read and understand!)
The world of Daggerfall is specified in several bsa data files from the original game that DFU streams data from at runtime. These files define the overworld map, locations (towns & dungeons), buildings, dungeons etc that make up the gameworld. The world data override system allows selective parts of the location data to be overridden and changed.

There are over 15 thousand locations across the regions of the Iliac bay, constructed from reusable blocks. World blocks for the outside world (RMB - Record Map Block), which includes building interiors, and dungeon blocks for large interior spaces (RDB - Record Dungeon Block). Dungeons interiors are constructed from RDB blocks and towns & dungeon exteriors are constructed from RMB blocks. The locations are merged into the streaming world at the map pixel coordinates specified.

The hierarchy is illustrated in this diagram.
DFworldData.png
DFworldData.png (13.48 KiB) Viewed 7719 times
Each map pixel is mapped to a region, and each region has a bunch of locations within it. Each location then has an overworld exterior constructed from reusable RMB blocks. As you can see from the illustration blocks can be used in multiple locations, so changing a block will potentially change many locations across the world and in different regions since all places the block is used will change. Locations can also optionally define a dungeon from RDB blocks, again the blocks can be shared between different locations.

Console data dump commands
To assist with overriding world data I've added several data dump console commands to DFU that dump various world data into JSON files. The files go into the folder where you can find the DFU settings file and do nothing at all if left there. They are simply put there for you to look at, copy from, move and edit etc. Just be aware that the contents will include any override data the game has loaded from mods and loose assets, these will need to be disabled to get a file with just the vanilla data.
  • dumpregion - Dump the current DFRegion to JSON file. (for example data only)
  • dumplocation - Dump the current DFLocation to JSON file. (can be used for location overrides)
  • dumpblock - Dump a set of RMB & RDB blocks to JSON files. e.g. "dumpblock RESIAM10.RMB M0000004.RDB" (can be used for RMB & RDB overrides) If no block names specified, will dump a block index to "BlockIndex.txt" containing all of the blocknames indexed as they are from the original data.
  • dumplocblocks - Dump the names of blocks for each location, or locations for a block, to JSON file. With no argument you get a list of blocks for all locations in the game which will take a while so be patient. Providing a blockname gives a list of all locations split by region that contain that block. e.g. "dumplocblocks RESIAM10.RMB" (useful for finding everywhere a block you're modifying is used) Giving the argument "locindex" dumps a location index to "LocationIndex.txt" with regionIndex, locationIndex, location name.
  • dumpbuilding - Dump the RmbSubRecord of current building player is inside to JSON file. e.g. "dumpbuilding"
Comparison with the 'New Locations' mod
Uncanny Valley has created a new locations modding resource already, and it's been used to create new things in the Daggerfall gameworld, so why is overriding world data of any use you may ask? The location loader and other resources in 'new locations' are fantastic, but they serve a different purpose. It enables new content made in Unity to be layered on top of the gameworld, allowing new decorations and places to appear in the exterior overworld. It doesn't enable new locations that can be fast travelled to or used in quest scripts however. I think the name locations is a bit misleading, since they're not daggerfall locations and are not integrated into the gameworld. Brilliant for adding small places of interest around the map, but not for a new town or dungeon.

Do I have to edit the raw json files?
Location and RMB blocks require json file editing. Buildings (RMB subrecords) and Dungeons (RDB blocks) can be edited using the 3D WorldData Editor (soon to be) supplied with the Daggerfall Unity source. Buildings edited can be put together into a complete RMB override if needed, however this is done via json editing.

What can I use to edit the raw json files?
Any text editor you like, but I would recommend one that can interpret json and allow section folding. This is incredibly helpful for navigating and focussing on specific parts of the data. My recommendation is to use VSCode which is free, provides json folding, and very good. Atom is another good option.

Development of override files.
When developing override files, the best way is to run the game in the Unity editor and put the files as loose files into StreamingAssets/WorldData/. This will allow changes to those files to be reflected in-game without requiring a restart, just re-load or exit and re-enter to get DFU to re-build the scene. When not running in the editor, the override data will be loaded and cached for the rest of the session, so changes will not be seen in game until it's restarted.

Test files.
I've attached a zip file with the test files I've used when developing this feature. The new dungeon block references a custom model from the Archaeologists mod, so you will need that installed or you will need to change the model id to one from the original data otherwise the block layout will fail. You can also see all the source files for my mods in github here: https://github.com/ajrb/dfunity-mods
WorldDataTestFiles.zip
(7.07 KiB) Downloaded 106 times
See my mod code for examples of how to change various aspects of DFU: https://github.com/ajrb/dfunity-mods

User avatar
Hazelnut
Posts: 2865
Joined: Sat Aug 26, 2017 2:46 pm
Contact:

Re: Modding Tutorials: World Data Overrides

Post by Hazelnut »

Locations

Note: To be able to target a specific building within a location, the sector field of the building data records can be used to index the block name in the exterior data array. The correct block containing the building must be known so the building key can be calculated when referencing the building & location from the place definition in a quest script. This is not what the field was for, but as it's unused I re-used it to allow this.

BadLuckBurt created a html location editor, dfu-worlddata-editor.html, which can be found in his github repo here: https://github.com/BadLuckBurt/dfu-worlddata-editor. Personally I prefer to edit location JSON by hand as it's quite easy and I've found Burt's editor to be tempramental, but feel free to give it a try.

Altering an existing location

To alter an existing location, travel there and run the dumplocation command to get the current data for that location. The json file will be called location-RR-NNNN.json where RR is the region index (e.g. 17 for daggerfall) and NNNN is the location index within that region. The json in this file can be edited to change the location in the same ways as shown for adding new locations. Region Ids can be found here: https://en.uesp.net/wiki/Daggerfall:Region_Numbers

At present, all that can be visibly changed for a location exterior is the RMB blocks used and their layout. This is done by changing the list of block names and the width / height elements. Only existing blocks can be used at this time until the 2D array serialization issue is resolved to allow entire RMB blocks to be changed or added. Individual buildings can have their interior and exteriors replaced, see later on in this tutorial for more detail. Building data is also at the location level and this is combined with the block building data at runtime to give the buildings (which are otherwise the same for every location the block is used) location specific data for nameSeed, factionId, and quality.


Altering a dungeon location dungeon block layout

Altering a dungeon location dungeon block layout is a case of specifying the RDB blocks in a list and defining the x,y coordinates they should be at. Only one block can be marked as the entrance block, and even though the crypt locations in original data all seem to define an '+' shape of 5 blocks with only the central one actually accessible by players, there's no need to do this for DFU and, as shown in my examples, just the single block seen by players needs to be defined. See https://en.uesp.net/wiki/Daggerfall:MAP ... ck_Element for more details.


Adding a new location

New locations should be named 'locationnew-LOCNAME-RR.json' where RR is the region index the new location will be in, and LOCNAME is your file name for this location. e.g. 'locationnew-archcrypt1-17.json' When adding a new location, I suggest finding a similar existing location and use the dumplocation command to get the data for it, then rename the file and edit it to become your new location as shown below. A unique location index will be assigned internally when loaded in the game, and this could be different each time depending on other mods, so you cannot rely on it being a particular value and should set the corresponding data elements to zero as shown below. You must restart the game when adding a new location replacement file regardless of running in the editor, as the index will not get assigned correctly. Once the new location file is there, you can make changes while the game is running as normal.

Now you will need to decide is where to put your new location on the map, first choosing a region, and then the specific map pixel in that region. As far as I know you can't have two locations in one map pixel. (utility to assist is coming... be patient: The easiest way to find the coordinates you want is to use the in-game travel map with the WorldDataUtilities.dfmod installed. This will display the map pixel coords the mouse is over enabling easy selection of a suitable map pixel.) Once you have the map pixel x,y coords then you can calculate the mapId and the other coordinates required for the header. These must be consistent otherwise errors will occur. I will refer to the map pixel x,y coords as mappx.x and mappx.y in all of the instructions below and I will use the example numbers 123,456 for mappx.x,y below.

Code: Select all

1) MapId = (mappx.y * 1000) + mappx.x = 456123
2) ExteriorData.MapId = MapId 
    (In original data, the MapId & 0xfffff = ExteriorData.MapId with the upper bits contain the LocationIndex but 
     these upper bits are unused by DFU so you can simply set both MapId's the same)
3) Latitude = (499 - mappx.y) * 128 = 5504
4) Longitude = mappx.x * 128 = 15744

Annotated example: a new crypt location

This is an annotated example of a new crypt location from the test files zip. The filename is: "locationnew-archcrypt1-17.json" and the 17 is the region index of Daggerfall. It's a copy of the Gaerhart Vaults and is placed one map pixel to the east, and uses a new added block ARCHC001.RDB for the crypt interior. It also uses a different existing RMB block for the exterior.

Location-crypt.jpg
Location-crypt.jpg (359.11 KiB) Viewed 3450 times

Annotated example: existing shack location

This is an annotated example of an existing shack location from dumplocation command. The filename is: "location-17-1268.json" and the 17 is the region index of Daggerfall, and the 1268 is the location index. It shows a location with building data, and no dungeon.

Location-shack.jpg
Location-shack.jpg (186.47 KiB) Viewed 8498 times
See my mod code for examples of how to change various aspects of DFU: https://github.com/ajrb/dfunity-mods

User avatar
Hazelnut
Posts: 2865
Joined: Sat Aug 26, 2017 2:46 pm
Contact:

Re: Modding Tutorials: World Data Overrides

Post by Hazelnut »

Dungeons

Altering an existing dungeon block

To alter an existing dungeon block, first dump the original using the dumpblock command. Do ensure you don't accidentally get the data from installed mods, unless that's what you want to start with. The file will be called BLOCKNAME.RDB.json and can be edited then moved into WorldData. See the annotated examples for details of how to change the data, but in summary there's a list of model references and a list of lists of rdbObject's. These objects can be flats, lights or models that make up the block. It's unclear why this is a list of lists, and I've not spotted any pattern yet. I suggest that any new objects are added to one of the empty lists to make it easier to keep track of new stuff, but it doesn't really matter. The model refs are used by model objects by the model ref list index, so any models you want to use need to have a reference with a numeric model id. New models provided via the asset injection system can have references added, but only if the model has a numeric name. (try to avoid collisions between mods)

In addition, model objects can have action resources attached to enable the model to trigger an action when clicked by the player. I've not figured out how this all works, but these can be added. It's unnecessary for any models that don't have actions, so feel free to delete it.


Adding a new dungeon block

To create a new dungeon block you will need a name for it, e.g. ARCHC001.RDB from my examples. I don't think it has to follow the 8.3 format of classic block names, but I've not tested that. Feel free to try and report back if you want. Next either start with an existing block dump and delete everything you don't need. The dungeon block will need constructing from existing and new models, and each will need a single entry in the model ref list regeardless of how many times the model is used. Then create object list entries for each placement of the model, following up with entries for flats and lights. Currently there's no taxonomy of the existing models in Daggerfall so it can be hard to find what you are looking for, but they can be browsed using the modelling utility availiable here.

Note that you cannot use a new model for the entrance part of the block without creating a related instance of CustomDoor.cs, otherwise it has to be an existing model with a static exit door definition. Also worth mentioning that a good way to look at complete blocks is to run DFU in the Unity editor and navigate to a dungeon the block is used in, pause the game, then switch to the scene view. Click on the interior dungeon tree on the left panel and select the block entry you're interested in. Rendered blocks have all the models combined so the entire 'finished' block can be inspected and rotated etc.


Annotated example: a new crypt block

This is an annotated example of a new crypt block from the test files zip. The filename is: "ARCHC001.RDB.json" and is referenced from the new location data as shown above.

RDBblock.jpg
RDBblock.jpg (195.28 KiB) Viewed 8413 times
RDBblockObjectLists.jpg
RDBblockObjectLists.jpg (74.37 KiB) Viewed 8413 times
RDBblockObjects.jpg
RDBblockObjects.jpg (298.93 KiB) Viewed 8411 times
See my mod code for examples of how to change various aspects of DFU: https://github.com/ajrb/dfunity-mods

User avatar
Hazelnut
Posts: 2865
Joined: Sat Aug 26, 2017 2:46 pm
Contact:

Re: Modding Tutorials: World Data Overrides

Post by Hazelnut »

Towns & Buildings

RMB blocks used for overworld locations like towns can now be overridden. Individual buildings in an RMB block can be altered independently (see next section), so for existing blocks, it's probably best to override specific buildings as only one override for each thing (block, location, building) can be used at a time. So two mods could change different building in the same block, but if one changes the whole block then it would conflict. I think mostly RMB block overrides will be used to add new blocks to the game because the building data lists of each location using the block would need to be changed if any new named buildings are added, whereas building overrides do not require this, and can modify exterior and interior. Recommendation is only use block overrides if modifying all/most the buildings, the layout, ground textures, or you're creating an entirely new block. Otherwise use building overrides. Even if you want to have the name vary by location you can still do that with building overrides by having a FactionId of zero and altering location building lists, but at that point consider a full block override.

UESP has a useful set of pages showing the existing blocks of the game here: https://en.uesp.net/wiki/Daggerfall:Blo ... apPItem.29

When creating a new RMB, the best way to start is to find an existing block that's as similar to what you want from the classic data, then dump the block data and use that as a starting point. Ground tile data and automap data have editors written by BadLuckBurt that I will link here once they are released. Most other data elements are described in the example below.

Annotated example: a new map block

This is an annotated example of a new map block for the fort from my upcoming FG master quest with a few minor changes so it's a better example.
RMBblock.jpg
RMBblock.jpg (261.76 KiB) Viewed 7600 times

Altering an existing town building (Building Overrides - use these first!)

Building overrides just affect a single building within a block, and allow multiple buildings in a block to be modified by different mods without conflicts. (except for the automap, as a block can only have one and there's no merging logic) They also allow residences to be turned into named (shop/tavern/guild) without needing the building list of every single location using the block having to be modified. Recommended method to modify existing buildings.

The way it works is that you create a JSON file containing data for the BuildingReplacementData struct in the WorldDataReplacement class and place it in StreamingAssets/WorldData. It needs to be named like this:

Code: Select all

string.Format("{0}-{1}-building{2}.json", blockName, blockIndex, recordIndex)    
e.g. blockName-blockIndex-building#.json
For example, the file I created for the Archaeologists mod is called RESIAM10.RMB-543-building10.json and overrides building 10 of RMB block RESIAM10. (refer to it as an example, and compare it with the default data dumped by command to see what I changed) This example doesn't contain a NameSeed since it's a guild, another example from Mountain Rumors does since it's a shop. Note that the block name & index in the filename are redundant, either one could have been used alone, but I put both are in the filename becuase I find it useful.

To create a JSON BuildingReplacementData file simply start with the JSON file produced by the dumpbuilding command like the example detailed below and edit the values. You will need to put the top level faction id and the building type (e.g. 11 which is for a guild hall) which can be any of DFLocation.BuildingTypes. Quality is only important for shops as far as I know. When location & block building data is being matched, overridden building NameSeed's are added to the location index so the shop/tavern names will vary and not be the same for every place the block with the building is used.

Note: You must set FactionId if this is a new 'named' building (see RMBLayout.IsNamedBuilding()) unless you modify the building list of every location using the block. So leave it zero when either not a named building or changing an existing named building which will already have a record. This is so that the location building matching doesn't get out of sync. NameSeed & Quality values are only used if FactionId is non-zero, otherwise all are taken from the matched building data of the location if found. BuildingType is always overridden regardless. NameSeed is not used for guilds, the faction data is used instead.

The remaining two members of the structure are RmbSubRecord which is where the specific building data goes and AutoMapData which is optional but allows the map data for the block to be adjusted to be consistent with the updated building. Note that if two buildings in the same block are overridden, only one can override the map data for that block. Currently there's no solution for this. FactionId of zero will allow DFU location building data matching to run, be careful with this as you can use up pool items and change other buildings in the location.

Code: Select all

{
    "FactionId": 1010,
    "BuildingType": 11,
    "Quality": 11,
    "NameSeed": 1234
    "RmbSubRecord": {
        ... Rmb block dump in here ...
    },
    "AutoMapData": [
        ... paste automap byte array dump in here (optional) ...
    ]
}
RmbSubRecord

The subrecord has 2 sections 'Exterior' and 'Interior'. The interior is split into following: Header, Block3dObjectRecords, BockFlatObjectRecords, BlockSection3Records, BlockPeopleRecords, and BlockDoorRecords. To add new things to the building (i.e. npc's, furniture etc), add json blocks to the following sections.
  • Block3dObjectRecords - 3d models, including the walls etc. Add new furniture like beds, shelves, chairs, tables in here. I found AlexanderSig's list of models he's replacing was really helpful to find the model id's, and you can also use the DF modeling tool as well.
  • BockFlatObjectRecords - Flat sprites used for decorations etc.
  • BlockPeopleRecords - Flat sprites used for npcs. The position field is filled from the position within the blocks file, just set it to a unique number within the list for the name seeding code. (start with 1 and count up...)
From here it's simply a case of adding all of the models, flats and npcs one by one. Getting them all in the right place is a case of trial an error or using an edior.

For automap data, use BadLuckBurt's tool to edit, then copy and pasted the output JSON into the relevant part of the building JSON file.
See my mod code for examples of how to change various aspects of DFU: https://github.com/ajrb/dfunity-mods

User avatar
Hazelnut
Posts: 2865
Joined: Sat Aug 26, 2017 2:46 pm
Contact:

Re: Modding Tutorials: World Data Overrides

Post by Hazelnut »

Using Variants for a more dynamic Daggerfall world!

The world data variant system allows different overrides to be used once a trigger happens. The triggers can set variant blocks (or location / buildings) to be used just for a specific location, or every location using that block like the base system does. A variant is simply a string that selects a specific world data override file, for example in the Roleplay & Realism mod I use the variant "_master" to select a file called ARMRAM03.RMB-765-building14_master.json that changes building number 14 in the ARMRAM03.RMB block. I used the underscore prefix to make variant separate from the rest of the filename, but it's not required. The building is actually an armorer shop that was not given the right data to be a real shop, and the override file changes it into a very fancy & decorated shop with a special NPC.

The class that controls this is WorldDataVariants and has 4 methods for adding & changing variants as listed below. For blocks and buildings, a locationKey can be specified if you want the variant to only appear in a specific location. A location key is simply the location index combined with its region index and you should use WorldDataReplacement.MakeLocationKey(int regionIndex, int locationIndex) to create one. If you want a variant block or building to be used for all locations, don't supply a locationKey or use -8 (chosen because it looks like an infinity standing up, and I'm bored of using -1, do refer to the constant AnyLocationKey :P )
  • SetLocationVariant(int regionIndex, int locationIndex, string variant)
  • SetNewLocationVariant(int regionIndex, string locationName, string variant) - Need a different method for new locations as the index is only allocated at runtime.
  • SetBlockVariant(string blockName, string variant, int locationKey = -8)
  • SetBuildingVariant(string blockName, int recordIndex, string variant, int locationKey = -8)
Removing a variant is simply done by setting a blank variant string, by using NoVariant constant. Setting a variant for the same parameters overwrites any already set.

There's a quest action for triggering variants called worldupdate and can take the following forms:
  • worldupdate location at <locationIndex> in region <regionIndex> variant <variant>
  • worldupdate locationnew named <locationName> in region <regionIndex> variant <variant>
  • worldupdate block <blockName> at <locationIndex> in region <regionIndex> variant <variant>
  • worldupdate blockAll <blockName> variant <variant>
  • worldupdate building <blockName> <recordIndex> at <locationIndex> in region <regionIndex> variant <variant>
  • worldupdate buildingAll <blockName> <recordIndex> variant <variant>
For example, from RRMSTARM1.txt in my mod:

Code: Select all

worldupdate building ARMRAM03.RMB 14 at 240 in region 52 variant _master
See my mod code for examples of how to change various aspects of DFU: https://github.com/ajrb/dfunity-mods

User avatar
Hazelnut
Posts: 2865
Joined: Sat Aug 26, 2017 2:46 pm
Contact:

Re: Modding Tutorials: World Data Overrides

Post by Hazelnut »

World Data Editing (WIP, please ignore for now)

Credits: Uncanny Valley for writing the original editor, Cliffworms & BadluckBurt for the full object lists.

The World Data editor is a tool for DFU that allows the Unity editor scene view to be used to edit World Data override files. It was originally written by Uncanny Valley for editing buildings and the thread for that is here: viewtopic.php?t=3217. Location json files are easy enough to edit by hand, and RMB blocks can be constructed from building files combined with hand editing, but editing RDBs by hand is almost impossible. So after a long absence from UV I decided that I would extend this editor to also allow dungeon blocks (RDBs) to be edited as well as buildings and add it to DFU project as a standard tool. I've kept the same basic UI as UV's editor, but I had to write a lot of code for the RDB editing - it turned out to be a lot harder than I originally thought it would be. :)

Please note that this is not a construction kit, or a professional editor! It's not foolproof, has many quirks, and takes time to learn how to use. Please don't complain about how it compares to <whatever> - it's provided as-is and allows for visual editing of world data but you will still need to have an understanding of the world data system and formats and the constraints & trade offs of doing different things with the editor. You'll also need to read the DFU code (mainly RDBLayout) to work out some of the property values to use for more advanced effects. Worthwhile results will take time and dedication, it's not like elder scrolls CKs that allow prefabs to be snapped together easy as pie, sorry.

Basic Instructions
  1. Download correct version of unity editor (2019.4.10f1 LTS) and open the Daggerfall Unity project downloaded or cloned from https://github.com/Interkarma/daggerfall-unity/
  2. Once opened you will find a menu option under Daggerfall Tools called "WorldData Editor"
  3. Recommend dragging the opened editor window to the inspector view, so it creates an extra tab for you to view it instead of the inspector. The editor was designed to be used in this way, but if you have a second screen you may prefer to have it undocked on there to give more space to scene view.
  4. Use the dumpbuilding command inside any building, or use the dumpblock command with a RDB (dungeon) block name to extract a world data json file that can be edited. Note that this will dump any changes made to the world data by mods which can be useful if you want to start from that point, but remember to disable mods if you want the vanilla data.
  5. Open the building file or the RDB file in the editor using the open buttons.
  6. Ensure you have scene view tab selected and double click on the root of the opened objects in the hierarchy window to center the opened building or block in the view.
  7. When you open a location it will load all the objects into your currently opened scene in Unity. 3D objects can be moved, rotated and scaled using the standard unity scene viewer controls. Note that billboards (flats) can only be moved.
  8. You can rotate and scale models using unity, however this is much more convenient to do by typing values into the fields on the WD editor window. Usually you'll have a multiple of 90 degrees. The unity controls are good for fine control when required though. You can also toggle display settings, e.g. the light bulb icon switches from scene to flat lighting.
  9. Selecting any object will show the editable properties for it. These are documented below.
  10. If you wish to add new objects to the location, click the "Add object" button. You can add objects from pre-made lists or add them "manually" by typing in their ID number.
  11. Some objects, such as painting flats, are grouped together. You will also notice that when adding new objects from a list, some of them are displayed as "ObjectName"[Number], to indicate that they are grouped together. See below for how this differs between building and RDB editing modes.
  12. When moving and rotating objects, you will probably notice that objects will slightly "snap" into place. This is because Daggerfall objects location and rotation is stored with less precision then Unity, so this "snapping" will make sure that any object you move or rotate in the editor will have the exact same position/rotation in the game
  13. The building and RDB editors work slightly differently so refer to the notes below for each.
  14. When finished, save the json file and place it into the WorldData folder in streamingAssets to see your changes in the game. (NOTE: the file name must remain the same as the original)
  15. To close down a current open file you can either delete the parent object in the hierarchy, or close down the editor window (as in right click and choose "Close Tab"). NOTE: Do not forget to save before you do this or your edits will be lost!
  16. If you later wish to distribute your edited interior(s), you can package the world data override files into a dfmod.
  17. Note that using the editor will modify the daggerfall start scene (or whichever you have loaded) even after the editor is closed, if propmted don't bother to save the changes to the scene just discard them. There are no actual changes if you've closed the editor but teh scene is modified with game objects during editing.
WDeditor1.png
WDeditor1.png (897.12 KiB) Viewed 1121 times
Building editing
  • Switch between editing interior and exterior of the building and also toggle a ground plane using the buttons that appear when editing a building file.
  • When selecting an object in the scene some objects, e.g. a wooden box, give the option to enable/disable it as a container. Ladders can be enabled too.
  • Select the parent object called (Building: "File Name" ) in the Hierarchy to edit special option for the location such as Building Type and faction id.
  • When selecting cyclable objects in the scene view, the editor will give you the option to quickly cycle through the different variances of that objects. These have the number of variants in square brackets in the lists.
  • Models can be previewed before being placed, and can by cycled if in a group. This is not so useful for buildings as you can place and then cycle them, but it can still be useful when browsing models.
  • Lighting is added by adding flats from the lighting archive. (210)
  • Flats can now be added to the exterior of a building. NPC flats must have a non-zero faction id to become NPCs.
  • Building are constructed from Interior parts. These can be switched using a button "Switch set" that appears to cycle through similar models based on the id. (this was in UVs code, I don't fully understand it)
  • The main building model must be the first in the list otherwise DFU will not recognise clicks on it. So when adding exterior models be careful not to reorder the object hierarchy in Unity.
WDbuildingProps.png
WDbuildingProps.png (122.91 KiB) Viewed 1111 times

Dungeon (RDB) editing

Dungeon editing is a bit more complex than buildings. Daggerfall dungeons are constructed by placing together some RDB blocks which have standard connection points. This page explains it best, refer to the diagram of a block with connections: https://en.uesp.net/wiki/Daggerfall:Dun ... f_Dungeons. There are border blocks that begin with B that close the edges of the dungeon, general content blocks start with N and water blocks with W. Special blocks start with S. There's no need to follow this convention with custom block names. I would suggest using some letters for author or mod name followed by something descriptive. I don't think there are any block name length constraints.

This gives several options for the method used to achieve the objective when editing dungeons blocks:
  1. Edit an existing block to make a new variation for use in new or existing dungeon locations.
  2. Construct an entirely new block that has standard connection points and can be used in new or existing dungeon locations. (I intend to provide a template for this)
  3. Construct an entirely new dungeon with a single custom RDB block using the blank template which just starts with an entrance/exit point. There are no size limits so you can make it as large as you like, but it will only be useful for a single dungeon location in the world. (unless you want identical dungeons)
  4. Construct a dungeon shell model (in blender or whatever) that is very custom. Can use one or multiple models, and just place an entrance/exit model plus the entry marker flat. Note that the dungeon exploration mechanic works model by model as the player sees them so using one or more large dungeon shells will make this much less granular and incremental than constructing a dungeon from standard lego-like building blocks. If the shell model doesn't have colliders, then ensure you add the model using the 'COL' option which instructs DFU to automatically add colliders to this model when laying out the dungeon to prevent players from simply falling though the floor.
The latter two options are best utilised for specific custom dungeons referenced as permanent places (locations) from a non-generic one time quest in a similar way to the fort location used in the Mountain Rumors quest from my Roleplay & Realism mod.
  • Dungeon editing works differently from buildings. Instead of an interior / exterior, each RDB has 10 object lists and you can add to just one or use them to split up your block into logical pieces. You can select the top level of each list in the hierarchy to see an outline what it contains in scene view.
  • To add an object in RDB mode, you first need to select an object list (0-9) from the drop down. The scene view will only show objects in this list, and the add object button will appear.
  • Flats are added in the same way as for buildings, but there are more properties and they can be part of actions.
  • Lights are added separately for dungeons with a radius, and as you will see from vanilla blocks are often shared between many 'lights' flats to reduce the amount of lights the engine renders.
  • Models can be added, both general clutter as well as dungeon parts to create the rooms and corridors etc.
  • Each model gets appended to a model list and then referenced from the object lists. This means that once placed, this entry in the model list is permanent even if all references are deleted. For this reason a preview button has been added so you can preview the models and cycle through groups until you have the one you want to place. Then click OK to place it and move it into position. Cycling cannot be done once placed in RDB mode.
  • There is a drop down for type when adding models with the options: MOD, DOR, LID, WHE, COL. Most of the time leave this at the default MOD value. For door models change it to DOR, for hatches/lids use LID, for wheels WHE, and for shell components use COL for automatic generation of colliders.
  • Note that models of each type are only added to the internal model list once, but then are never removed.
  • When any object is selected the editor window displays the object list number, the index of the object in that list to allow the object to be found in the JSON file.
  • Actions are supported using property fields where you can type in values. You will likely need to read the DFU RDB layout code to understand how these values work and what they do. When an object is selected the ID value that is used to link objects together in action chains is shown and can be entered into a preceding objects' next field. (prev field is not necessary to fill in as DFU can generate these automatically)
  • You can navigate between objects in an action chain using the select buttons. All the tools are there to create dungeon actions, but you will need to figure out how to use them.. it's a bit beyond my explaining skills.
  • Don't duplicate objects using unity scene view (e.g. select-copy-paste) as the required metadata is not created and after you save then load the RDB the duplicated object will be incorrect.
WDdungeonProps.png
WDdungeonProps.png (137.19 KiB) Viewed 1117 times
Working with custom models

Using custom models with the editor is a bit tricky as they need to be made available via the DFU mod system.
  • Ensure the model is provided in a mod to DFU when it's run in the unity editor.
  • The mod doesn't need to be built, it can be virtual.
  • Before opening the world data file to be edited, play DFU in the unity editor ensuring the mod is enabled and the load/new screen is displayed.
  • Switch to the scene view tab and open the world data file to edit it.
  • In this mode the flats will not rotate to the scene view camera, they will rotate to the player. You can load a save in the game tab and move/turn the player to change the flat orientation in editor, or you can rotate the camera until flats are visible. It's a bit awkward which is why you should only have DFU playing while editing if you need to use custom models. (and flats, though I've not tested this)
  • Add the custom model manually by entering it's model id.
  • Any custom model will fail to load if DFU is not playing with a loaded and enabled mod providing the model, and if you load and save it will simply be removed from the world data file.
  • It's quite possible to edit a file in the StreamingAssets/WorldData folder, save and switch to the DFU game tab to see the results in game. To refresh simply load a save or exit/enter the building so the structures are re-layed out by DFU.

Automap & Ground data editing

The automap for building overrides or RMBs, and the ground data for RMBs can be edited using BadLuckBurt's html editors which can be found in his github repo here: https://github.com/BadLuckBurt/dfu-worlddata-editor

Use dfu-automap-painter.html to edit an automap data array. This is how I converted the houses used for the Archaeologists guild halls to show up as blue on the town map. The JSON array output is nicely formatted so you can see the map and should be copied into the applicable part of a building or RMB json file. Note that the World Data editor will convert this to a single line of values when ever you save, so I would recommend copying the nicely formatted automap data once you've finished 3d editing. See my mods for examples.

Use dfu-terrain-viewer.html to view the ground data tiles for an RMB file. Using BadLuckBurts instructions (viewtopic.php?f=22&t=2984 and https://github.com/BadLuckBurt/tiled-da ... owtouse.md) and the downloadable program called Tiled, the ground tiles for an RMB can be edited without needing to manually edit the JSON values.
See my mod code for examples of how to change various aspects of DFU: https://github.com/ajrb/dfunity-mods

Locked