[Tool] GD save file editor

Thank you so much for the help! It’s been years since I used command line so hehe might’ve stumbled a bit.

Now it’s time to figure out how to reset mastery levels. ><

I am a little suprised people use this tool for things that can more easily be done in GD Defiler and GD Stash

  • changing faction reputation
  • rename char
  • switch mastery (can be done by setting points of one to 0 and selecting a new one in GD)
  • change level / XP

Everything posted here that people try to do / are doing is covered by them and probably easier as they offer a UI and do not need typed commands to do so.

I would have expected people to use this for the things that cannot be done in them (there is so much info in the save file that neither GD Defiler nor GD Stash cover everything, but they cover the important / frequent stuff) :wink:

Howdy,

Try this build: https://dl.dropboxusercontent.com/u/3848680/GrimDawn/editor/gd-edit-0.1.2-SNAPSHOT-class-skill-slot-display.exe

When you run the “class” command, it’ll now also show you where you can find that class in your character sheet.

For example:
Running “class” on one of my characters shows this:

classes:
    Shaman (skills/17)
    Soldier (skills/5)

It shows me two classes, and “where they can be found”.
What does that means? Well, if I run the command, “show skills/17”, it shows me:

  autocast-controller-name : ""
       autocast-skill-name : ""
       devotion-experience : 0
            devotion-level : 0
                   enabled : true
                     level : 50
              skill-active : false
                skill-name : records/skills/playerclass06/_classtraining_class06.dbr
          skill-transition : false
                  sublevel : 0

                        10 fields

What we’re after here is the “level” field. That indicates the current mastery level. To change that, run “set skills/17/level <some number here>”.

Hope that works for you!

Well using GD Stash or Defiler didn’t work. Stash couldn’t load anything even if right dirs were defined. Maybe it’s 'cos I’m using GOG and not Steam or there were more changes.

How do I change my dir btw? I’m using GOG version.

If you’re asking how gd-edit deals with directories, they can be changed via “savedir” and “gamedir” commands. There there is currently an issue where “C:\some dir\somewhere” needs to be entered as “C:/some dir/somewhere”. x)

Hi mamba!

You’re right. GD Defiler and GD Stash covers a lot of ground. Thanks for all the effort you put into GD Stash, btw!

This editor was originally meant as a tool for tweaking and generating gear/loot for different builds I wanted to try. It took the whole first post to finally explain how to generate an item! x)

Anyway, regardless of how people are using the editor, I’m glad somebody somewhere has found this little program useful. =)

Hi all!

A new build is ready!
Link: https://dl.dropboxusercontent.com/u/3848680/grimdawn/editor/gd-edit-0.1.2-SNAPSHOT-standalone.exe

  • “savedir” and “gamedir”
    These can now use normal paths. You can now use “c:\path to\directory” like a sane person instead of the previously required “c:/path to/directory”. :slight_smile:

what do you mean by could not load anything ? both GOG and Steam use the same save location (local, not Steam cloud), that definitely is not the problem.

Don’t want to derail this, so if you want help, ask in the GD Stash thread

you are welcome :wink:

This editor was originally meant as a tool for tweaking and generating gear/loot for different builds I wanted to try

interesting, GD Stash does that too so I am surprised that is the itch you needed to scratch :wink:

Anyway, regardless of how people are using the editor, I’m glad somebody somewhere has found this little program useful. =)

oh definitely, that was not to take away from your tool.

When I saw the OP, I was immediately thinking of what could be done with it that the others do not allow…
I checked here from time to time to see if there is demand for something my tool does not have yet, based on what people try to do with yours

What surprised me was that the questions then were about how to do things you already could do in several other tools rather than about how to do more esoteric things the others did not anticipate :wink:

Haha, when I started working on this, I haven’t tried GD Stash. I browsed the screenshot, then skipped over it, thinking it was a stash management tool. x)

Anyway, it turned into an excuse to work on something in clojure. I was pleasantly surprised at how “relatively” easy it was to implement certain features like the query command.

Well, if you ever have any ideas you want to try out, I’m all ears! I think the editor is at a pretty good starting point to implement strange features.

One of the features I wanted to try was to implement a directed search to optimize the character’s equipped gear for some specific traits. Maybe that can be applied to picking skills and devotions also. Then, it might be possible to tell the editor “optimize my character for life leech” and have a character build ready to go. I’m pretty sure this would just about take all the fun out of the game though. =(

one of the pics on the first page is the Crafting tab, maybe I need a better picture then :wink:

One of the features I wanted to try was to implement a directed search to optimize the character’s equipped gear for some specific traits. Maybe that can be applied to picking skills and devotions also. Then, it might be possible to tell the editor “optimize my character for life leech” and have a character build ready to go.

that won’t be easy, a lot of stuff to consider… definitely a nice brain teaser though

I am curious about how you generate weapons, on your first post you e.g. use the example

set weapon-sets/0/items/0 “vampiric legion warhammer of valor”’

the first issue is that affixes, and to an extend items (MIs), come at several tiers, so you have an affix by that name at e.g. level 10, 30 and 50 with increasing bonuses. You overcome this by having an additional parameter for char-level. I assume you use the tier one below the char level then… easy enough

next is that there are different affixes by the same name for different item categories, e.g. for 1H and 2H weapons (2H have higher bonuses), do you take that into account ?

then there are affixes that come in several flavors, ‘of Spellweaving’ can deal Chaos + Fire, Lightning + Vitality and a whole bunch of other combinations, how do you know / does the user specify which one to use ?

finally, not all affixes are allowed on all gear, nor are all combinations allowed, some (most uniques) do not allow any at all, do you consider that ?

With so many details in simply generating one item, generating a whole build (and deciding on what build it should be out of the many combinations there are) will be a nightmare :wink:

Okay… I think our approach and thinking regarding item generation is a bit different. :slight_smile:

Why “set item” exists…
The item generation command isn’t very smart. All it does is to help locate prefix, basename, and suffix, given the name of an item.

Without the command, though, editing an item requires manually querying the database to locate the right records, then manually alter the fields of an item. With the command, create an item is fairly low effort. If someone spots the name of an item they want to try from a build guide, for example, they can get one as fast as they can type the name.

But… does it generate “legal” items?
Well, they’re “legal” in the sense that the game engine should still be able to apply all the affix effects without issue.

Does it follow item generation rules? Not at all. :slight_smile:
Will it generate combinations that the game itself will never generate? All depends on what the user entered.

For instance, the example I used in the original post, “vampiric warhammer of valor”, makes no sense. The “of valor” suffix boosts defense and are supposed to be on leggings or shields. Should a warhammer have the “of valor” suffix? I don’t know, but if that’s the item the user wanted to have, the editor will help make one.

Regarding your questions…
I suppose you were just trying to make a point that character “optimization” is difficult. But just in case… :slight_smile:


Unfortunately, there is no good way to deal with this. The editor tries to take apart the item name to see if it can generate something with a similar name. If a single suffix has versions with completely different effects, there is simply not enough information to infer which one should be picked.

But… even if the editor can’t quite generate the exact variant the user wanted, the user can still mod the item in-place.

For the specific case of “of Spellweaving”…
A quick look at the db shows that there are 420 records that matches the “of Spellweaving” suffix. That’s 105 variations assuming there are 4 tiers to each combination of effects. If the user wants to narrow things down to the exact variant exactly what they want… Well, it’s a pain. But, it can be done!

Try the command:

q recordname~affix name~spellweaving offensiveChaos>0 offensiveLightning>0

It’ll show some records that matches the criteria. The user can then pick one and then set the record name into an item’s suffix field.
Pleasant? No.
Possible? Yes.

I guess this is how I think about the editor. There are low level commands that can be issued to view and change everything. Then there are slightly higher level commands to help get things done without having to do a bunch of manual work all the time. So if the convenience commands should fail for 10% of the uses case, that okay. It’s still speeding up the workflow 90% of the time and making the editor less tedious most of the time. x)


That’s not currently done. Right now, the editor pulls the item name apart and arrived at a list of potential affix and basename records. It then picks the “best match” in each of the lists and turn that into an item.

It’s possible to run a separate filter pass over the potential affixes once the basename best match has been determined. That means for a 2 handed weapon, we can filter out all affixes that do not apply to them, etc. This can also be used to weed out “illegal” affix combinations, I imagine.


Yes! For sure! That’s what makes it fun though? But… it’s also why I haven’t tackled it yet. x)

If I were to implement it, though, I imagine it would make use of A* to basically try out all possible combinations of skills & devotions in some sort of sane order. Game rules and skill/devotion dependencies just turn into potential outgoing branches from a node. There’s no guarantee that a search like this would complete in any sort of reasonable timeframe, but it can technically be done! x)

wait, is it possible,

lets assume the easy case with a single target, like opening that tier 3 constellation with its skill.

first, theres the cost, which is 5 affinity types (a,b,c,d,e) and the devotion points you have (f)

lets say your target requires 10c and 6d

at the start, you can spend a point and get 1 of those types. now, which one do you go to? you can’t say I am going to the ‘c’ or ‘d’ type for sure, since each constellation gives 2 types of point for the most part. you have to check further ahead. for example, opening a constellation, say ‘b’ may very well lead to more ‘d’ points in the end, which we could only know about if we went ahead in branches for x moves.

then, theres the case of path being reversible, i.e. you will start at a constellation, but you can close that later. you may complete 3 different constellations, and once you have your 10a 5b 1c points, use those to open another constellations and close the old ones. If you start following a path and reversing it, you will also need to know when you are going in a loop and not have your algorithm believe its still making progress.(which would be slightly different than a path finding algorithm since your cost changes even when you go back)

most good builds I see tend to close the 1 point ones, and I have seen some people close multiple constellation branches.

so this is like, a* on a 2d grid, where following a path may decreases cost of another path(but only if you have x moves left), and going back a path is actually a different thing than going thru the path for the first time, and each step at a path comes at a different cost(based on the path you followed) and affects the cost of all the other paths, including the ones you couldn’t buy yet, and some paths ahead becoming impossible.

I found this on google images, just a plain tree:

now it will work as if 9 had a different benefit(thus essentially cost), based on if you went with 1>2>5>9 or with 1>2>(open both 5 and 6)>9, and the second version may even end up as “cheaper” (but you can only tell this if you go far enough after that point)

of course in reality picking the relative affinities only will work, but even then, the cost will end up as essentially O(very high)

and maybe you can prepare lists(“if you choose this path, you can end up at these constellations for these costs”, for each few steps), then I can see it working.

but can you actually find the best way of unlocking a few target skills, in a reasonable time with nothing cached?

I may not be making any sense, what did you have in mind?

For devotions only it probably is not all too hard, not sure what structure I would use though, tree seems too generic :smiley:

If you want to pick a certain devotion, you know what your prerequisites are, i.e. how many points of what type. This gives you the possible prerequisite devotions, which narrows them down, potentially by a lot (any constellation not granting the right points is automatically out, any devotion having even higher requirements is automatically out as well).

From the remaining ones, it is a matter of find the shortest path, or most useful path (if you specify the type of constellations you want, e.g. by the type of damage they buff), which really is just another way to specify a shortest path (not just by points spent alone).

You can get 5b points from a constellation with the cost of 4a
Which you can turn it into 6c points by opening another constellation(a constellation may require 1 type, but reward 2 types) and by opening another smaller constellation, you can cancel the first two out.
Like, by making a lot of assumptions you can get it working. And in the game itself, the cases arent as extreme

So yeah, there are 50 constellations, and you can only open a few near the start and near the end of the process, so those parts are relatively easy.

In the middle though, basically you can open anything and go anywhere. What if the constellations type you need comes up after opening 5 of them and closing 4.

I dont doubt this being doable with a map like grim dawns. Though even in this case, I’d be surprised if you managed to find the “best” path for any given target.

Good luck if anyone writes this.

not sure I follow, how do you turn them into something else or cancel them out ? The number of points (Chaos, Eldritch, …) only goes up the more constellations you unlock

I was thinking about writing something similar, how to best spend 50 points where you can specify

  • some constellations you absolutely want to use
  • some criteria (damage type buffs or RRs, etc.) the other constellations should ideally have (the more the better, but if you have to pick one purely for the points it offers, that is ok too)

Did not start on that though :wink:

The number of points (Chaos, Eldritch, …) only goes up the more constellations you unlock

point being, you can also lock constellations, and some people do it. so the best result may be a result can only be obtained by unlocking and locking constellations back in a certain order.

again, in practice the numbers aren’t very high, if you pick 3 constellations as “must have those”, there won’t be much of a choice. unless you are aiming for a type of stat or a single constellations, then the numbers may be high.

consider it a thought experiment of sorts.

also the constellation cost going up higher thing is because they are set as such in the database files, but it could very well not have been the case as well.

Hi Stormcaller!

I’m not sure if I can address your post point by point. I’ll try to describe what I imagine ought to work.

The A* algorithm wouldn’t really be used to just traverse the constellation graph. Instead, we’re using A* to traverse & path-find in a graph that represents all possible states the character might be in as it buys/sells different constellations/stars.

So… a node represents the state of a character after a specific sequence of buy/sell combinations. A branch out of that node would represent “some action” that can be taken to alter the state of the character. That means we can model buying as well as selling. Lastly, we’ll need a way to evaluate the fitness of a build, relative to all other potential builds (that A* has seen).

Running A* on this setup then looks something like… The character starts with 50 devotion points and no devotions purchased. Let’s say A* is given the goal do something like “find a build with the highest dmg output”, encoded as a fitness function. It then starts to try it’s “first move”.

It gathers all possible actions. In this case, it is only to buy one of the 5 starting constellations. How does it pick? Well, it doesn’t pick. It tries them all. It tries them all and discovers 5 other “nodes” or potential builds. It then has the opportunity to choose one of these nodes to continue to explore. How does it choose which node to attempt exploration first? We use that fitness function to figure it out. In this example, say the fitness function just cares about dps. So it calculates the dps for all 5 builds and picks the one with highest dps and attempts to continue it’s exploration of the graph.

Let’s go one more iteration… Both the bottom right and bottom left constellation at the crossroads gives +18 offense. Suppose it tries to buy the lower right “star/constellation” first. It then again gathers all potential actions reachable through that build/node. Let’s suppose it finds 3 potential actions, each leading to a different build/node.

  1. take the first star in the lion constellation
  2. take the first star in the falcon constellation
  3. sell the crossroad star that was just bought

It then, again, tries all 3 of the new builds/nodes. It then ranks all previously encountered builds + the 3 new builds. It’ll find that the build that takes branch 2 results in the “best” build with a +15% dmg. It’ll also find that branch 3 leads back to a build that it’s already seen and closes off any further exploration into that branch.

A* then continues forever to explore the graph until it has either explore all possible builds/nodes or has hit a preset time limit on the search. It can then grab the build with the highest fitness rank, then walk backwards in the graph to tell you exactly how to arrive at that build and what the build looks like in the end.

I sounds like it ought to work. But honestly, I have no idea how long this sort of thing might run, especially given that the fitness function and determining available actions might be “expensive”. Also, A* isn’t very good for “find the optimal answer” tasks. It’s also difficult for A* because it’s hard to tell if taking a branch will definitely lead to a better answer when we’re exploring a space where “attempting to be greedy” doesn’t necessarily help reach the right answer. But at least A* can give you “the best answer found so far” given some bounded time.

One more thought regarding performance… Since the connectivity of the builds/nodes do not change unless the game db/data changes, it should be possible to pre-build the entire graph for storage in, say, a sqlite db. Traversing the graph with new fitness functions should then get a lot less expensive, potentially making search times bearable. x)


Yeah, the search will have to go through a lot of potential builds. It may try to be greedy and fall into a little “pocket” of suboptimal solutions by taking c or d first, and only get out of it after exhausting all builds in that pocket.

Maybe it’ll be good to put in a bit of randomness in how it chooses the next node to expand? That way, it at least has the opportunity to “accidentally” try something better.

Right, selling can be modeled. Though A* will likely choose not to explore those branches/nodes until much much later in the search. Because selling is likely to remove some bonuses, a fitness function will likely rank them lower than other builds. =( Maybe this can be countered by figuring available devotion points into the fitness function? A build with more devotion points has the potential to be better? x)

Lastly, regarding whole character/build generation. I think we might be able to approach skill selection in a similar manner. Once the skills and devotions are picked, then go back and outfit the character with best possible/legal gear. I figure we’d need to separate the search spaces so there is a chance this thing can actually run to completion. x)

Anyway… I think this will be one of those things that’s fun to implement and experiment with. Not sure how useful this will be.

once you pick a path and go till its end, you still don’t know if something else would have been better, so you have to follow all the paths till the end. at least, thats my understanding.

thus essentially, it is not much different than plain brute force – unless you stop at, say, after 3 depth (which seems to be your plan anyway)

I am assuming you can’t have a fitness function, though. Because you’d have to rate different affinities with different fitness ratings or different constellations with different fitness ratings, which depends on your target. this is assuming searching for a single constellation, and with can’t, I mean “that works 100% correctly to give the best result”, I dont doubt you can have a fitness function for each constellation that is based on its possible damage output. Since damage can be calculated, you can probably have a pretty good fitness function. But for a “this constellation will get me closer to my target constellation by x”, x would be hard to find I think. (because of the affinities ahead)

I mean, as far as I understand, doing this will require a ton of (execution)time, no?

Since the connectivity of the builds/nodes do not change unless the game db/data changes, it should be possible to pre-build the entire graph for storage in, say, a sqlite db. Traversing the graph with new fitness functions should then get a lot less expensive, potentially making search times bearable. x)

yes you can do a table that stores that kind of information, but that kinda destroys the point :stuck_out_tongue: since it guarantees you way more time, you can just do a brute force search, and store all the results for every possible target.

Well, its true that to look for the optimal build, it’ll basically have to explore every possibility. But, it’s more useful than a plain depth first or depth first search because it at least attempt to try paths that seem more promising.

I think you can just imagine a fitness function to be a comparison function. When we want to search for a different kind of build, we’d supply a new fitness function. It can be something as simple as comparing the HP of each build when searching for build with highest possible HP. Or it can be something slightly more complicated like searching for highest retaliate dmg, which requires calculating the dmg output of each build first. Or, it can even optimize for several conditions.

We need this to rank different nodes, or partial builds, so we know which node seems like the most promising build and attempt further exploration from that point.

Yeah, it’ll take a long time because we’re not just pathfining on the constellation chat. We exploring all possible actions dictated by the chat and other affinity rules. X)

Think of this basically as pre-generating the graph the algorithm can traverse, instead of generating them on the fly. Different searches will supply different fitness functions which will cause the algorithm to traverse the graph differently and arrive at different results. Just saying if we’re expecting the search take a long time, it’d make sense to cache as much as possible.