You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Generate graphical display of difference between pre- and post- sort orders #377
Back when LOOT was BOSSv3 beta 8, it could generate an image of the plugin graph used to sort the load order. This functionality was removed because rendering the graph image was slow, required the bundling of a separate executable, and the result too complex to easily glean useful information from.
An idea that came up was to save the graph data each time LOOT calculated a load order, and then use that data to produce an image that displayed the difference between the previously calculated load order and the newly calculated order.
As the difference would be much less to render than the whole graph, this should solve the performance problem, and the difference would be of greater benefit in informing users about what changes had occurred than the full graph.
Boost's graph library can output GraphVis files, and a quick search comes up with a bunch of JavaScript renderer libraries that could be used to produce images from them, which would be neater than using a separate executable (and could be done asynchronously with greater ease, so that the whole process was not slowed down).
Something else I just thought of: if this is done, then edges should have a "type" property, to distinguish between priority, conflict, etc. edges, and the edge types should also be displayed in the generated image.
On the prompt to Apply sorting, the plug-in could have it's position before and after sorting displayed in the left panel. Just the position number would not be sufficient though. Maybe an arrow and position change count, with Ɵ for unchanged.
ElminsterAUToday at 04:23
I was going to write a request about that at some point
I would like to see the list basically doubled, with old and new order, and lines connecting the same file.
Ok, build the two lists, then align them as good as possible, finally draw lines between the same mod in both lists if they are not aligned
Just my thought on it, but something built into the UI instead of a generated image might work instead, but I'm not sure if that would be more costly than generating an image. I mean you already have pre and post sort load order when apply is showing.
The second list might not even be necessary.
It would have to show which mods where moved, the direction and how far. While ignoring mods which moved relative to that change.
This could even be extended further to have labels for the rule type which caused the change.
Such as Group, Load after, Master.
Two months ago, we discussed this a bit more in Discord, and Ortham produced a couple more graphs. So let's post the discussion here as well, so that it doesn't get lost.
Ortham:
Hah, maybe I'll take a look at 377 now that the plugin graph has 2/3 fewer edges. Though the image is probably still a crazy number of lines all over the place.
I can cut edges some more, but doing that would probably make things slower again, unless I can think of an efficient way to do it...
pStyl3:
Maybe produce a graph with LOOT as it is right now and then go from there? Whatever the complexity, it wouldn't be too bad to see what such a graph would look like. Maybe we get new ideas on how to iterate on it from there.
Would it look like the graphs that you produced before?
Ortham:
How it looks depends on the visualisation library I use, if I used the same library it would look similar (but with 1/3 the lines).
Getting the data from libloot for a rough stab at it should be fairly straightforward, the main thing is I need to decide what that interface would look like.
Ortham:
Here's the graph of a very small load order, visualised using the same library and algorithm as the groups editor uses.
There's a small problem: I tried to generate one for my 400 plugin test load order, and Chromium killed the page after it ate 1.3 GB of RAM...
I also tried the library I was using a few years ago, and that just gave up instead of crashing.
Ortham:
It managed to finish rendering a circular 'breadthfirst' layout - orange isn't the background colour, that's all lines...
But yeah, if this is going to go anywhere, I need to find a more efficient library...
Kerber
What is that library?
Ortham:
cytoscape.js
Ortham:
Using https://github.com/vasturiano/force-graph now, it uses WebGL to improve performance, so visualisation is feasible, just useless due to the sheer amount of information - and this is with a third as many lines as there would have been a couple of weeks ago!
(ignore that the graph is overflowing its dialog box)
I think I need to try reducing the number of edges in the graph before I go any further with this.
Those graphs include all plugins in the load order, right?
Basically, it's the load order (after a sort, that is).
What about a graph that looks like this:
Each point is a plugin. The size of each point represents the number of factors, why said plugin is in that place (master flag, load after, and so on).
If you right click one of the points, it will look like this:
And if I click on, say "group" it then expands to:
Would any of these ideas make any sense?
I'm trying to come up with a way to hide information if they aren't needed all the time.
Question would also be, if that would make any tangible sense for the user.
Maybe more, if there would be numbers to each node, indicating how many slots the individual plugin went up or down through sorting. Something like this:
Also, if the load order graph would be displayed after sorting, maybe mention it in the header bar
Show Graph | Accept | Cancel
Those 3 graphs you generated above look great, but as you also mentioned, the sheer amount of information makes it difficult to make anything from it.
And even if we assume that the average load order has 100 plugins in it, we still would need to make something out of a load order with 300 plugins and more (maxing out the usual slots + lots of .esl's).
Alternatively:
A right click on a node will reveal all connections to other plugins, with the color of each connection revealing what sort of connection it is (loadafter, group, etc).
And if there is a list of some sort at the side, detailing what colors will represent what (load after, groups, .. ) .. by clicking on said explanation one could maybe expand / collapse every connection of that sort in the load order, for all plugins.
Though I would imagine that expanding/collapsing so much information would probably take considerable pc horse power to do...
Ortham:
Filtering is possible and would help. Displaying all the plugins in a line that is their load order should also be doable, but I'll need to expose more info to do that. I don't think just having displacement numbers would help, it's more interesting to see why something has moved than how far, and anyway how do you tell how far anything has moved? (e.g. have a lot of plugins moved down one position, or has one plugin moved up many positions?)
And yes, this would work better as a "show graph" button when sorting, but was easier to hack in as a separate thing.
I've edited pStyle3's posts above to include the original images that he was referencing inline, since the host he was using stopped serving the images.
I recently experimented again with displaying the plugin graph, by repurposing the groups editor's graph view. However, calculating a sensible layout remains a showstopper: with my 1630-plugin Skyrim SE install, opening the editor causes memory usage to spike over several seconds, and I have to kill the process when it goes above 50 GB.
With a 31-plugin Starfield install, opening the editor takes about 1 second and uses 80 MB of memory, but even with this small load order, the graph produced is busy enough to make it difficult to read:
zoomed in a bit:
So moving to the Qt-based GUI didn't solve the problems I'd seen before (not that I expected it to).
What has changed very recently is that LOOT now has a dialog for viewing the load order changes after sorting:
It shows what has changed in the load order, though it intentionally doesn't show how much a plugin's load order index has changed by, for two reasons:
the change of index doesn't really carry any intrinsic meaning. A plugin could load at index 5 or 500 and have exactly the same impact on your game: what matters is what plugins it's being loaded with, and how it loads in relation to them.
there's no corresponding control over plugin indexes, so if a user is told of a change in index and decides that they don't like that number, they've got no way to directly affect it: it's the plugin data, metadata and existing load order that matter, and the latter only matters in terms of the relative positioning of plugins, rather than their absolute indexes.
The dialog doesn't explain the why of anything. There is more than one why question though, for example:
Why did plugin X's position change?
This can only really be answered by displaying a diff of the whole plugin graph since the last time LOOT sorted the load order, since the change may not be directly related to X. The change must be somewhere in one of the paths that go to or from X, but since every plugin is necessarily connected to every other plugin in the graph, that means the whole graph is in scope.
It's worth bearing in mind that this will only be possible if the current load order was produced by LOOT, otherwise LOOT won't have the graph data to explain it, and the diff will be against some other load order, so there would need to be handling for this case (probably just a "sorry, can't be done").
Why is plugin X sorted after plugin Y?
This can be answered by displaying the path in the plugin graph between X and Y, similar to what's done when there's a cyclic interaction error. Since that's just a linear sequence of plugins, that's easy to visualise.
Why is plugin X positioned where it is?
This is a vague question, but I see it as asking about X's context in the plugin graph. It might be answerable by showing the direct connections for X, but that might not be enough context.
You could show this by displaying a graph view to the side of the plugins list, and clicking on a plugin in the list would add it and its direct connections to the graph view. Clicking on another plugin (in the list or in the graph view) would also add it to the graph view, and so you could build up the plugin graph piece-by-piece until you had enough context. A bit like pStyle's images above, but without displaying the whole linear load order in the graph to start with.
The graph displayed would start off relatively small (though a .esp would load after all .esms, so there could be a lot of plugins even to start with, but only one line per plugin), so the layout shouldn't be too expensive, but that would change quickly as the context displayed in the graph view grows, and would probably soon hit the performance limitations I've seen with even quite small load orders.
This is similar to what's requested in Display plugin dependency graph #837, though I think that's limited to only the hard sorting rules (so no groups, overlaps or tie-breaks).
I'd like to do something in the area of this ticket, but first I think I need to understand which specific questions people have, and which would be most useful to answer.
Activity
Ortham commentedon Jun 15, 2015
Something else I just thought of: if this is done, then edges should have a "type" property, to distinguish between priority, conflict, etc. edges, and the edge types should also be displayed in the generated image.
MacSplody commentedon Sep 26, 2018
Taken from discord
https://cdn.discordapp.com/attachments/473543945188802580/494356108131958784/unknown.png
Just my thought on it, but something built into the
UIinstead of a generated image might work instead, but I'm not sure if that would be more costly than generating an image. I mean you already have pre and post sort load order when apply is showing.The second list might not even be necessary.
It would have to show which mods where moved, the direction and how far. While ignoring mods which moved relative to that change.
This could even be extended further to have labels for the rule type which caused the change.
Such as
Group,Load after,Master.lmstearn commentedon Dec 16, 2018
LO history sounds like a great idea tailoring to such parameters as:
pStyl3 commentedon Sep 4, 2019
Two months ago, we discussed this a bit more in Discord, and Ortham produced a couple more graphs. So let's post the discussion here as well, so that it doesn't get lost.
Ortham:
pStyl3:
Ortham:
Ortham:
Ortham:
Kerber
Ortham:
Ortham:
pStyl3 commentedon Sep 4, 2019
pStyl3:
Ortham:
Ortham commentedon May 9, 2026
I've edited pStyle3's posts above to include the original images that he was referencing inline, since the host he was using stopped serving the images.
Ortham commentedon May 9, 2026
I recently experimented again with displaying the plugin graph, by repurposing the groups editor's graph view. However, calculating a sensible layout remains a showstopper: with my 1630-plugin Skyrim SE install, opening the editor causes memory usage to spike over several seconds, and I have to kill the process when it goes above 50 GB.
With a 31-plugin Starfield install, opening the editor takes about 1 second and uses 80 MB of memory, but even with this small load order, the graph produced is busy enough to make it difficult to read:
zoomed in a bit:
So moving to the Qt-based GUI didn't solve the problems I'd seen before (not that I expected it to).
What has changed very recently is that LOOT now has a dialog for viewing the load order changes after sorting:
It shows what has changed in the load order, though it intentionally doesn't show how much a plugin's load order index has changed by, for two reasons:
The dialog doesn't explain the why of anything. There is more than one why question though, for example:
Why did plugin X's position change?
This can only really be answered by displaying a diff of the whole plugin graph since the last time LOOT sorted the load order, since the change may not be directly related to X. The change must be somewhere in one of the paths that go to or from X, but since every plugin is necessarily connected to every other plugin in the graph, that means the whole graph is in scope.
It's worth bearing in mind that this will only be possible if the current load order was produced by LOOT, otherwise LOOT won't have the graph data to explain it, and the diff will be against some other load order, so there would need to be handling for this case (probably just a "sorry, can't be done").
Why is plugin X sorted after plugin Y?
This can be answered by displaying the path in the plugin graph between X and Y, similar to what's done when there's a cyclic interaction error. Since that's just a linear sequence of plugins, that's easy to visualise.
Why is plugin X positioned where it is?
This is a vague question, but I see it as asking about X's context in the plugin graph. It might be answerable by showing the direct connections for X, but that might not be enough context.
You could show this by displaying a graph view to the side of the plugins list, and clicking on a plugin in the list would add it and its direct connections to the graph view. Clicking on another plugin (in the list or in the graph view) would also add it to the graph view, and so you could build up the plugin graph piece-by-piece until you had enough context. A bit like pStyle's images above, but without displaying the whole linear load order in the graph to start with.
The graph displayed would start off relatively small (though a .esp would load after all .esms, so there could be a lot of plugins even to start with, but only one line per plugin), so the layout shouldn't be too expensive, but that would change quickly as the context displayed in the graph view grows, and would probably soon hit the performance limitations I've seen with even quite small load orders.
This is similar to what's requested in Display plugin dependency graph #837, though I think that's limited to only the hard sorting rules (so no groups, overlaps or tie-breaks).
I'd like to do something in the area of this ticket, but first I think I need to understand which specific questions people have, and which would be most useful to answer.