Wow, thanks, that's really helpful. I'll go investigate Wrye Bash. Chances are I will write the actual dungeon generator in Java (because that's the only real language I have any experience in), and then learn just enough Python to handle read / write operations. Where can I find information or updates on CBash?
Well, I don't intend to put together static tiles to create a dungeon, I intend to put entire rooms (like the warehouse interior rooms), so it should not look too maze-like. I'm more worried about the dungeon becoming too linear (the algorithm I'm thinking of implementing will probably tend to create a "tree" like dungeon.)
UPDATE: Well, looking through Wrye Bash, I believe that it does not have the functionality I desire (editing references in cells) - and even if it does, chances are I won't be able to find said functionality without a lot of tedious searching through the source (or just asking Wrye, but I don't know how to contact him, and even if he would help).
So, I opened up an .esp file I made with 3 static objects placed at specific coordinates using a hex editor. I learned that TES4 likes to store coordinates as 32-bit floating point numbers... backwards. From there, I've managed to isolate what I believe is a single reference.
So far, all I've managed to do is change the coordinates of objects. I tried to duplicate a reference, but it just crashed TES4CS when I tried to open the esp (although I believe I might have screwed up the duplication itself lol). I'm going to check now if the .esp has some kind of checksum. I also have a suspicion that the cell object has a checksum or a count of how many references a cell should contain.
As usual, any information would be welcome! I'll eventually post all my findings when I feel I have enough to be worthwhile.
UPDATE:
YESYESYESYESYES
I managed to successfully duplicate a reference in a cell! TES4CS also threw me a whole bunch of errors, which while bad, also informed me a lot about how the .esp file works. Furthermore, pressing yes to all the errors didn't cause a crash, and when I opened up the interior, I saw my extra reference!
brb victory dance
Here are the errors; if anyone can recognize them, that would be helpful.
UPDATE:
I've done a lot more research on the inner workings of the .esp. I'm nearing a point where I am confident that I know enough to create a dungeon filled with static objects (I have not investigated things such as traps, NPC's and doors - still a lot of work to do!).
This is the file with all my findings (I had to use <code> tags).
ESP files seem to store floats as 32-bit, in hex, backwards.
Use this to convert: http://babbage.cs.qc.edu/IEEE-754/Decimal.html
So, if your number in decimal is 3000, and the hex conversion is 45 3b 80 00, then it's stored as 00 80 3b 45.
44A72000
44 A7 20 00
Coordinates of the reference are stored as XYZ, one after another, as backward 32-bit floats.
After this is twelve 00's (00 00 00 00 00 00 00 00 00 00 00 00). This seems to represent the end of the reference.
These values may have some significance (probably boolean flags).
Now that we know the end of the reference, we can isolate a single reference! Yay!
// ======================================================================================
// Reference Analysis
// ======================================================================================
52 45 46 52 28 00 00 00 00 00 00 00 E7 0C 00 01 07 57 00 00 4E 41 4D 45 04 00 B3 45 03 00 44 41 54 41 18 00 00 20 A7 44 00 20 A7 44 00 20 A7 44 00 00 00 00 00 00 00 00 00 00 00 00
52 45 46 52 28 00 00 00 00 00 00 00 E8 0C 00 01 07 57 00 00 4E 41 4D 45 04 00 B3 45 03 00 44 41 54 41 18 00 00 00 7A C4 00 00 FA 44 00 80 3B C5 00 00 00 00 00 00 00 00 00 00 00 00
52 45 46 52 28 00 00 00 00 00 00 00 E9 0C 00 01 07 57 00 00 4E 41 4D 45 04 00 B3 45 03 00 44 41 54 41 18 00 00 00 7A 44 00 00 FA 44 00 80 3B 45 00 00 00 00 00 00 00 00 00 00 00 00
// ======================================================================================
52 45 46 52 28 00 00 00 00 00 00 00 E9 0C 00 01 07 57 00 00 4E 41 4D 45 04 00 B3 45 03 00 44 41 54 41 18 00 00 00 7A 44 00 00 FA 44 00 80 3B 45 00 00 00 00 00 00 00 00 00 00 00 00
I---------I
Reference header - in text shows as "REFR".
// ======================================================================================
52 45 46 52 28 00 00 00 00 00 00 00 E9 0C 00 01 07 57 00 00 4E 41 4D 45 04 00 B3 45 03 00 44 41 54 41 18 00 00 00 7A 44 00 00 FA 44 00 80 3B 45 00 00 00 00 00 00 00 00 00 00 00 00
I---------I
This appears to be the form ID of the reference itself. Backwards, naturally.
// ======================================================================================
52 45 46 52 28 00 00 00 00 00 00 00 E9 0C 00 01 07 57 00 00 4E 41 4D 45 04 00 B3 45 03 00 44 41 54 41 18 00 00 00 7A 44 00 00 FA 44 00 80 3B 45 00 00 00 00 00 00 00 00 00 00 00 00
I---------I
Not sure what this is, but I saw the same sequence in the CELL and GRUP objects.
There are 10 in total - the same number of form IDs in the file.
// ======================================================================================
52 45 46 52 28 00 00 00 00 00 00 00 E9 0C 00 01 07 57 00 00 4E 41 4D 45 04 00 B3 45 03 00 44 41 54 41 18 00 00 00 7A 44 00 00 FA 44 00 80 3B 45 00 00 00 00 00 00 00 00 00 00 00 00
I---------I
Name header. Shows as "NAME" in text.
// ======================================================================================
52 45 46 52 28 00 00 00 00 00 00 00 E9 0C 00 01 07 57 00 00 4E 41 4D 45 04 00 B3 45 03 00 44 41 54 41 18 00 00 00 7A 44 00 00 FA 44 00 80 3B 45 00 00 00 00 00 00 00 00 00 00 00 00
I---------I
I think this is the form ID of the object our reference is pointing to. Backwards.
// ======================================================================================
52 45 46 52 28 00 00 00 00 00 00 00 E9 0C 00 01 07 57 00 00 4E 41 4D 45 04 00 B3 45 03 00 44 41 54 41 18 00 00 00 7A 44 00 00 FA 44 00 80 3B 45 00 00 00 00 00 00 00 00 00 00 00 00
I---------I
This says "DATA" in text.
// ======================================================================================
52 45 46 52 28 00 00 00 00 00 00 00 E9 0C 00 01 07 57 00 00 4E 41 4D 45 04 00 B3 45 03 00 44 41 54 41 18 00 00 00 7A 44 00 00 FA 44 00 80 3B 45 00 00 00 00 00 00 00 00 00 00 00 00
I--X-POS--I I--Y-POS--I I--Z-POS--I
00 00 7A 44 00 00 FA 44 00 80 3B 45
I--X-POS--I I--Y-POS--I I--Z-POS--I
This is where the reference coordinates are stored, in backward 32-bit single float, three of them.
// ======================================================================================
52 45 46 52 28 00 00 00 00 00 00 00 E9 0C 00 01 07 57 00 00 4E 41 4D 45 04 00 B3 45 03 00 44 41 54 41 18 00 00 00 7A 44 00 00 FA 44 00 80 3B 45 00 00 00 00 00 00 00 00 00 00 00 00
I--X-ROT--I I--Y-ROT--I I--Z-ROT--I
00 00 00 00 00 00 00 00 00 00 00 00
I--X-ROT--I I--Y-ROT--I I--Z-ROT--I
Sample data:
DB 0F 49 3F E4 CB 16 40 2D D1 59 40
I--X-ROT--I I--Y-ROT--I I--Z-ROT--I
This one seems to be rotational data for the object.
Stored as radians, not as degrees. Strange.
DB 0F 49 3F = 0.7853981852531433 radians = ~45 degrees
// ======================================================================================
// Scaled Reference Objects
// ======================================================================================
Looks like modifying the scale of an object creates an "XSCL" object.
This appears after the end of the "NAME" object.
58 53 43 4C 04 00 00 00 00 40
I---------I
This just says "XSCL" - the header.
I am currently unsure how the actual scale is stored (the scale of this object is 2.00).
// ======================================================================================
// File Header Analysis
// ======================================================================================
Seems to be inside the "HEDR" object.
48 45 44 52 0C 00 00 00 80 3F 09 00 00 00 F7 0C 00 00
I---------I
Says HEDR.
// ======================================================================================
48 45 44 52 0C 00 00 00 80 3F 09 00 00 00 F7 0C 00 00
II ?? ?? ??
This looks like the form count. Maybe it uses 4 bytes? Probably does, but need confirmation.
// ======================================================================================
//
// ======================================================================================
I tried to duplicate a reference, and I got an error while loading:
Duplicate form ID (01 00 0C E9) encountered.
Then I got this error:
SetFormID bashing entry in form ID map at 01 00 0C E9.
Form basher: type REFR_ID
Bashed form: REFR Form (01 00 0C E9) to STAT form 'ARFloor03' (00 03 45 B3)
in Cell 'aaaMyDungeon' (01 00 0C E6).
Then this error:
Form counts don't match.
File = thegame.esp
Forms loaded = 10
Forms in file = 9
Do you want to correct the file header?
The .esp loaded fine, and I saw my duplicate reference. Awesome.
The second time I loaded, I got only the first two errors, not the third one.