[Tool] GD save file editor

Hi there!

What mamba said is accurate. What you want to use is the “level” command.
https://odie.github.io/gd-edit-docs/commands/#command-level

All you need to do is to provide it the level you want your character to be, it will adjust your character’s

  • level
  • experience points
  • attribute points
  • skill points

to the correct values.

So in your case, you just do this in the editor:

level 65

Hi, thanks a lot for making this tool. I use it regularly and it saves a lot of time.

Is there a way to search for an item across all characters instead of loading each of them individually? If not I would greatly welcome such a feature. Thanks!

Hi there!

Can you describe briefly how you might use this kind of feature? What makes you want to search for an inventory item across characters? If you can briefly describe your workflow, or how you’re using the editor now, it’ll help me understand how to go about putting such a feature in.

Thanks!

Sure! I’m not using any other tools to manage my items for all characters. So everything is spread out across all of their stashes and bags. I’ve tried GDStash but frankly find it to be confusing and don’t quite trust it with my items. It also doesn’t have the particular feature I’m looking for.

Quite often there’s a need for a particular item. One way is to check all five stashes and six inventory bags of every character. Gd-edit fortunately makes it possible to find items much more quickly. But what’s keeping it from being the ultimate tool for this purpose is that the search only works for one character at a time, making it slow and still somewhat tedious.

TL;DR: A way to use the “find” command without loading a character would be much appreciated.

anything in particular you find confusing ?

It also doesn’t have the particular feature I’m looking for.

because you are supposed to store your items in the tool, not in mules and then search across those :wink:

Howdy!

The new version adds the “find all” command. It works in exactly the same way as the “find” command, except it will search through all the character files the editor can find. This includes the local and cloud save directories, as well as anything configured via “savedir”.

It looks like this when you run it:

> find all steel

character: <path/to>/_Odie/player.gdc
Haunted Steel: inventory-sacks/0/inventory-items/76
Chilled Steel: inventory-sacks/1/inventory-items/13
Chilled Steel: stashes/0/items/48
Blessed Steel: stashes/0/items/89

character: <path/to>/_AnotherChar/player.gdc

I did minimal testing on this, but it should work! Lemme know if you run into any issues!

This is awesome! I’ve been using it a lot in the last couple of weeks and it works flawlessly. No bugs to report so far, but I’ll let you know if I find any. Thanks a lot.

Hello, I am using latest version of gdedit (0.1.7.-SNAPSHOT) with latest Grim Dawn 1.0.6.1 and I have problem loading my character.
I have char on Veteran difficulty. After configuring the gdedit with game and save dir, I tried loading my char with following error:

Please tell me what am I doing wrong.
Thanks

Hi there. I am new to this tool so its possible this is my user error.

What happened is, I followed the guide precisely, loaded my character’s save file correctly

then used the command: set inv/0/items “sacred hammer of eternal wrath” as shown in the example, just to see if it worked.

I entered the ‘w’ command to save my changes.

Then I closed the editor and I loaded my game…

:confused: There was nothing new in my inventory. :confused:

My inventory was mostly empty so it’s not a space availability issue.

If anyone can guide me so I can add gear (sometimes drops are stingy and I feel like I deserve a better item after a certain point >.<) I’d prefer to have them added to my inventory because I’m worried about wiping out my currently equipped stuff.

Will it work in the regular campaign?
Do I need to run a custom game for this to work?
And will it work during multiplayer?
How do I learn what the correct prefixes etc are?
Is there an existing database of gear names I can just type in easily without setting my own suffixes etc?

I’m sure someone else has already asked somewhere on this thread but its 72 pages long… lol so sorry in advance if these questions are redundant, that’s a bit too much searching for me. :stuck_out_tongue:

Hi,

I have found GDStash : http://www.grimdawn.com/forums/showthread.php?t=23414 to be a great tool and will do what you want and has a very user friendly GUI as well as a comprehensive manual (idiots guide).

All I will say about GDStash is use with caution it has the ability to really ruin your game by giving you everything you want plus more so use with caution.

Regards

Hi there!

After running

set inv/0/items “sacred hammer of eternal wrath”

What did the editor print out? The editor will either print out the specifics of the item created, or say the inventory is out of space, or it will say it could not create the exact item you wanted.

One thing you might want to try is to make sure that you quit out of the game before writing out your character file. I seem to remember it’s not quite enough to just quit to the main menu.

As for your other questions…
Yes, it will work in the regular campaign. It should also work if you’re playing a custom game, though you’ll need to use the “mod pick” command to help the editor access the right additional game db files.

Yes, it will work for multiplayer.

The editor does have ways for you to explore and search the game db to find the affixes and items you might be interested in. I have to say it’s not particularly user friendly. I think you’d be better off using GDStash or Grimtools. Lemme know if you really really really want to try using the editor for this. I can write up a short post on how you might do this with the editor.

Friendly UI -and- and idiot’s guide? Hot damn, sign me up! I read a little about this after you recommended it. Does it really have a huge database of every item in the game and I can just import them to my inventory at will? And it works with the regular campaign mode in online play? If so: AWESOME

:smiley: now to get some sleep and test it out tomorrow. I’ll try not to go overboard. I play a lot of Borderlands so I’ve learned my lessons with save file editors in not giving yourself too much or it ruins the fun.

It printed a long list of things. I’ll try running it again today and copy the text is generates.

Both Steam and Grim Dawn were closed out when I ran the tool.

Thank you for taking the time to answer my other questions!

yes please!!! :smiley:

Alright so I found GD stash, got the idiot’s guide and loaded it up. I’ve successfully enacted a few edits! Woohoo! This is great!!!

However, what I can’t figure out is, once I add items to the Stash Transfer tab, how to I get them into my in-game character inventory from there?

Any help would be awesome

Well, okay… Summoning Wall o’ text…

There are two ways to explore the game database to find the prefix you might be interested in.

  1. “db” command
    This lets you walk through all records in the database by path. It’s able to just match the path “partially” also to help reduce typing. If you give it enough info in the path to uniquely identify 1 record, it will show you the contents of that record.

For example:


> db r/items/affix

records/items/lootaffixes/broken
records/items/lootaffixes/completion
records/items/lootaffixes/completionrelics
records/items/lootaffixes/crafting
records/items/lootaffixes/prefix
records/items/lootaffixes/prefixunique
records/items/lootaffixes/suffix
records/items/lootaffixes/suffixunique

8  matches

> db r/items/affix/prefix

records/items/lootaffixes/prefix/aa000_base_blank.dbr
records/items/lootaffixes/prefix/aa002a_exp_01.dbr
records/items/lootaffixes/prefix/aa002a_exp_02.dbr
records/items/lootaffixes/prefix/aa003a_light_01.dbr
...

2692 matches

As you can see, things can get unwieldy pretty quickly. That’s when you need…

  1. “q(uery) command”

The query command lets you search db records by specifying some kind of criteria to help you explore and narrow down your choices.

Let’s start with something basic where you just want to say “I want to look at all the prefixes”.


> q recordname~prefix
...
0-10 / 2828 matched records

> qn
...
10-20 / 2828 matched records

That query says to retrieve all records where the “recordname” has the word “prefix” in there somewhere. A recordname is just the path to some unique game db record. Remember the path we were seeing in the “db” command outputs? Those are recordnames.

So now we’ve kind of replicated what the db command was doing, except now you have more control. Still, that returned 2828 records. The editor outputs 10 records at a time and you can use “qn” to display the next 10. This is still a lot of things to look though though.

Let’s try to narrow the search a bit. BTW, you can press the up arrow key to get at commands you’ve entered earlier. Helps save a few keystrokes and avoid mistakes. =)


> q recordname~prefix key~offensive
...
1909 matched records

This says to retrieve records that have the string “prefix” in it’s record name, and also if any of the key-value pairs has a key that contains the string “offensive”. Still too many records. Let’s try to be a bit more specific about the effects.


> q recordname~prefix key~offensivepoison
...
67 matched records

This one looks neat:


records/items/lootaffixes/prefix/ao011a_acid_08.dbr
        Class: LootRandomizer
        characterBaseAttackSpeedTag: CharacterAttackSpeedAverage
        itemClassification: Magical
        levelRequirement: 80
        lootRandomizerCost: 3700
        lootRandomizerJitter: 10.0
        lootRandomizerName: Corrosive
        marketAdjustmentPercent: 100.0
        offensivePoisonMax: 16.0
        offensivePoisonMin: 10.0
        templateName: database/templates/lootrandomizer.tpl

The “lootRandomizerName” field says it’s named “corrosive”. Great. We can create something with that prefix.


> set inv1/items "corrosive scrapmetal sawblade"

Item placed in inventory-sacks/1/inventory-items/23

Corrosive Scrapmetal Sawblade

            augment-name : ""
            augment-seed : 0
                basename : records/items/enemygear/skeletons/a01_axe001.dbr
           modifier-name : ""
... [omitted] ...
records/items/lootaffixes/prefix/ao011b_acid_09.dbr
        Class: LootRandomizer
        characterBaseAttackSpeedTag: CharacterAttackSpeedAverage
        conversionInType: Physical
        conversionOutType: Poison
        conversionPercentage: 10.0
        itemClassification: Magical
        levelRequirement: 90
        lootRandomizerCost: 5500
        lootRandomizerJitter: 8.0
        lootRandomizerName: Corrosive
        marketAdjustmentPercent: 110.0
        offensivePoisonMax: 30.0
        offensivePoisonMin: 18.0
        templateName: database/templates/lootrandomizer.tpl


Great, looks like the item has been placed into bag 1 (inv/1/items). The editor will print out the record that represents the axe itself and any records that the item references. This includes a “corrosive” prefix.

It looks like the prefix the editor put on the axe is has a level 90 requirement though. I wanted to level 80 variant. Since the editor told me where it put the new axe, I can just use that information with another command to get the right variant.


> swap-variant inv/1/items/23 prefix

Pick a variant for the prefix-name of Corrosive Scrapmetal Sawblade

1) records/items/lootaffixes/prefix/ao011a_acid_01.dbr
  lootRandomizerCost : 200

2) records/items/lootaffixes/prefix/ao011a_acid_02.dbr

3) records/items/lootaffixes/prefix/ao011a_acid_03.dbr
  levelRequirement : 16
...
8) records/items/lootaffixes/prefix/ao011a_acid_08.dbr
    levelRequirement : 80
  offensivePoisonMax : 16.0
  offensivePoisonMin : 10.0
... [omitted] ...

> 8

The editor prints out a big list of possible variants for you to choose from. I found the level 80 one I wanted. It was listed as #8. Entering 8 in the command prompt confirms the choice.

It’s a bit unfortunate that the editor doesn’t print out anything after that command. But you can confirm that the item has been changed by doing


> show inv/1/items/23
...
records/items/lootaffixes/prefix/ao011a_acid_08.dbr
        Class: LootRandomizer
        characterBaseAttackSpeedTag: CharacterAttackSpeedAverage
        itemClassification: Magical
        levelRequirement: 80
... [omitted] ...

Yep, looks like that’s the one. Hitting “w” writes out the character file as usual. You’re free to enjoy your new axe. =)


If you made it here…
Congratulations! Determination +1 for you!

Commandline tools do look scary. The custom “query language” shown here certainly doesn’t help. But for item creation, I think it can hardly get any more straightforward than just typing in the name of the item and getting what you want.

Anyway, if you do want to keep trying this editor, don’t forget to use the “help” command. You can also find docs on the commands here: https://odie.github.io/gd-edit-docs/commands/

Happy Gaming!

I’ve got a similar problem to what PathofChaos (might) be dealing with. I’m getting a brick of error codes when trying to run a set inv/etc. Here’s the feedback from the program:

> set inv/4/items "Empowered Soiled Trousers"

Caught exception: Map failed
java.io.IOException: Map failed
 at sun.nio.ch.FileChannelImpl.map (:-1)
    gd_edit.utils$mmap.invokeStatic (utils.clj:34)
    gd_edit.utils$mmap.invoke (utils.clj:27)
    gd_edit.arc_reader$make_load_tex_fn.invokeStatic (arc_reader.clj:291)
    gd_edit.arc_reader$make_load_tex_fn.invoke (arc_reader.clj:288)
    gd_edit.inventory$make_dims_lookup_fn.invokeStatic (inventory.clj:55)
    gd_edit.inventory$make_dims_lookup_fn.invoke (inventory.clj:48)
    clojure.core$map$fn__6881.invoke (core.clj:2726)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:49)
    clojure.lang.RT.seq (RT.java:525)
    clojure.core$seq__6422.invokeStatic (core.clj:137)
    clojure.core$some.invokeStatic (core.clj:2673)
    clojure.core$some.invoke (core.clj:2665)
    gd_edit.inventory$texture_slot_dims.invokeStatic (inventory.clj:90)
    gd_edit.inventory$texture_slot_dims.invoke (inventory.clj:87)
    gd_edit.inventory$item__GT_dims.invokeStatic (inventory.clj:158)
    gd_edit.inventory$item__GT_dims.invoke (inventory.clj:148)
    gd_edit.inventory$fit_new_item.invokeStatic (inventory.clj:202)
    gd_edit.inventory$fit_new_item.invoke (inventory.clj:197)
    gd_edit.commands.item$place_item_in_inventory_BANG_.invokeStatic (item.clj:481)
    gd_edit.commands.item$place_item_in_inventory_BANG_.invoke (item.clj:467)
    gd_edit.commands.item$set_item_handler.invokeStatic (item.clj:539)
    gd_edit.commands.item$set_item_handler.invoke (item.clj:515)
    gd_edit.command_handlers$set_handler.invokeStatic (command_handlers.clj:676)
    gd_edit.command_handlers$set_handler.invoke (command_handlers.clj:630)
    gd_edit.core$fn__20636.invokeStatic (core.clj:65)
    gd_edit.core/fn (core.clj:65)
    gd_edit.core$repl_eval.invokeStatic (core.clj:194)
    gd_edit.core$repl_eval.invoke (core.clj:152)
    gd_edit.core$repl_iter.invokeStatic (core.clj:214)
    gd_edit.core$repl_iter.invoke (core.clj:208)
    gd_edit.core$repl$fn__20722.invoke (core.clj:222)
    gd_edit.core$repl.invokeStatic (core.clj:221)
    gd_edit.core$repl.invoke (core.clj:217)
    gd_edit.core$start_editor.invokeStatic (core.clj:519)
    gd_edit.core$start_editor.invoke (core.clj:511)
    gd_edit.core$_main.invokeStatic (core.clj:546)
    gd_edit.core$_main.doInvoke (core.clj:528)
    clojure.lang.RestFn.invoke (RestFn.java:397)
    clojure.lang.AFn.applyToHelper (AFn.java:152)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    gd_edit.core.main (:-1)

I tried using the corrosive scrapmetal blade from above and that worked. Then it worked when trying to add non-Empowered Soiled Trousers.

Is the problem that the “empowered” signifier isn’t working in the way I think it is?

Edit: I forgot to write my changes, so I went back to re-run some of them just to get the base items to screw around with and then got the same error for the plain “soiled trousers”:

> set inv/4/items "soiled trousers"

Caught exception: Map failed
java.io.IOException: Map failed
 at sun.nio.ch.FileChannelImpl.map (:-1)
    gd_edit.utils$mmap.invokeStatic (utils.clj:34)
    gd_edit.utils$mmap.invoke (utils.clj:27)
    gd_edit.arc_reader$make_load_tex_fn.invokeStatic (arc_reader.clj:291)
    gd_edit.arc_reader$make_load_tex_fn.invoke (arc_reader.clj:288)
    gd_edit.inventory$make_dims_lookup_fn.invokeStatic (inventory.clj:55)
    gd_edit.inventory$make_dims_lookup_fn.invoke (inventory.clj:48)
    clojure.core$map$fn__6881.invoke (core.clj:2726)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:49)
    clojure.lang.RT.seq (RT.java:525)
    clojure.core$seq__6422.invokeStatic (core.clj:137)
    clojure.core$some.invokeStatic (core.clj:2673)
    clojure.core$some.invoke (core.clj:2665)
    gd_edit.inventory$texture_slot_dims.invokeStatic (inventory.clj:90)
    gd_edit.inventory$texture_slot_dims.invoke (inventory.clj:87)
    gd_edit.inventory$item__GT_dims.invokeStatic (inventory.clj:158)
    gd_edit.inventory$item__GT_dims.invoke (inventory.clj:148)
    gd_edit.inventory$fit_new_item.invokeStatic (inventory.clj:202)
    gd_edit.inventory$fit_new_item.invoke (inventory.clj:197)
    gd_edit.commands.item$place_item_in_inventory_BANG_.invokeStatic (item.clj:481)
    gd_edit.commands.item$place_item_in_inventory_BANG_.invoke (item.clj:467)
    gd_edit.commands.item$set_item_handler.invokeStatic (item.clj:539)
    gd_edit.commands.item$set_item_handler.invoke (item.clj:515)
    gd_edit.command_handlers$set_handler.invokeStatic (command_handlers.clj:676)
    gd_edit.command_handlers$set_handler.invoke (command_handlers.clj:630)
    gd_edit.core$fn__20636.invokeStatic (core.clj:65)
    gd_edit.core/fn (core.clj:65)
    gd_edit.core$repl_eval.invokeStatic (core.clj:194)
    gd_edit.core$repl_eval.invoke (core.clj:152)
    gd_edit.core$repl_iter.invokeStatic (core.clj:214)
    gd_edit.core$repl_iter.invoke (core.clj:208)
    gd_edit.core$repl$fn__20722.invoke (core.clj:222)
    gd_edit.core$repl.invokeStatic (core.clj:221)
    gd_edit.core$repl.invoke (core.clj:217)
    gd_edit.core$start_editor.invokeStatic (core.clj:519)
    gd_edit.core$start_editor.invoke (core.clj:511)
    gd_edit.core$_main.invokeStatic (core.clj:546)
    gd_edit.core$_main.doInvoke (core.clj:528)
    clojure.lang.RestFn.invoke (RestFn.java:397)
    clojure.lang.AFn.applyToHelper (AFn.java:152)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    gd_edit.core.main (:-1)

Running the query for the corrosive scrapmetal sawblade then for soiled trousers worked again, though. I think the problem is the editor isn’t querying uniques properly until after having been “seeded” by running a non-unique item generation query.

Hi there,

I seem to be able to run the command okay.


> set inv/4/items "empowered soiled trousers"

Item placed in inventory-sacks/4/inventory-items/15

Empowered Soiled Trousers

            augment-name : ""
            augment-seed : 0
                basename : records/items/gearlegs/c019_legs.dbr
... [omitted] ...

Can you run the “diag” command and make sure if the editor is able to find all the files it needs to?

If it reports not being able locate some of the game files, please use the “gamedir” command to tell the editor where to find your game installation.

Please see https://odie.github.io/gd-edit-docs/commands/#command-gamedir for details on this command. =)

Btw, if the stacktrace is pointing at the correct error, the editor failed when it was trying to read texture diemsions of the item being processed, so it can figure out large it is and where it might fit in the inventory.

Somehow, it’s not able to read the texture file. That’s why I guessed the game installation directory wasn’t set.

Checked and it is pointing to the right directory and it did successfully create the items after making the randomized magic one the first time. Here’s the diag result:

> diag

? JVM version: 1.8.0_181-b13
? Game directory exists
? File exists: C:\Program Files (x86)\Steam\steamapps\common\Grim Dawn\database\database.arz
? File exists: C:\Program Files (x86)\Steam\steamapps\common\Grim Dawn\resources\Text_EN.arc
? File exists: C:\Program Files (x86)\Steam\steamapps\common\Grim Dawn\resources\Items.arc

Looks good! The editor should be ready to go!

Interestingly, it stacked all the items on top of each other into the same square of the inventory. They all worked and fit normally into the inventory after picking them up the first time, it was just on generation that they all clumped up.

How strange. Does what happens when you try create the same item but target another inventory bag? Say inv/3/items or inv/2/items? Maybe it’s another item in inv/4/items it can’t find the texture for?

Do you mind sending me your character file?