Bertilsson Posted June 24, 2014 Share Posted June 24, 2014 (edited) I'm planning to make a new tool for .INI patching The tool would be a simple vbscript with optional arguments for sourcefolder and targetfolder.(default should be current directory and ..\My Games\XCOM - Enemy Within\XComGame\Config\) Source files are identified by the extension .mini and target file is identified by the name of the .mini file. Example:XComGameCore.mini will target XComGameCore.iniXComGame.mini will target XComGame.ini So basically all that is needed to patch .ini files would be to run the script from a folder with one or more .mini files. The .mini files are not complete .ini files, but instead they only contain instructions what should be changed. For smaller mods this is good because it can be used by multiple mods without conflict (as long as they are modifying different values). For larger mods it should make life a lot easier if a new patch is released since it will still be compatible unless the new patch targets something which is part of the mod. So far I think all is good, but I still haven't decided on the exact notation inside the .mini files and which features should be available. So, right now I'm thinking about the following features and notation, but I am still very open to suggestions: ;Changing unique one-liners like UPLINK_CAPACITY= from 1 to 2 UPLINK_CAPACITY=2 ;Find the kevlar armor and replace it with a complete new line Armors= & kevlar : Armors=( ABILITIES[0]=0, ABILITIES[1]=0, ABILITIES[2]=0, ABILITIES[3]=0, Properties[0]=0, Properties[1]=0, Properties[2]=0, Properties[3]=0, strName="", iType=eItem_ArmorKevlar, iHPBonus=3, iDefenseBonus=0, iFlightFuel=0, iWillBonus=0, iLargeItems=1, iSmallItems=2, iMobilityBonus=3 ); Tac Armor ;The script will search (non-case sensitive) for a line with *Armors=* and *kevlar* and replace with whatever is found after : ;Find the kevlar armor and replace only a few selected parameters Armors= & kevlar : iWillBonus=100, iMobilityBonus=50 ;The script automatically discovers that this cannot be a complete line replacemet and instead updates the individual parameters, if more than 1 they must be separated by comma. ;Modifying the third SAT_HELP_DEFECT line (3) SAT_HELP_DEFECT=0.7 ;Adding a new Armor on the third Armors= line (3/22) Armors=( : Armors=( ABILITIES[0]=0, ABILITIES[1]=0, ... ;3 indicates that the new line should become the third to match the search critera, 22 indicates that it should only be added if the current number of matching lines is <=22. If it is 23 then the line has obviously already been added and the third line will be replaced instead of added. This is to secure that the mod can be applied again and again without issue. ;Adding a new unique line to the end of [XComGame.XGTacticalGameCore] [XComGame.XGTacticalGameCore] (1/1) Something_completely_new=123 Any feature missing?Any suggestion how the notation could be improved? Edited June 24, 2014 by Bertilsson Link to comment Share on other sites More sharing options...
dubiousintent Posted June 25, 2014 Share Posted June 25, 2014 (edited) ...Example:... ;Changing unique one-liners like UPLINK_CAPACITY= from 1 to 2 UPLINK_CAPACITY=2 ;Find the kevlar armor and replace it with a complete new line Armors= & kevlar : Armors=( ABILITIES[0]=0, ABILITIES[1]=0, ABILITIES[2]=0, ABILITIES[3]=0, Properties[0]=0, Properties[1]=0, Properties[2]=0, Properties[3]=0, strName="", iType=eItem_ArmorKevlar, iHPBonus=3, iDefenseBonus=0, iFlightFuel=0, iWillBonus=0, iLargeItems=1, iSmallItems=2, iMobilityBonus=3 ); Tac Armor ;The script will search (non-case sensitive) for a line with *Armors=* and *kevlar* and replace with whatever is found after : ;Find the kevlar armor and replace only a few selected parameters Armors= & kevlar : iWillBonus=100, iMobilityBonus=50 ;The script automatically discovers that this cannot be a complete line replacemet and instead updates the individual parameters, if more than 1 they must be separated by comma. ;Modifying the third SAT_HELP_DEFECT line (3) SAT_HELP_DEFECT=0.7 ;Adding a new Armor on the third Armors= line (3/22) Armors=( : Armors=( ABILITIES[0]=0, ABILITIES[1]=0, ... ;3 indicates that the new line should become the third to match the search critera, 22 indicates that it should only be added if the current number of matching lines is <=22. If it is 23 then the line has obviously already been added and the third line will be replaced instead of added. This is to secure that the mod can be applied again and again without issue. ;Adding a new unique line to the end of [XComGame.XGTacticalGameCore] [XComGame.XGTacticalGameCore] (1/1) Something_completely_new=123 Any feature missing?Any suggestion how the notation could be improved? Interesting idea. May be more difficult to implement. Let me point out some obvious (to me at least) problem areas you will need to overcome. (This is in the hopes you can see your way around them without becoming discouraged rather than trying to dissuade you. Part of my personal "how feasible is this" approach.) 1. Who is your target audience: players or mod creators? If not just creators, then you need to make things as obvious as possible to someone who has no programming experience and has barely figured out how to read the content of the INI. Which means explicit flags in your mini, such as [iNSERT_AFTER],[iNSERT_BEFORE], [DELETE], [REPLACE], [APPEND_TO_BLOCK], etc., along with consistent and clear rules that conform as closely as practical to what they are already used to from Firaxis. For instance, just to illustration some questions I can see arising to your complete line replacement for "Armors= & kevlar : Armors=( ABILITIES[0]=0, ..." example (admittedly without referencing the DGC.INI at the moment): what is the "& " for? If it's part of the line identifier (i.e. "& kevlar" is the search term), does that mean the " : " is your delimiter for that search term, to separate it from the other parameters? Or is the "& " signalling something else? Are spaces otherwise significant, and if only sometimes how do people know or convey that? Is the search term automatically prefixed to the remainder of the statement, or should everything after the search term be a complete, 100% replacement? I realize this adds much more of a burden on you as the programmer, but never underestimate the ability of the end-user to fail to comprehend (much less read) the instructions. The programmer is the only one who is going to be able to prevent or repair the consequences. "An ounce of prevention ..." and all that. 2. In that same example, the ("ABILITIES[0]=", etc.) are array entries. How do you plan to prevent the replacement from having an incorrect number of entries? How can you prevent a "non-programmer" with no concept of arrays from adding too many or too few in the replacement line? While you will have to make such internal checks regardless, it would certainly be preferable to make it clear to the end-user in the mini itself when they have an unbalanced number of parameters of any type. (Embedded templates are one way to accomplish this.) 3. In the ";Adding a new Armor on the third Armors= line" example: what if another mini added a 23rd item. Then either this one or the other mod would fail (depending upon install order) because they would be assuming they were the one that added the 23rd item. Lots of perils with assuming the mini "knows" the correct number of current entries purely on the basis of numbers. (I don't see how you can avoid having to perform some sort of check for prior existence for the presence of any mini "item" line, but perhaps you can.) Those were my initial impressions. I wish you success with this. -Dubious- Edited June 25, 2014 by dubiousintent Link to comment Share on other sites More sharing options...
Bertilsson Posted June 25, 2014 Author Share Posted June 25, 2014 No need to apologize, that was exactly the type of feedback that I requested. Making it more structured would make things easier for myself but the main focus is not to make it simple for myself but for the user. However there is actually more structure than meets the eye in my example, I just didn't do a very good job of explaining it. The structure is really as simple as this:Seach critera : Target data (replace) The search criteria is one or more wild card search words (separated with '&') which will be used to identify which line to edit.Target data is the complete replacement line you want to enter. If search critera is not unique, such as some difficulty level settings, then you can add (#) to indicate that you are interested in the second, third, ... matching line for that search critera. This far we have a very simple to use notation, Find this : Write this In order to be more user friendly it allows the following special case where search criteria is omitted and only target is provided:Steam_Vent=3 This is intended to make it child easy to use for simple edits and should increase the readability of the mini file. The next special case is that you don't want to enter the full target line if you only want to edit something small on that line, ie iWill=10 or whatever inside a long array. So you are allowed to enter target data as one or more array objects separated by ',' the same way as the original ini file does it, instead of complete target line. This allows much better readability and modder friendliness, but more importantly, doesn't unintentionally overwrite other parameters in that line. A mod that increase mobility for armors can now co-exist with a mod that increase will for the very same armors. (Internally the tool will check if the beginning of the target data matches the beginning of the targeted line and assume it to be partial edits otherwise. Then it is only a simple matter of chopping up the contents of the target data and the contents of the array and match/replace it in the same way as Steam_Vent=3, but separated by , instead of line breaks). So far, we have now covered all possible replace existing row, use cases that I can think of. The only thing missing is ability to ADD stuff and delete stuff. The ability to delete stuff has been ignored since I cannot think of one single use case where that would be necessary. The ability to add stuff, almost went down the trashcan for the very same reason, except I can think of a few isolated scenarios, which probably all have in common that they are part of long war or are at least extremely rare to find outside that mod. First of all, if a new line is to be added, then it needs to be clarified in which [sECTION] of the ini file should it be added? If you want to add something completely new like Backup_Steam_Vent=3 I could allow it to be as simple as:[sECTION] : Backup_Steam_Vent=3 Ok, so Backup_Steam_Vent does not exist, this must mean that user wants to add that to this section... But does the user mean the beginning of [sECTION] or the end of [sECTION]? Does it even matter? Technically it shouldn't matter in most cases except for difficulty settings and similar where it actually does matter and in those cases neither is sufficient. And what happens if user accidentally enters Stean_Vent=3, will this be a bug in the mod where original value is not updated and Stean_Vent is added? So now suddenly we have the following issues, it must be clear that user, really wants to implement the very rare exception of adding stuff and it must be clear exactly where it should be added and on top of this it must be repeatable, so that a new version of the mod will not accidentally add unwanted extra lines every time the mod is installed. AddBefore and AddAfter commands where indeed considered for this but they both risk failing on repeatability if used multiple times with same search critera.So bascially what I would need is AddBeforeAfterOnlyIF, commands and now we are guaranteed to make it so complex that the learning curve will make it unlikely that anyone, including myself, would ever attempt to use it... and we still haven't approached the possibility to add new parameters inside existing arrays. Based on this I decided that I wanted to only allow adding new rows and ignore the ability to add parameters to existing objects, at least to begin with. What I figured would be least complicated would be to expand the (#) match indicator to (x/y) which would only be relevant in the rare situation that someone wants to add something and once learned how to use it would be very simple to use again. As to multi mod conflicts.Yes, if two mods both want to expand the same "Matrix" or "vertical array" or one of them expands it to mess up the order for the other then this is pretty much already an unresolvable scenario and one of the mods simply needs to be adapted to be compatible with the other one. As to number of objects/parameters inside a single line array, as long as the tool only allows replacing existing ones, there really is no risk of messing up the number of parameters. Link to comment Share on other sites More sharing options...
dubiousintent Posted June 26, 2014 Share Posted June 26, 2014 Well, all I can say is you are well on the way to having developed the documentation you are going to need to provide with it. :devil: -Dubious- Link to comment Share on other sites More sharing options...
Recommended Posts