Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Nightinggale

#46
ModCheck 1.7 has been released.
Quotev1.7 changelog
- Speedboost: cached mod indexes for massive speed boost of some ModCheck internals
- Rewritten the log writing system to give better control/more features to patch writers
- Rewritten error messages to make it easier to find the error
- Changed profiling output. Total on top, one entry for each mod
- All PatchOperation names can now be used starting with both upper and lower case (fixes naming inconsistency)
- Added new mode to LoadOrder. It can now use first and last strings instead of the old approach (which still works)
- Added Sequence operation, which does the same as the vanilla operation, but with ModCheck specific options
- Added logic operations AND, OR, IfElse, Loop and Once
- Added warning/error if outdated versions of ModCheck are being loaded (risk of new vs old conflicts)
- Added a preview logo (thanks to larSyn for drawing it)
- Added support for ModSync RW
- Fix: profiling now displays correct time if the hardware has a high precision timer
- Fix: profiling will no longer cut off the output if you have a lot of patches
- Removed the need to include yourMod and modName unless they are actually used

The best I can do regarding people running multiple versions of ModCheck is to make the DLL aware of it and print a warning if multiple versions are loaded and an error if the newest isn't first. On top of that all harmony code will only trigger in the newest version. In other words if the newest is loaded first, it should work, particularly when the time comes for 1.7 to be the oldest. However it's not great and I will try to avoid minor updates in the future and instead wait and collect for major releases.

The log writing system is completely rewritten. You can now use tags to tell when the string should be used and what kind of output: message(white), warning(yellow) and error(red). You can add verbose to make it only trigger if verbose logging is enabled. Examples: ErrorFail and VerboseMessageSuccess. Works on cached operations and the new ModCheck.LogWrite.

Log writing can now take arguments, like {0} and {1}, which are mod and file being patched respectively. Those two are likely the most useful because that's the strings needed for ModCheck.FindFile. There are 5 such arguments in total.

ModCheck.OR has been added. It's a sequence where it stops at the first operation, which passed and then it will pass itself and only fail if everything failed. You can use it to make a list of FindFile operations if you for some reason want to apply the same patch operation(s) to multiple files.

The changelog will have to do for the rest of the changes for the time being. I plan to rewrite the wiki from scratch. Since this release is fully backward compatible, updating shouldn't break anything and you can continue to use the 1.6 documentation until the 1.7 version is ready.
#47
Quote from: Kiame on May 31, 2018, 07:21:02 PMQuick correction for the code
protected bool isModLoaded(string name)
{
        return ModsConfig.ActiveModsInLoadOrder.Any(m => m.Name.Equals(name));
}


Equals instead of ==
I started researching this and it turns out that == vs .Equals is a hot topic online. Some says it's the same, some says it isn't and some says while it generally isn't, it is when working on two strings. Some says .Equals is slower due to added overhead and some don't. In other words the internet fails to provide a proper answer to this question.

I decided to call both in a loop. While the speed is a bit unstable (expected), all both mostly stayed below 33 ms, hit 32.4 ms multiple times, but none of them went below 32.4. If there is a performance difference, it's hidden in the noise and I'm not going to spend ages analyzing the noise to detect such a minor difference. I added a Dictionary<string, int> and called using ContainsKey. Not counting dictionary building, it managed to do the same in around 6.7 ms. However I suspect the building of the Dictionary takes way longer than a single call, meaning it's an approach for frequent calls.

The next question is what the functional difference is. In this case, apparently nothing. The == is part of the stable release since 1.0 (released on Halloween last year), is well tested and nobody have reported any issues.


One interesting observation I made here is that sometimes a test hit 42 ms. Not 44 or 37, but 42 every single time. I suspect this is the lag from moving the process from one CPU core to another. In case you don't know, modern CPUs move 100% loaded threads around frequently to spread the heat production. Say you have a cooling, which can handle 100W. That's 25W/core if they are all loaded. However if only one is loaded, you can use 60*1+5*3 = 75 W. The problem here is that the cooler can't cool 60W from one core, but inserting cooling periods and you get (60+5+5+5)/4 ≈ 19 W on average. More power allows higher clock speed. In my case single core can work 0.5 GHz faster than when using all cores, which still performs better overall even though it suffers from pauses while changing core. It's one of those issues you have to be aware of while benchmarking and one reason why getting reliable readings can be tricky.

This is getting a bit off topic regarding ChangeDresser and more about how to code (including ChangeDresser), but whatever. If the DLL patching idea works, this thread and patch mod will no longer be needed anyway.
#48
Quote from: Kiame on May 31, 2018, 09:10:20 PM
I think i know how to do it w/o a 'patch mod'. For Change Dresser and Weapon Storage it'd be a huge pain as I'd have to specifiy each method to patch...
That's why I proposed one DLL file for patches to always apply and one for conditional patching. That way it is possible to maintain the simple approach to Harmony inside each DLL file and keep it in the "apply all patches from this DLL file" approach.
#49
I have been wondering about this mod and how it conditionally adds harmony patching. I tried to get ModCheck to load a DLL file conditionally and failed to get it working reliably. Still I don't like patch mods and while conditional xml patching works fine with ModCheck, I'm still on the lookout for conditional harmony patching. I have finally come up with an idea, which I think will do the trick.

protected bool isModLoaded(string name)
{
        return ModsConfig.ActiveModsInLoadOrder.Any(m => m.Name == name);
}

This method is included in ModCheck 1.6 and does precisely what you would think. It checks if a mod is loaded and it compares against the name tag in About.xml. Since it relies on vanilla code only, it should be safe to copy between mods. I imagine it could be used something like this.
static Main()
{
        if (isModLoaded("Mending"))
        {
                var harmony = HarmonyInstance.Create("com.mendingchangedresserpatch.rimworld.mod");
                // rest of the harmony code
        }
}

Now when the DLL is loaded, if Mending is loaded, it will do the same as the existing DLL. If Mending is not loaded, the static constructor will do absolutely nothing. In other words it should be safe to add this to change dresser and it should work even if Mending isn't loaded. You can't merge the DLL files though as it will use all the harmony code in the DLL and as such makes it problematic to conditionally load just some of it. However there is no issues involved in adding multiple DLLs to a single mod. They will be loaded alphabetically.

Now the really big question is if it works. I haven't actually tested it, but based on my experience in this area, I see no reason why it shouldn't work.
#50
Unfinished / Re: [B18] (WIP) ModSync
May 29, 2018, 10:31:15 PM
Quote from: Kiame on May 29, 2018, 10:11:40 PMDo you know if ModCheck uses anything else other than version?
It doesn't and I'm 100% sure because I wrote the whole thing.... well apart from the ModSync version reading code, which is copied with permission  ;)

Quote from: Kiame on May 29, 2018, 10:11:40 PMI was thinking the file would turn into:
Looks good. I don't have to change anything. It will just work even with the current version. That is if the file is still named ModSync.xml, though it would be silly to change that.
#51
Unfinished / Re: [B18] (WIP) ModSync
May 29, 2018, 09:00:14 PM
Quote from: Kiame on May 29, 2018, 03:47:24 AMOriginally i was thinking i'd create a new .xml file in About but now thinking the dialog will hijack the existing ModSync.xml file and reformat it to the new standard.
How about just adding the needed tags to the existing file? Right now ModCheck reads <ModSyncNinjaData><Version> in About/ModSync.xml. If it's moved, then ModCheck would need to be updated to look at the new location, but it should likely look at the old one as well to keep support of mods not having updated yet.

Releasing a new version of ModCheck is a bit problematic because it requires mod owners to update their mods with a new included DLL. In response to this problem I plan to add everything from the TODO list in the next release. If ModSync requires a new approach to version reading, then I will need to include that as well. The problem is that next release is fast approaching and it could be a matter of days and after that I have no idea if/when the next version will be released.

In other words it would be a good idea to decide on a way to store and read the version tag now and then stick to it.
#52
Unfinished / Re: [B18] (WIP) ModSync
May 29, 2018, 01:23:05 AM
I don't get how it's supposed to figure out if the mod is outdated or not. Sure it can detect the newest version on GitHub, but how will it figure out which version is on the HD? If we add a version tag then it will clash with mod owners not having to do anything after initially adding the mod.

Also about version tag. ModCheck can display errors if a mod requires at least a certain version of another mod. To do this, it reads the version tag from ModSync and it assumes it to be readable by Version, meaning it's x.x or x.x.x or x.x.x.x where x is an int. It would be nice if ModSync enforces this version system as well, though if the version number is out of reach for ModCheck, then it doesn't matter anyway.
#53
Tools / Re: ModSync Ninja - Mod update manager!
May 27, 2018, 07:43:50 AM
Quote from: historic_os on May 27, 2018, 06:58:07 AM6. keep updating the project: u'll need to keep updating the project, not just leave it as it is now.
I'm completely with you on this one. However wouldn't it be better to just maintain it as it is right now if the alternative is to shut it down completely? What is the minimum to just keep it running? Somebody paying the bills?

I agree we should aim as high as possible, but it seems to me that right now we are in a situation where we have to take what we can get. Rather than picking the best solution (because it's might not be there), picking the least bad solution would be the way to go. We should also be open to the option of somebody paying the bill and somebody else doing the coding.
#54
I have good news and bad news. The good news is that I have finally made a DLL, which is able to pick which ModCheck DLL to load and it will indeed pick the newest one if there are multiple available. The bad news is that while I can load the DLL this way and call methods from it, I can't get it to work with the xml passing code, meaning it can't find ModCheck.FindFile even if that method is loaded. Even worse, despite my efforts, I can't really tell why, meaning it doesn't appear I will be able to fix it :'(

Right now I can't really think of any other approach than to keep the current system and rely on people to update whenever ModCheck is updated. What I can do is to add code to ModCheck startup, which makes it scan for ModCheck in all loaded mods and print a warning for each outdated and error if it isn't the newest, which is in use. Not ideal, but it's the best solution I can think of.
#55
Tools / Re: ModSync Ninja - Mod update manager!
May 16, 2018, 01:31:57 AM
Quote from: Jaxxa on May 16, 2018, 01:12:26 AMI am thinking that when (if) I get the time I could have a look into how feasible it would be to modify the mod to work without a central server.
My current plan would be that the ModSync.xml file could be modified to include a link to a GitHub Repository, then the current version could be pulled from that. Thus avoiding all centralized hosting and authentication issues.
That's not a bad idea. It's not as good as a central server where you can list and sort mods, but it's far better than nothing. The best solution would be to give it to ludeon and let the server keep running.
I don't even think it would be that hard to code the mod to fetch data from github. After all it's just about downloading the xml file as plain text and it's possible to do that directly from the git repository if given the right url. The problem would be lag if it has to contact a git server for each mod, but it's still better than nothing. If there could be added an ingame button with a link to the github page for each mod (which opens in the browser), then downloading and hence updating will be easier.

Steam is bad for mod distribution because you can't make savegame breaking changes and tell people to update next time they start a new game. That and a bunch of other issues. Steam workshop is not designed for a game with requirements like RimWorld.
#56
Tools / Re: ModSync Ninja - Mod update manager!
May 14, 2018, 09:45:18 PM
This is what I feared when this mod started and is the main reason why a mod update feature should be part of vanilla. Regardless of intensions, modders are working just as a hobby and will have a hard time being reliable enough for important features like this one.
#57
Help / Re: A quick tutorial of xpathing and patching
March 29, 2018, 10:16:55 AM
Quote from: Takashi Yonezawa on March 29, 2018, 01:38:33 AM
Dear Nightinggale.
I've finished the translation. Thanks to your post and permission.
My translation is here.
https://github.com/oramu7524/Mods-for-RIMWORLD/blob/master/A_quick_tutorial_of_xpathing_and_patching_Japanese_translation.txt
A minor, yet important correction: you credited me for writing the first post while it was actually written by minimurgle.
It could also be worth to translate the performance thread or at least mention that // should not be used.
#58
Help / Re: A quick tutorial of xpathing and patching
March 27, 2018, 07:05:13 PM
Quote from: Takashi Yonezawa on March 27, 2018, 03:44:05 PM
May I translate this document into Japanese? There are many Japanese players and modders who need to know this.
Go ahead and translate. My only concern is about keeping it up to date with future releases. You should use a wiki to allow other people to update in the future, if needed. It would also be nice if you post a link here.

I have a half written update for ModCheck, which I will finish when I get time (whenever that is). You should include ModCheck in the translation because it adds some rather powerful modding options. It also adds much faster startup times, but only for mods actually using ModCheck.FindFile.
#59
Quote from: Roolo on March 01, 2018, 11:36:05 AM
Can anyone help me with this? I want to write a transpiler to update some code in the Pawn_PlayerSettings.GetGizmos() method, but I'm running into the same issue as the one Nightinggale reported a few pages back, namely that this isn't so easy for code inside iterators.
I'm a bit confused about this. You mention transpiler, but then you quote something related to a Postfix  :o

The postfix issue was fixed in post #174 on page 12. It turns out that you can solve the issue on a higher level than what was proposed. What I did works well for appending data. I never really tried modifying existing data. That step might cause other issues.

If you are indeed talking about actual transpiler, my experience is that all I had to do was to find somewhere inside the loop code where the stack is empty and then add my own code. I managed to get an easy to write and well working solution by just adding variables to the stack and then call a void method. That way I managed to get a C# method with the variables I need and since it's a void method, it will not pollute the stack and it shouldn't affect the vanilla code whatsoever. It should be possible to expand on this approach and write more complex IL code to affect private data, but I have not had the need for that yet.
#60
Help / Re: A quick tutorial of xpathing and patching
February 25, 2018, 12:36:28 PM
Quote from: Shurp on February 25, 2018, 12:25:40 PM
OK, is any advice in this thread still useable?  Because when I start a document with <Patch> Rimworld immediately complains "root element named Patch; should be named Defs".
Yes it still applies, but you seem to have mixed up Defs and Patches.

There are two different directories to place xml files in. They are called Defs and Patches. All files in Defs needs to have Defs as root. All files in Patches needs to have Patch as root. On load, the game will load the Defs one by one and each time a Def is read, all the patches are applied to that one.