Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 [2] 3 4

Author Topic: Save Format  (Read 6345 times)

Gakidou

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #15 on: March 27, 2007, 08:41:00 pm »

Ah, nice, ya'll have found the bits that determine if the words in the surname are plural! That'd be a nice thing to eventually have control over... (I find that otherwise respectable names often sound ugly or awkward if both the first and last word are pluralized...)
Logged

flap

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #16 on: March 28, 2007, 01:57:00 am »

First I have uploaded again memorydf.zip. You will see my commented source code.

About the fact that my application does not work on your system : Oups... I have been workign on v0_22_123_23a... The latest version is v0.23.130.23a

I'll correct that tonight.

About the difference between Tsearch and Artmoney, I don't know.

Finally, felling bad about reverse engineering Dwarf Fortress. Well, really the idea is not break some copy protection or steal Toady's code to do something else with our name. As Darwin's says, it is mainly to temporary correct some annoying bugs, or with my exemple of work profile management do a demonstration of how one specific issue in the game could be handled : a proof of concept to help Toady design instead of just saying stuff.

For an other game I wrote an application that way to solve plenty of bugs for server games. The author of the games looked quite happy with that, and really improved a lot the online game play. So really reverse engineering bad/good karma depends on what you do with it.

[ March 28, 2007: Message edited by: flap ]

[ March 28, 2007: Message edited by: flap ]

Logged

Erasmus Darwin

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #17 on: March 28, 2007, 01:11:00 pm »

quote:
Originally posted by flap:
<STRONG>About the fact that my application does not work on your system : Oups... I have been workign on v0_22_123_23a... The latest version is v0.23.130.23a

I'll correct that tonight.</STRONG>


Great!

Anyway, I managed to decode how the last names of the dwarves work.  It starts in position 32 of the structure, and it consists of 4 integers, each 4 bytes long:

(word 1 index) (word 1 subindex) (word 2 index) (word 2 subindex)

Subindex:
0, 1: Noun, plural noun
2: Adjective
3: ? (Prefix, maybe?)
4-8: Verb (foo, foos, fooed, fooed, fooing)

Index goes from 0x00000000 (abbey) to 0x00000482 (COUNSEL/counsellor).  Words are in the order they appear in language_words.txt -- they aren't sorted first.

The important thing is that you have to set the subindex correctly for the word.  For example, if your index is 5, that corresponds to WORD:AGELESS in the word list.  However, the only defined part of speech for AGELESS is ADJ:ageless.  So the subindex has to be set to 2 for anything to show up.

I'll cook up some code tonight or tomorrow that you're welcome to use in the labour script if you want to include full names.

[ March 28, 2007: Message edited by: Erasmus Darwin ]

Logged

flap

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #18 on: March 29, 2007, 06:59:00 am »

I've udated the links.

Also the address where you would find the pointer to the array of pointers to the units (for the latest version) is 0x00ACB3EC.

Yep, thanks for the info. It is one of the first that I am investigating data from a game at the same time has someon else. I really appreciate that (well, I had other cool common projects in the past, but was with people bringing very different hacking knowledge...)

I probably won't update my application before I have some feedback, and eventually next DF version. So it might be a month or two..

Logged

Erasmus Darwin

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #19 on: March 29, 2007, 01:09:00 pm »

Thanks, flap.  I haven't gotten a chance to try things out, but I'm looking forward to it.

Anyway, I got the surname decoder written:  http://angband.org/~erasmus/df/surname.c

It expects to be running from the main DF directory (as it has to be able to find language_words.txt and language_dwarf.txt).  Otherwise, the path needs to be adjusted accordingly.

To use it, call init_surname() to read in all the data.  Then pass to 64 character strings in to lookup_surname, along with the four 32-bit integers that make up the dwarf's surname code.  It'll pass back both the English and Dwarven versions of the names in the strings.

There's also a main() that gets compiled in if you define STANDALONE.  In that case, run it as either "standalone dump" to dump the entire word array or "standalone (first index) (first subindex) (second index) (second subindex)" to get back a corresponding name.

I skipped out on a little error checking here and there because I was in a hurry.  And I'm also a little rusty with C -- too much Perl hacking these days.  Oh, and I only tested it under Linux.  But in theory, it should work fine.

Logged

flap

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #20 on: March 30, 2007, 02:50:00 am »

Ok, I'll put my hands in that a bit later. So this time the address I gave you was usefull ?
Logged

Erasmus Darwin

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #21 on: March 30, 2007, 09:34:00 am »

quote:
Originally posted by flap:
<STRONG>Ok, I'll put my hands in that a bit later. So this time the address I gave you was usefull ?</STRONG>

Very much so, thanks.  I haven't gotten a chance to do more than just look at it with a debugger, but everything seems to look great.  I was able to go for that address to the unit table to the first dwarf without all the crazy searching I normally have to do.

It also looks like the next pointer might indicate the end of the unit array.  Or that could just be coincidence and the next memory structure is located right after the unit array anyway.  I'll have to do some experimenting and see what points where.

Logged

flap

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #22 on: March 30, 2007, 11:30:00 am »

And also, to which extend was my code usefull ? From reading your posts, you seem to know   what you are doing when programming (better than me at last).
Logged

Erasmus Darwin

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #23 on: March 30, 2007, 07:14:00 pm »

quote:
Originally posted by flap:
<STRONG>And also, to which extend was my code usefull ? From reading your posts, you seem to know   what you are doing when programming (better than me at last).</STRONG>

Your code's been very useful.  Without your help, I probably would've given up by now.  Instead, I should be able to get a dwarf teleporter (for saving stuck dwarves) working in the next day or two.

I may have some programming experience, but a lot of this stuff is new to me.  The closest I've come in the past is using a hex editor to change a byte here or there in saved games.  Nothing major and nothing recent.

Logged

Buffered

  • Escaped Lunatic
    • View Profile
Re: Save Format
« Reply #24 on: March 30, 2007, 09:25:00 pm »

Using your code I was able to find and figure out the skill entries, which of course can let the labor assigner assign based on skill.

Also note the way the pointer arrays are read. Add a

#define UNIT_ARRAY_END (UNIT_ARRAY + 4)

and use

while ((arrayUnit+UNIT_ARRAY_NEXT*comp1) < arrayUnitEnd){

to keep things from blowing up.

I wonder how bad this will look. I'm used to clicking on preview a dozen times before posting.

code:

#define ADDRESS_SKILLS   1076
#define ADDRESS_SKILLS_END   (ADDRESS_SKILLS + 4)

typedef struct {
   WORD id;
   WORD level;
   DWORD exp;
   DWORD unknown[2];
} skill_entry;

const char *skill_levels[16] = {
"Dabbling ",
"Novice ",
"",
"Competent ",
"Skilled ",
"Proficient ",
"Talented ",
"Adept ",
"Expert ",
"Professional ",
"Accomplished ",
"Great ",
"Master ",
"High Master ",
"Grand Master ",
"Legendary "
};

const char *skill_names[68] = {
"Miner",
"Wood Cutter",
"Carpenter",
"Engraver",
"Mason",
"Animal Trainer",
"Animal Caretaker",
"Fish Dissector",
"Animal Dissector",
"Fish Cleaner",
"Butcher",
"Trapper",
"Tanner",
"Weaver",
"Brewer",
"Alchemist",
"Clothes Maker",
"Miller",
"Thresher",
"Cheese Maker",
"Milker",
"Cook",
"Grower",
"Herbalist",
"Fisherdwarf",
"Furnace Operator",
"Adamantine Extractor",
"Weaponsmith",
"Armorsmith",
"Metalcrafter",
"Gem Cutter",
"Jeweler",
"Wood Crafter",
"Stone Crafter",
"Metal Crafter",
"Glassmaker",
"Adamantine Worker",
"Adamantine Smelter",
"Adamantine Weaver",
"Leatherworker",
"Bone Carver",
"Wrestler",
"Axedwarf",
"Swordsdwarf",
"Knife User",
"Macedwarf",
"Hammerdwarf",
"Speardwarf",
"Marksdwarf",
"Shield User",
"Armor User",
"Siege Engineer",
"Siege Operator",
"Bowyer",
"Pikedwarf",
"Lasher",
"Bowdwarf",
"Blowgunner",
"Thrower",
"Mechanic",
"Druid",
"Ambusher",
"Building Designer",
"Wood Burner",
"Lye Maker",
"Soaper",
"Potash Maker",
"Dyer"
};


code:

{
   DWORD arraySkills, arraySkillsEnd, addressSkill;
   int compSkill=0;
   skill_entry skill;

   ReadProcessMemory(h_process, (VOID*) (addressUnit+ADDRESS_SKILLS), &arraySkills, 4, &bytes);
   ReadProcessMemory(h_process, (VOID*) (addressUnit+ADDRESS_SKILLS_END), &arraySkillsEnd, 4, &bytes);
   //if(arraySkills) printf("%08x %08x\n", arraySkills, arraySkillsEnd);
   while ((arraySkills + UNIT_ARRAY_NEXT * compSkill) < arraySkillsEnd) {
      ReadProcessMemory(h_process, (VOID*) (arraySkills + UNIT_ARRAY_NEXT * compSkill), &addressSkill, 4, &bytes);
      ReadProcessMemory(h_process, (VOID*) addressSkill, &skill, sizeof(skill), &bytes);
      printf("\t%s%s %d/%d\n",
         skill_levels[skill.level > 14 ? 15 : skill.level],
         skill_names[skill.id],
         skill.exp, (skill.level+5)*100);
      compSkill++;
   }
}


edit: less table-breaking

[ March 30, 2007: Message edited by: Buffered ]

Logged

Erasmus Darwin

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #25 on: March 31, 2007, 11:54:00 pm »

Ok, it's done:

Teleport v 1.0 -- Teleports any dwarves under the selection cursor to a point just outside the mountain.  This is useful when dwarven children decide to climb on your magma smelter (which seems to happen disturbingly often according to some posts I've read).  Since you can't draft the children to trick them into getting off the smelter, and demolishing the smelter seems to lead to them jumping in the magma, this is your best bet for saving them.

http://angband.org/~erasmus/df/teleport.zip

It doesn't use anything we haven't discussed already, so there's not too much point in looking at the source code.  However, I threw it in there for the curious.

Logged

flap

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #26 on: April 01, 2007, 11:27:00 am »

Huhu, nice. I see that a few things are happening there !

Tomorrow, I am coming with an other tiny application : Every few Dward Fortress days (Between 1 day and 1 year), it will pause the game.

I wrote that because I wanted to let DF run, but not miss the winter change of activities for the growers.

I don't have the adress for ht pause in mind, but it is very easy to find : It is DWORD with the value 1 when it is paused, and 0 when not.

Also to know how time has been spend, I haven't been able to find the date, but I have found a number wich increases by 1 every cycle (when you pause and press "."). That figure retsart at 0 every time you reload a saved game.

Logged

Fieari

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #27 on: April 01, 2007, 11:39:00 am »

Could that have something to do with the adamantine endgame?
Logged

Erasmus Darwin

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #28 on: April 01, 2007, 02:16:00 pm »

quote:
Originally posted by flap:
<STRONG>Also to know how time has been spend, I haven't been able to find the date, but I have found a number wich increases by 1 every cycle (when you pause and press "."). That figure retsart at 0 every time you reload a saved game.</STRONG>

I can't find the month or day, but 0xAA91E0 seems to be the year.  I haven't double-checked to make sure it doesn't jump around, but it looks like it's where most of the stable addresses are.

Logged

flap

  • Bay Watcher
    • View Profile
Re: Save Format
« Reply #29 on: April 02, 2007, 02:22:00 am »

Yes, the year was easy to find. If you change that value, save the game and reload, it is still new one you wrote (same if you start a new fortress or reclain it : it adds time to the new year). So that's definitaly the good think to look at. But I spent a lot of time with days and month and couldn't find them. (Yet)
Logged
Pages: 1 [2] 3 4