-
Notifications
You must be signed in to change notification settings - Fork 6
Importing data from mlox #114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I've implemented the
I've also updated the script to strip out I've also investigated whether the mlox The conditions that contain a
Based on other rules in the base file, The rule with the
and the rule with the
|
You seem to progessing with a steady pace, which is intriguing and great to see. One has to wonder how the final result of the conversion process will look like. That being said, I think there is an elephant in the room, which I feel the need to address better now than later. The issue I'm talking about it Let that be as it was, one learning from that was, that a lot of plugins that we had data for, particularly in the I'm not exactly sure if this was the reason, or if we had thought about this before working on the above mentioned task, but since then we have implemented a rule, that we only add new plugin entries, if we know the source of the plugin. We want to know at all times, where a plugin can be downloaded from, if we have data on it, since it is an integral part of working on the masterlists, to be able to reevaluate plugins at a later date. So, if we want to add a new entry to one of our masterlists, we do it like this: - name: 'Tamriel_Data.esm'
url: [ 'https://www.nexusmods.com/morrowind/mods/44537/' ] Or even better: - name: 'Better Propylon Teleport Warp(-Master Index)?\.esp'
url:
- link: 'https://www.nexusmods.com/morrowind/mods/46364/'
name: 'Pikas Miscellaneous Mods' Looking at mlox_base.txt there are currenly
These numbers don't necessarily need to be absolutely correct, but it does show the discrepancy. Now, does finding plugin sources for many thousands of plugins sound very appealing to me? No, of course it doesn't. But the question really becomes, even if the conversion process is done and the result looks kind of neat - how much of that converted data actually connects to plugins, that are still available to this day? And how much converted data is for plugins, that are long since gone? I really would like to see help from the community for this. We really would need people, experienced Morrowind modders, to help us identifying where plugins come from - or which plugins are no longer available anywhere. All that being said, to have a starting point, I have gone through Nexus Top 60 Mods and put together the following list of plugins, that currently are not in LOOT's masterlist, but in Plugins - name: ''
url:
- link: 'https://www.nexusmods.com/morrowind/mods/47392/'
name: 'Morrowind Crafting'
Morrowind Crafting 2-1.esp
Morrowind Crafting Equipment.esp Taddeus' Necessities of Morrowind - name: ''
url:
- link: 'https://www.nexusmods.com/morrowind/mods/52158/'
name: 'Taddeus'' Necessities of Morrowind'
NOM 3.0.esp
NoM Modders Res.esp
NoM_Creatures Loot PHW.esp
NoM_Creatures Loot Standard.esp
NoM_Grass FotG+FF.esp
Vurt's Groundcover for NoM - BC, AI, WG, GL.esp
Vurt's Groundcover for NoM - Solstheim [Lush version].esp
NoM_CoM Compatibility Patch.esp
NoM_IO Compatibility Patch.esp
NoM_LL Compatibility Patch.esp
NoM_MC Compatibility Patch.esp
NoM_MC Lists for Merging.esp - name: 'XE Sky Variations.esp'
url:
- link: 'https://www.nexusmods.com/morrowind/mods/41102/'
name: 'MGE XE' - name: 'Better Bodies.esp'
url:
- link: 'https://www.nexusmods.com/morrowind/mods/3880/'
name: 'Better Bodies' - name: ''
url:
- link: 'https://www.nexusmods.com/morrowind/mods/42226/'
name: 'Better Heads'
Better Heads.esm
Better Heads Tribunal addon.esm
Better Heads Bloodmoon addon.esm - name: ''
url:
- link: 'https://www.nexusmods.com/morrowind/mods/6006/'
name: 'Morrowind Comes Alive'
MCA.esm
MCA - BB Peasant Gowns Addon.esp
MCA - BadKarma Clothing Vendor Addon.esp
MCA - COV Addon.esp
MCA - Hilgya the Seamstress Addon.esp
MCA - Illy's OMG Addon.esp
MCA - Khajiit Diversity Revamped Addon.esp
MCA - TR Addon.esp
MCA - Vampire Realism Patch.esp
MCA - Westly's FCOT Addon.esp - name: ''
url:
- link: 'https://www.nexusmods.com/morrowind/mods/37795/'
name: 'Morrowind Rebirth'
Morrowind Rebirth [Main].ESP
Morrowind Rebirth - Birthsigns [Addon].ESP
Morrowind Rebirth - Game Settings [Addon].ESP
Morrowind Rebirth - Mercenaries [Addon].ESP
Morrowind Rebirth - Races [Addon].esp
Morrowind Rebirth - Skills [Addon].ESP
Morrowind Rebirth - Tools [Addon].ESP
Julan Ashlander Companion 2.02 [For Rebirth].esp
Julan Ashlander Companion 3.0 beta [For Rebirth].esp
Morrowind Patch Project v1.6.6 [For Rebirth].esm
Project Cyrodiil [For Rebirth].esm
Siege at Firemoth [For Rebirth].esp
Skyrim Home of the Nords [For Rebirth].esm
Uvirith's Legacy 3.53 [For Rebirth].esp Better_Clothes Official Version - name: ''
url:
- link: 'https://www.nexusmods.com/morrowind/mods/42262/'
name: 'Better_Clothes Official Version'
Better Clothes_v1.1.esp
Better Clothes_v1.1_nac.esp - name: 'Better Bodies.esp'
url:
- link: 'https://www.nexusmods.com/morrowind/mods/42399/'
name: 'Better Bodies for NMM' - name: 'RealSignposts.esp'
url:
- link: 'https://www.nexusmods.com/morrowind/mods/3879/'
name: 'Real Signposts' Run Faster - Faster Running Speed - name: ''
url:
- link: 'https://www.nexusmods.com/morrowind/mods/42796/'
name: 'Run Faster - Faster Running Speed'
RunFaster-LightSpeed.ESP
RunFaster-LightSpeedx2.ESP
RunFaster-SpeedofSound.ESP
RunFaster-Fast.ESP
RunFaster-Faster.ESP
RunFaster-FasterPlus.ESP
RunFaster-Fastest.ESP - name: ''
url:
- link: 'https://www.nexusmods.com/morrowind/mods/42509/'
name: 'Better Morrowind Armor'
Complete Armor Joints.esp
Better Morrowind Armor DeFemm(a).ESP
Better Morrowind Armor DeFemm(o).ESP
Better Morrowind Armor DeFemm(r).ESP
Better Morrowind Armor.esp
LeFemmArmor.esp
Snow Prince Armor Redux.E
8000
SP - name: ''
url:
- link: 'https://www.nexusmods.com/morrowind/mods/14435/'
name: 'THE Facepack Compilation'
THE Facepack Compilation.esp
THE Facepack Compilation.esm - name: 'Fair Magicka Regen 2.0b.esp'
url:
- link: 'https://www.nexusmods.com/morrowind/mods/39350/'
name: 'Fair Magicka Regen v2B' - name: 'Robert''s Bodies.ESP'
url:
- link: 'https://www.nexusmods.com/morrowind/mods/43138/'
name: 'Robert''s bodies' - name: 'Graphic Herbalism.esp'
url:
- link: 'https://www.nexusmods.com/morrowind/mods/43140/'
name: 'Graphic Herbalism' - name: 'DB_Attack_Mod.esp'
url:
- link: 'https://www.nexusmods.com/morrowind/mods/14891/'
name: 'Delayed DB Attack V2' - name: ''
url:
- link: 'https://www.nexusmods.com/morrowind/mods/6932/'
name: 'Romance English Version'
Bisexual_v10EV.esp
Prostitution_v12EV.esp
Romance_Follow_v10EV.esp
Romance_v37EV.esp - name: ''
url:
- link: 'https://www.nexusmods.com/morrowind/mods/42773/'
name: 'Better Robes'
Better Robes.ESP
Better Robes TR.esp
UFR_v3dot2.esp - name: 'Vurt''s Corals.esp'
url:
- link: 'https://www.nexusmods.com/morrowind/mods/31051/'
name: 'Vurt''s Groundcover' - name: ''
url:
- link: 'https://www.nexusmods.com/morrowind/mods/44921/'
name: 'Skyrim Home Of The Nords'
Sky_Main.esp
Sky_Main.esm
Sky_Main_Grass.esp In the list of plugins above there is one plugin, that demonstrates that mlox's masterlist also contains old data. The mod |
My goal so far has basically been to make it as easy as possible to convert mlox rules to LOOT metadata, which neatly sidesteps any issues of input data quality. I agree that the data quality is a huge issue when it comes to actually maintaining the data though. FWIW, the I agree with the rule of only adding entries for which you have a URL. If we were to import the mlox metadata though, I don't think it would be practical to enforce that for the imported metadata: there's just too much of it (21236 plugin entries and counting). I think we'd need to make a distinction between adding new metadata, and porting existing metadata, where in the latter we'd basically be aiming for parity with mlox as the goal, with the understanding that we could then opportunistically improve on things after that. On the subject of data quality, the messages in mlox have a variety of issues, relative to how we do things in LOOT:
So there's a lot that could be done to improve on the source data, but a lot of that is due to the limitations of the mlox rules format. I wonder if it would make sense for the mlox maintainers/community to have the ability to derive mlox rules from the LOOT masterlist, so they could take advantage of our masterlist structure, and there could be a single source of truth that gets improvements? That's putting the cart a long way before the horse though. One thing that might help with finding plugin URLs and also with matching file regexes to plugin names would be if we could download a dump of the file contents for all the downloads of all the Morrowind mods on Nexus Mods: a dump of all the downloads themselves would probably not be feasible (I don't know how large that would be, but I'm guessing 100s of GBs to a few TB), but each downloadable archive has a "Preview file contents" link that lists the files in the archive, and I'm guessing that's stored somewhere when you upload a file, and that list includes plugin names, so we could associate plugin names to Nexus URLs using that data. That wouldn't help with any mods that aren't on Nexus Mods, but my guess is that it's got most of them. It might be worth us asking Picky or someone else at Nexus Mods if that would be possible. It would also be more efficient for them than serving us all those page views as we manually check page after page. |
I've gone back to checking for cycles because I only ran the check treating all plugin names as literals, which isn't right because some are patterns. Unfortunately, there are cycles when also checking for pattern matches. I ran the checks in 3 stages:
So, what does this mean?
|
I had a quick look at the URLs in the mlox rules, using grep to find and filter them:
That leaves 32 unfiltered URLs that I haven't checked the domains of. Of the URLs that I filtered out:
are domains that have since lapsed, been retired, or otherwise no longer serve their original purpose.
are domains that I got timeouts on (I think I vaguely recall Great House Fliggerty shutting down). Also, Finally,
are domains that still point to modding sites (though individual pages may have moved or been deleted). I'm not doing anything with this info right now, just wanted to record it so I could come back to it in the future. |
Dumping a bunch of links in here as relevant previous discussions:
Also the Morrowind Modding Community Discord server has an mlox-rules channel that people are active in - I might get around to asking about Danae's rules in there tomorrow. |
I've submitted a request to our team. They're quite busy at the moment so this could take a while. |
The import script is now able to convert everything in The script doesn't handle all the possible expression combinations, but it should log a warning if it encounters a rule that it can't fully convert (along with other warnings for all the filenames that use special characters in places LOOT doesn't support that). |
I've tidied up and published the code I used to check for cycles in mlox's rules above as mlox-cycle-finder, and while doing that I realised that I could reduce the complexity of the output graphs some more, so have updated the comment above with new images that are both now small enough for GitHub to render. |
I've asked in Discord about the possibility of getting a license added to Danae's mlox rules repo. |
With the release of LOOT v0.26.0, the metadata syntax extensions I've made to support equivalents to mlox's expressions are now released. While there are still other things that mlox supports and LOOT doesn't, I think what's left is stuff that I don't intend to change:
I've got some other stuff that's higher priority, but intend to come back to this soon. |
Mlox is the most popular load order utility for Morrowind mods. It's inspired by BOSS but takes an approach that's more similar to LOOT (IIRC the two were developed independently though, I don't think I've ever looked into what mlox actually does before now), in that it defines load order rules that define the relationships between plugins instead of using a total load order, and then sorts plugins in a graph.
Mlox's base rules (equivalent to LOOT's masterlist) contains a lot of data: there are 7966 rules, 3710 of which affect load order (the rest are for messages). A direct comparison is difficult, for reasons I'll get into, but LOOT's masterlist only contains 80 plugin entries.
(There are also more recent rules at https://github.com/DanaePlays/mlox-rules, but that repo doesn't have a license and I haven't yet asked if it would be OK to port them.)
It would be good if mlox's rules could be translated into LOOT metadata:
Users can just use mlox of course, but there's no mlox library that developers can use to access mlox's data: I'm only aware of mlox itself and plox as existing parsers of mlox's rules file format. mlox's code can't be used to just parse a rules file because it intertwines parsing and evaluation, while plox seems like it's in a better position as a starting point but I think would need changes to be useable as a library.
So, I've written my own parser (currently in the
import-mlox.py
script in themlox
branch) that seems to work - it doesn't follow the mlox documentation, because the docs don't agree with the actual base rules file, and mlox itself allows for more syntax variations than my parser does, but those variations don't seem to be used in practice. I've found that parsing isn't actually that complicated, except when you get to the expression syntax, because it uses expression type delimiters that can appear in filenames ([
and]
), and doesn't delimit filenames except with whitespace (which can also appear in filenames), so it gets a little tricky to tell where one thing ends and another begins.The script I've written parses the rules file into an AST, and then attempts to convert that into a masterlist file. The parsing side is self-contained and just over 400 lines with type definitions, so may be reusable. It doesn't preserve comments, but I had a look at some and very few of them seem potentially useful, so it's probably best to manually port any that are.
The conversion side is more difficult. While mlox and LOOT are quite similar, there are some mlox features that LOOT doesn't support:
after
metadata, 38 forreq
and 649 forinc
. To put that in perspective, that's 1041 warnings of invalid filenames vs. 27657 valid filenames, so although it's a large number it's still less than 4% of metadata entries.version()
condition function also supports extracting conditions from filenames, which LOOT does not, which is also why there are 39 regex warnings for them (if the filenames didn't use regex then they'd have the version hardcoded, so no need to check it). I'd be open to adding another function that does the same thing, e.g.filename_version(regex, version, operator)
.SIZE
predicate that LOOT has no equivalent of. There are 752 warnings about it not being supported. I'd be open to adding afile_size(path)
condition to support this functionality. It seems to be used to distinguish between plugins with the same name: given the choice, I think LOOT'schecksum()
condition function is better for that.SIZE
predicate uses a regex filename, which doesn't make much sense to me, I think that should just be manually replaced with the actual filename of the file of that size, or replace it with a regex file condition, because the message it's attached to isn't very specific anyway.DESC
predicate that LOOT has no equivalent of. This causes 178 warnings (none for regex filenames), and again I'd be open to adding adescription_contains(path)
function to cover this functionality.say
andwarn
levels. I don't see there being enough difference to warrant a distinction between normal messages and "low priority" messages, so I don't see the point of adding another level to LOOT: the script treats "low priority" messages assay
messages.<hide>spoiler</hide>
tags, which LOOT doesn't. The script could convert that to something like<span class="spoiler">spoiler</spoiler>
, but LOOT currently strips out HTML when displaying messages, so that would need to be disabled, and it would also need to have some styling rules added for the spoiler text to actually work as intended. However, there is only one message in mlox's base rules that actually uses the<hide>
tag and I think it would be better just to strip out it and its contents, it doesn't add enough value for the effort to be worth it.The script logs warnings whenever it encounters one of those differences.
Aside from those differences, there's a significant structural difference: LOOT's metadata is generally plugin-centric (e.g. most messages and all load after, incompatibility, requirement, etc. metadata sits within plugin objects), while mlox's is not.
For example, if you've got a
[Requires]
rule you need to parse its expressions to identify which plugins are dependents and which are dependencies, and because both are defined in expressions you can have a single rule defining relationships between groups of plugins that are quite complex (e.g. "this group contains these plugins and one or more of these plugins but only when these plugins don't exist, or when this plugin's version is this value and that other plugin's size isn't this value..."). Because the expressions also decide when mlox should display an error, they also need to be correctly converted to LOOT metadata conditions.The way that mlox messages are displayed (relatively rudimentary compared to LOOT's approach, IMHO) also means that many of the messages are written so that the only make sense if you can see the expressions that they were defined for, which means they need a bit of deciphering. I haven't fully solved that problem in the script, but I think it's doable.
This structure makes the mlox rules much more concise: the LOOT metadata YAML produced by my script is currently more than twice the size of the mlox rules file (and more than 5x the size of the other masterlists!). It also makes it hard to unpick and convert the rules to a more plugin-centric form, so I've been focussing on the simpler expressions and building up to more complex expressions. As it stands, the script can convert about 94% of the rules, leaving 489 in need of manual conversion, which I think is good enough that manual conversion of those is practical (if a bit of a slog). I think I can improve coverage further, but I'm not aiming for 100%.
Aside from that, the formatting of the script's output could be improved:
I'm hoping those improvements can be done in code, rather than manually.
Beyond the ability to translate between the mlox and LOOT metadata formats, it's also worth noting that mlox allows its rules to produce cycles, and will just ignore whichever rule is about to cause a cycle when it applies them at runtime. In contrast, LOOT expects its metadata (aside from group metadata) not to cause cycles and sorting will fail if they do. That means that a straight translation of mlox's
[Order]
rules might end up causing a lot of cyclic interaction errors.I think that's fixable. The good news is that mlox doesn't seem to sort based on any plugin data, so it should be possible to brute-force finding cycles by building a graph out of all the order rules and scanning through that, and once found the cycles can be avoided by making the equivalent LOOT metadata conditional as necessary. I'm not sure how practical that is though. Not relying on plugin data also has the downside that the metadata also includes plugin masters, which is unnecessary for LOOT, but they can't be automatically stripped out without having the plugins to read.
Finally, mlox has NearStart and NearEnd rules that the script translates into Near Start and Near End groups that sit on either side of the default group: this should give similar behaviour, but it probably won't be exactly the same as the rules don't work the same way as groups, and I don't want to add complexity trying to bridge the gap.
So, in summary:
say
messagesafter
,req
andinc
metadata, which I don't want to support. That affects ~ 1041 metadata entries, which is a large number but only < 4% of the total number of filenames added asafter
,req
orinc
metadata.The text was updated successfully, but these errors were encountered: