***************************  Script_Rules.txt Content  ***************************************
	- Script Members Description
	- Advanced Script Rules / Tips
	- DEPRICATED (do not use)

	- See 'General Information on AMUMSS.txt' for more information about AMUMSS
	
	- NOTE: we are using LUA 5.3
		Can be used in the script:
			- All the standard lua syntax (section 3 of https://www.lua.org/manual/5.3/),
			- All available standard functions in {string, math, table}
			- Also io.open, io.input, io.type, io.read, io.lines and io.close
			- And os.clock, os.date, os.difftime, os.getenv, os.time, os.tmpname
			- Plus {assert, pairs, ipairs, print, tonumber, tostring, type}

	- Some definitions/comments:
		- in this document, "==" means "is equal to"
		- EXML files are closely related to XML files but are not the same
		- the TOP level is always <Data template="something"> AND this value is NOT used by the tool
		- Each level ends with </Property> except the TOP level which ends with </Data>
		- Every new level (SECTION) starts with a line ending in [">] (never with a line ending in [" />])
		- a SECTION is defined as "all the lines" from the beginning [">] to the ending </Property> line
			(so a SECTION is at least 3 lines long)
		- a SECTION can have one or more sub-SECTIONs

	- Generally using the "ModScriptCollection\LearningExamples\StandardSchemeExtended.lua" script
		in the ModScriptCollection\LearningExamples folder as an example.

***************************  Script Members Description  ****************************
Simplified hierarchy of the 'NMS_MOD_DEFINITION_CONTAINER':

		NMS_MOD_DEFINITION_CONTAINER
			MOD_FILENAME
			MOD_AUTHOR
			MOD_DESCRIPTION
			NMS_VERSION
			MOD_BATCHNAME
			ADD_FILES
				FILE_DESTINATION
				EXTERNAL_FILE_SOURCE
				FILE_CONTENT
			MODIFICATIONS
				MBIN_CHANGE_TABLE
					MBIN_FILE_SOURCE
					REGEXBEFORE
					REGEXAFTER
					EXML_CHANGE_TABLE
						SPECIAL_KEY_WORDS
						PRECEDING_FIRST
						PRECEDING_KEY_WORDS
						SECTION_UP
						WHERE_IN_SECTION
						SAVE_SECTION_TO
						SAVE_SECTION_ACROSS
						USE_SECTION
						MATH_OPERATION
						INTEGER_TO_FLOAT
						REPLACE_TYPE
						VALUE_MATCH
						VALUE_MATCH_TYPE
						LINE_OFFSET
						VALUE_CHANGE_TABLE
						ADD
						REMOVE

NMS_MOD_DEFINITION_CONTAINER = {
	- Always REQUIRED
	- a table containing one or many tables
	- The Master Table (it defines the script that will be processed by this tool)
	- the order of members is not important
	- members of NMS_MOD_DEFINITION_CONTAINER are:
		- MOD_FILENAME		REQUIRED	- a STRING
		- MOD_AUTHOR		OPTIONAL	- a STRING
		- MOD_DESCRIPTION	OPTIONAL	- a STRING
		- NMS_VERSION		OPTIONAL	- a STRING
NEW		- MOD_BATCHNAME		OPTIONAL	- a STRING
		- ADD_FILES			see below	- a table
		- MODIFICATIONS		see below	- a table containing one or many tables
}

MOD_FILENAME = {
	- Always REQUIRED
	- if MOD_FILENAME is not found, it will default to 'GENERIC.pak' and a WARNING will be issued
	- a member of NMS_MOD_DEFINITION_CONTAINER
	- a STRING, the name of the pak file created by the tool
		ex.: 	["MOD_FILENAME"] 		= "ZZZsome.pak",
		(unless a combined mod is created, then the name may not be used)
	- maximum name length is 106 char + .pak
}

MOD_AUTHOR, MOD_DESCRIPTION and NMS_VERSION = {
	- These members are all OPTIONAL
	- members of NMS_MOD_DEFINITION_CONTAINER
	- a STRING
		ex.: 	["MOD_AUTHOR"] 			= "ItIsMe",
				["MOD_DESCRIPTION"]		= "anything goes",
				["NMS_VERSION"]			= "1.77",
	- Used for reference only
}

MOD_BATCHNAME = {
	- is OPTIONAL
NEW	- it supersides the standard AMUMSS name when more than one .lua scripts are present
	- if MOD_BATCHNAME is not found, it will default to AMUMSS name generation
	- a member of NMS_MOD_DEFINITION_CONTAINER
	- a STRING, the name of the pak file created by the tool
		ex.: 	["MOD_BATCHNAME"] 		= "ZZZsome.pak",
	- maximum name length is 106 char + .pak
}

MODIFICATIONS = {
	- a member of NMS_MOD_DEFINITION_CONTAINER
	- a table containing one or many tables
	- can be used with or without ADD_FILES
	- is OPTIONAL when ADD_FILES is used

	- the order of members is not important
	- members of MODIFICATIONS are:
		- PAK_FILE_SOURCE	OPTIONAL and NO LONGER REQUIRED
		- MBIN_CHANGE_TABLE	REQUIRED	- a table or many tables
}

PAK_FILE_SOURCE = {
	- IS NO LONGER REQUIRED
	- a member of MODIFICATIONS
	- (VERY OPTIONAL NOW) the NMS PAK "path and name" involved as a STRING
	- always an original name from the NMS/PCBANKS folder
	- the PAK_FILE_SOURCE "path and name" will be provided (and displayed) by this tool
}

MBIN_CHANGE_TABLE = {
	- a member of MODIFICATIONS
	- a table of MBIN_FILE_SOURCE(s) and EXML_CHANGE_TABLE(s)
		to apply to the MBIN_FILE_SOURCE file(s)

	- the order of members is not important
	- members of MBIN_CHANGE_TABLE are:
		- MBIN_FILE_SOURCE	REQUIRED	- a string or a table or a table of tables
		- REGEXBEFORE		OPTIONAL	- a table of (two STRINGs)table(s)
		- EXML_CHANGE_TABLE	REQUIRED	- a table of table(s) and STRINGs
		- REGEXAFTER		OPTIONAL	- a table of (two STRINGs)table(s)
}

MBIN_FILE_SOURCE = {
	- is REQUIRED
	- is a member of MBIN_CHANGE_TABLE
	- alternate syntax #1: a NMS MBIN path STRING, as in "METADATA\SIMULATION\SCENE\EXPERIENCESPAWNTABLE.MBIN",
		- used to work on this one file

	- alternate syntax #2: a table of NMS MBIN path STRINGS,
		- as in {
				"METADATA\SIMULATION\SOLARSYSTEM\BIOMES\BARREN\BARRENHQOBJECTSFULL.MBIN",
				"METADATA\SIMULATION\SOLARSYSTEM\BIOMES\BARREN\BARRENOBJECTSDEAD.MBIN",
				"METADATA\SIMULATION\SOLARSYSTEM\BIOMES\BARREN\BARRENOBJECTSFULL.MBIN",
				...
			  },
		- used to work on all those files from top to bottom

	- alternate syntax #3: a table of tables of NMS_MBIN_PATH_FILENAMES STRINGS and NEW_PATH_FILENAMES STRINGS
		see NEW_PathFilename.lua for an example of use,
		as in {
				{"METADATA\SIMULATION\SOLARSYSTEM\BIOMES\PLACEMENTVALUES\SPAWNDENSITYLIST.MBIN", "NEWPATH\temp1\temp2\My.GLOBALS.MBIN", Optional_Flag},
				...
			  },
		- this allows you to create a new MBIN file (My.GLOBALS.MBIN) in any folder you like (NEWPATH\temp1\temp2\)
		BASED on an original NMS pak file (SPAWNDENSITYLIST.MBIN)

		Note #1: The create/rename part happens before processing the whole MBIN_FILE_SOURCE section
			- the My.GLOBALS.MBIN file will be identical to the original SPAWNDENSITYLIST.MBIN file
			- the SPAWNDENSITYLIST.MBIN file will be modified by the content of the enclosed EXML_CHANGE_TABLE
			- if you want to modify the new My.GLOBALS.MBIN file, you need to add a new section in MBIN_CHANGE_TABLE
			  with MBIN_FILE_SOURCE now referencing the new My.GLOBALS.MBIN file (see NEW_PathFilename.lua for an example of use)

		Note #2: Optional_Flag can be omitted or ""
			- if Optional_Flag is "REMOVE" then the original file ..\SPAWNDENSITYLIST.MBIN will NOT be included in the mod pak
}

REGEXBEFORE = {
	- is OPTIONAL
	- is a member of MBIN_CHANGE_TABLE
	- is a table of (two STRINGs)table(s)
	- if use, will invoque a regex utility to process the EXML file BEFORE any script processing
	- the table is of the form {{"ToFindRegex","ToReplaceRegex"},...},
		ex.: ["REGEXBEFORE"] =
						{
							{[[((.*Unknown.*)(True))]],[[\2False]]},
							...
						},
	- sed regex rules apply (see https://www.gnu.org/software/sed/)
}

REGEXAFTER = {
	- is OPTIONAL
	- same as REGEXBEFORE, see above
	- if use, will invoque a regex utility to process the EXML file AFTER the script processing
	- the table is of the form {{"ToFindRegex","ToReplaceRegex"},...},
		ex.: ["REGEXAFTER"] =
						{
							{[[((.*Unknown.*)(True))]],[[\2False]]},
							...
						},
	- sed regex rules apply (see https://www.gnu.org/software/sed/)
}

EXML_CHANGE_TABLE = {
	- is REQUIRED
	- is a member of MBIN_CHANGE_TABLE
	- is a table of table(s) and STRINGs

	- the order of members is not important
	- members of EXML_CHANGE_TABLE are:
		- SPECIAL_KEY_WORDS		OPTIONAL	- a TABLE of (one or multiple) two STRINGs
		- PRECEDING_FIRST       OPTIONAL	- a STRING
		- PRECEDING_KEY_WORDS	OPTIONAL	- a STRING or (TABLE of STRINGs)
		- SECTION_UP            OPTIONAL	- a number
		- WHERE_IN_SECTION      OPTIONAL	- a table of (two STRINGs) table(s)
NEW		- SAVE_SECTION_TO		OPTIONAL	- a STRING
NEW		- SAVE_SECTION_ACROSS 	OPTIONAL	- a STRING
NEW		- USE_SECTION   		OPTIONAL	- a STRING
		- MATH_OPERATION		OPTIONAL	- a STRING
		- INTEGER_TO_FLOAT		OPTIONAL	- a STRING
		- REPLACE_TYPE			OPTIONAL	- a STRING
		- VALUE_MATCH			OPTIONAL	- a STRING
		- VALUE_MATCH_TYPE		OPTIONAL	- a STRING
		- LINE_OFFSET			OPTIONAL	- a STRING
		- VALUE_CHANGE_TABLE	OPTIONAL	- a table of (two STRINGs)table(s)
		- ADD					OPTIONAL	- a STRING or [[long multi-line string]]
		- REMOVE				OPTIONAL	- a STRING
}

SPECIAL_KEY_WORDS = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- a TABLE of (one or multiple) two STRINGs
	- "", or {}, or {"",}, ==> all these mean: no SPECIAL_KEY_WORDS to use
			ex.: ["SPECIAL_KEY_WORDS"] = {"","",...},
	- {"Property name1","value1",}, ==> special_key_word pair #1
		that will be used optionally with the PRECEDING_KEY_WORDS to help define the SECTION
		we are looking for
	- One or more pairs can be used of the form {"Property name1","value1","Property name2","value2",...},
	- "Property name1","value1" defined a SECTION#1 AND "Property name2","value2" defined a sub-SECTION of SECTION#1 and so on
	- "value2" here (the last of the "values" when multiple pairs are used) can be "IGNORE" (useful in the case where NMS changes that value later)
		see the script LearnMoreWords.lua as an example...
	- If the line pointed to by the special_key_word pair(s) is found, it will be used by LINE_OFFSET (if any)

	- WHAT ARE CONSIDERED SPECIAL_KEY_WORDS?
		* any line with a Property AND a value
		* where the value is NOT: "", "True", "False" or a number
		* lines with a value like a filename (???.MBIN or ???.xml for example) are now accepted as SPECIAL_KEY_WORDS

	- Works alone or with PRECEDING_KEY_WORDS (see OPTIONAL use below and MiningLaserSpeed.lua for example)
	- If SPECIAL_KEY_WORDS are used, they are processed BEFORE the PRECEDING_KEY_WORDS unless [PRECEDING_FIRST] = "TRUE"
}

PRECEDING_FIRST = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- a STRING
	- DEFAULT value is "FALSE"
	- can have one of these values: {nil, "", "TRUE", "FALSE"}
	- "FALSE" means that PRECEDING_KEY_WORDS will be processed 'after' SPECIAL_KEY_WORDS (the default behavior)
}

PRECEDING_KEY_WORDS = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- a STRING or (TABLE of STRINGs)
	- "", or {}, or {"",}, ==> all these mean: no key_words to search (so search the whole file)
	- {"key1","key2","key3",...}, ==> are a list of key_words inside an EXML
			ex.: ["PRECEDING_KEY_WORDS"] = {"","",...},
	- LEVEL 0 being the whole EXML file SECTION
	- LEVEL key1, key2, ... defined sub-SECTION heads (SECTIONs) in the EXML file hierarchy (the line ends in [">] )
	- Skipping one or more LEVEL can work, specially if you want to specify many sections (see REPLACE_TYPE)
	- works alone and with SPECIAL_KEY_WORDS
	- UNLESS used like in 'ALTERNATE USE' below, PRECEDING_KEY_WORDS are ALWAYS a LEVEL key (the line ends in [">] )

	- 'ALTERNATE USE' of PRECEDING_KEY_WORDS: when using SPECIAL_KEY_WORDS, you can use multiple PRECEDING_KEY_WORDS to further refine
		the sub-section to look for inside the SECTION defined by the SPECIAL_KEY_WORDS.

		If these PRECEDING_KEY_WORDS are not found inside the SPECIAL_KEY_WORDS's SECTION then
			the last PRECEDING_KEY_WORDS will be used to try locate a line inside that SPECIAL_KEY_WORDS's SECTION.
			This single PRECEDING_KEY_WORDS can be any name or value inside that SPECIAL_KEY_WORDS's SECTION (much better if UNIQUE in that SECTION)
			(see MiningLaserSpeed.lua or Multi_PAK_Multi_MBIN_Example_Mod.lua for example)

		If the single "preceding_key_word" word is not found in that SECTION, the whole SPECIAL_KEY_WORDS's SECTION will be used
		(but you probably have a problem with you script at this point!)

********  'Simplified' example EXML with LEVELs and possible keys:

<Data template="GcRewardTable">               	--The LEVEL 0 key (no need to use it)
	<Property name="GenericTable">            		--a LEVEL 1 key (could be the start of a SECTION, this one has no children)
	<Property value="GcGenericReward.xml">          	    --another LEVEL 1 key, start of a SECTION with children
		<Property name="Id" value="VEHICLE_SCAN" />   	    	--is a child, possible SPECIAL_KEY_WORDS pair, NEVER a key
		<Property name="Common" value="Gc...List.xml">	    --a LEVEL 2 key, start of a SECTION with children
			<Property name="Reward" value="GiveAll" />      	--is a child, possible SPECIAL_KEY_WORDS pair, NEVER a key
			<Property name="Count" value="Vector2f.xml">    --a LEVEL 3 key, start of a SECTION with children
				<Property name="x" value="1" />			    	--is a child, NEVER a key
				<Property name="y" value="1" />			    	--is a child, NEVER a key
			</Property>									    --end of a LEVEL /3 SECTION
			<Property name="List" />                        	--is a child, NEVER a key
		</Property>                                   	    --end of a LEVEL /2 SECTION
	</Property>											    --end of a LEVEL /1 SECTION
</Data>                                             	    --end of LEVEL /0

******* End of 'Simplified' example

	- "key2" is allways at the same or a higher level than "key1" in the EXML file hierarchy and so on...
		if (keyi LEVEL) == x; (keyi+1 LEVEL) == x + (0 or more); (keyi+2) LEVEL == (keyi+1 LEVEL) + (0 or more); ...

	- taken together, these key_words 'always' define/point to only one SECTION of lines inside the EXML file

	- ONLY <"start of a level"> line's <"Property name" or "Property value"> info can be used as key_words
		***** see 'ALTERNATE USE' above for "preceding_key_word" exception

	- REMEMBER: Every level starts with a line ending in [">] (never with a line ending in [" />])

	- PRECEDING_KEY_WORDS rarely define a single line in the EXML file
		but the start line of the SECTION found can be used as the base for LINE_OFFSET

	- If that is not enough to narrow down the search for the right SECTION,
		we can use a <SPECIAL_KEY_WORDS pair> to help define the SECTION we are looking for

		- These SPECIAL_KEY_WORDS are defined in SPECIAL_KEY_WORDS (see above)

		- Using NMS_REALITY_GCPRODUCTTABLE.EXML as an example:
			This EXML is madeof a big bunch of SECTIONs all starting with <Property value	="GcProductData.xml">
				They are all inside the <Property name="Table"> SECTION
				So "GcProductData.xml" is NOT a good key_word to use here
				but in the next line or so there is <Property name="Id" value="CASING" /> (and some other lines)
				that can help define the SECTION where we want to make the changes to the EXML
				This is were the SPECIAL_KEY_WORDS "Id" and "CASING" come in play, we add them as SPECIAL_KEY_WORDS
				and this tool will find the line SECTION 5-81 to be where we want to make changes

			AND we can use multiple PRECEDING_KEY_WORDS or a single PRECEDING_KEY_WORDS to specify a value to look for
			inside the SECTION defined by the SPECIAL_KEY_WORDS
			(see 'ALTERNATE USE' above for PRECEDING_KEY_WORDS exception)
			(see also MiningLaserSpeed.lua or Multi_PAK_Multi_MBIN_Example_Mod.lua for example)

		- Note that you can specify as many other key_words as REQUIRED to help narrow down
			the SECTION (like "Table") in the case where this EXML file had more than
			one major SECTION ("Table" here)
}

SECTION_UP = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- a number between 0 and the number of levels in the current EXML
		ex.: ["SECTION_UP"] = 0, --(meaning stay in the selection section) (the default value)
		     ["SECTION_UP"] = 1, --(means: select the level one up from the current level)
		     ["SECTION_UP"] = 2, --(means: select two level up from the current level)
			 ...
	- default value is 0 (meaning stay in the selection section)
}

WHERE_IN_SECTION = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- a table of (two STRINGs) table(s)
		ex.: 	["WHERE_IN_SECTION"] =
				{
					{"Property name/value1","WhereValue1",},
					{"Property name/value2","WhereValue2",},
					...
				},
	- a table containing one or many "two string" table describing:
		a "Property name" or "Property value" we want to check the value of
		and a "WhereValue" that will be compared to the original one in the EXML file
	- IF the "Property name/value" has that "WhereValue" in the section specified by
		SPECIAL_KEY_WORDS and/or PRECEDING_KEY_WORDS then that section will be use
		by the script to update the EXML, otherwise that section is skipped
	- "IGNORE" can be used in place of one or both strings
	- an example use can be found in the script RewardTable_Test.lua
}

************************  THIS IS STILL IN DEVELOPMENT  **********************
SAVE_SECTION_TO = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- "" or a STRING
		ex.: 	["SAVE_SECTION_TO"] = "user_name_of_section",
	- user_name_of_section is the name the user will insert in the script to refer to the SECTION content
		The SECTION content will be a STRING
	- it instruct AMUMSS to copy that section for future use in the script
	- Only the first section of multiple sections returned by the keywords is saved
}

************************  THIS IS STILL IN DEVELOPMENT  **********************
SAVE_SECTION_ACROSS = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- "" or a STRING
	- DEFAULT value is "FALSE"
	- can have one of these values: {nil, "", "TRUE", "FALSE"}
	- "FALSE" instruct AMUMSS to record this section ONLY for the current script
	- "TRUE" instruct AMUMSS to create a permanent record of this section
		that can be used by the current script AND any other scripts in ModScript
}

************************  THIS IS STILL IN DEVELOPMENT  **********************
USE_SECTION = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- "" or a STRING
		ex.: 	["USE_SECTION"] = "user_name_of_section",
	- user_name_of_section is the name the user will insert in the script to refer to the SECTION content
		The SECTION content will be a STRING
	- it instruct AMUMSS to paste that previously SAVEd section into the current EXML at the current position
}

MATH_OPERATION = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- "" or a STRING composed of
	- == "$" + one of {+, -, *, /} + (a SUFFIX and an endString)(OPTIONAL) OR (a SUFFIX and NUMBER_OF_LINES)(OPTIONAL)
		ex.: 	["MATH_OPERATION"] 	= "*",
			or	["MATH_OPERATION"] 	= "*F:MaxAmount",
			or	["MATH_OPERATION"] 	= "*$L:5",
			or	["MATH_OPERATION"] 	= "$-",

	- After retrieving the LINE pointed to by the keywords (AND possibly redirected by LINE_OFFSET):

	- "$" when used, commutes the order of the operands so that, for example, (3 - 5 = -2) becomes (5 - 3 = 2)

	- {+, -, *, /} used alone will apply the math operation between the VALUE at that LINE and the script "newvalue". Use as the mod "newvalue"

	- with SUFFIX == one of {F:, FB:} AND
		endString == "IGNORE" or a Property Name STRING (like [MaxAmount] here: <Property name="MaxAmount" value="300" />)
		  Note: the value pointed to MUST be a numerical value (NOT a text string like [ALLOY1] here <Property name="Value" value="ALLOY1" />)

		F: == Fetch Forward from the LINE for endString and get the value on that new line
		FB: == Fetch Backward from the LINE for endString and get the value on that new line

		now apply the math operation between this value and the script "newvalue".  Use as the mod "newvalue"

	- WARNING If you can avoid using {L:, LB:}, it is better. A one line added/removed by NMS <<in between>> would kill the script
	- with SUFFIX == one of {L:, LB:} AND NUMBER_OF_LINES
		L: == Lookup Forward from the LINE PLUS NUMBER_OF_LINES and get the value on that new line
		LB: == Lookup Backward from the LINE MINUS NUMBER_OF_LINES and get the value on that new line

		now apply the math operation between this value and the script "newvalue".  Use as the mod "newvalue"
}

INTEGER_TO_FLOAT = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- a STRING

	- WARNING: even if you use this option to silence the AMUMSS WARNING's, MBINCompiler may still refuse
		to compile the EXMl when the underlying value is 'really' an INTEGER.
		USE 'INTEGER_TO_FLOAT' if you know that what you are doing is right

	- [WARNING]: ORIGINAL and NEW number value have mismatched types (INTEGER vs FLOAT or STRING vs NUMBER)
		You may see this WARNING in the REPORT . 
		This WARNING only tells you that the script is changing an INTEGER "0" to a FLOAT "0.75"
			or a STRING to a NUMBER or a NUMBER to a STRING.
		If the EXML compiles fines with MBINCompiler then it is alright, 
			otherwise it may be the case why MBINCompiler fails to conpile the EXML.  
		So it is an AID to you in finding a possible problem.
	
	- can have one of these values: {nil, "", "FORCE", "PRESERVE"}
	- default value is "PRESERVE"
	- "FORCE" will change the INTEGER value to a FLOAT if necessary
	- "PRESERVE" will keep the same type of value as before the operation
		A FLOAT will still be a FLOAT
		An INTEGER will still be an INTEGER (rounding up the value if necessary)
}

REPLACE_TYPE = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- a STRING
	- can have one of these values: {nil, "", "ALL", "ALLFOLLOWING", "RAW", "ADDAFTERSECTION"}
		ex.: 	["REPLACE_TYPE"] 	= "ALL",
	- == if missing or nil or "": it will replace only the first line that match the key_words

	- NOT YET IMPLEMENT == "ALLFOLLOWING" will replace ALL lines that match the VALUE_CHANGE_TABLE pairs FOLLOWING
		the most recent replaced line (after the first replacement obviously)

	- == "ALL" will replace ALL lines that match the VALUE_CHANGE_TABLE pairs
	- == "ALL" with "some key_words" will replace ALL lines that match the VALUE_CHANGE_TABLE pairs
		INSIDE the SECTION(s) defined by the key_words

	- == "ADDAFTERSECTION": When used with ADD, REPLACE_TYPE can only be "ADDAFTERSECTION" to specify to add the TEXT_TO_ADD AFTER the SECTION
		specified by the SPECIAL_KEY_WORDS and the VALUE_CHANGE_TABLE property

	- == RAW replaces property with value on ALL lines where property is found
		SPECIAL_KEY_WORDS / PRECEDING_KEY_WORDS and other options can be use to limit the SECTION

		NOTE: each RAW only targets one line of the EXML

		WARNING: RAW IS POWERFULL AND DANGEROUS, EVEN DESTRUCTIVE IF NOT USED CORRECTLY
		***** USE WITH GREAT CARE *****

		>>> see the "RAW_REPLACEMENT.lua" script in the ModScriptCollection\LearningExamples\Commented
			folder for some more details <<<
}

VALUE_MATCH = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- a STRING
		ex.: 	["VALUE_MATCH"] 	= "Snow",
			or	["VALUE_MATCH"] 	= "5",
	- a literal value (a string or a number) from the EXML file that
		matches exactly the "original value" we want to change
		like if we want to change only values when the "original value" is "5" or "Snow" or "False"
	- can be useful when the tool has difficulty finding the right one
	- see CreatureSizeAndSpawnRateIncrease.lua and MoreScreenFilters.lua as examples
}

VALUE_MATCH_OPTIONS = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- a STRING
		ex.: 	["VALUE_MATCH_OPTIONS"] 	= "~=",
	- IF VALUE_MATCH value is "" or does not exist, VALUE_MATCH_OPTIONS have no effect
	- forces the tool to match this options for the "newvalue"
		when searching for the "Property name/value" (see VALUE_CHANGE_TABLE below)
	- If VALUE_MATCH is a STRING:
		- To replace the VALUE on ALL lines defined by the keywords:
			- that MATCH VALUE_MATCH,                  use "=" (default option)
			- that DO NOT MATCH VALUE_MATCH,           use "~="
	- If VALUE_MATCH is a NUMBER:
		- To replace the VALUE on ALL lines defined by the keywords:
			- that MATCH VALUE_MATCH,                  use "=" (default option)
			- that DO NOT MATCH VALUE_MATCH,           use "~="
			- that is less than VALUE_MATCH,           use "<"
			- that is les or equal to VALUE_MATCH,     use "<="
			- that is greater than VALUE_MATCH,        use ">"
			- that is greater or equal to VALUE_MATCH, use ">="
}

VALUE_MATCH_TYPE = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- a STRING
		ex.: 	["VALUE_MATCH_TYPE"] 	= "NUMBER",
	- IF VALUE_MATCH value is "" or does not exist, VALUE_MATCH_TYPE have no effect
	- can be "NUMBER" or "STRING" only
	- forces the tool to match this type for the "newvalue"
		when searching for the "Property name/value" (see VALUE_CHANGE_TABLE below)
}

LINE_OFFSET = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- WARNING: if you can avoid LINE_OFFSET, it is better. A one line added/removed by NMS in between would kill the script
	- EXCEPT where a list of lines like <Property value="4" /> as in GCFLEETGLOBALS.GLOBAL.EXML are used and you want
		to alter some particular line or lines
		- For a script example see LodDistanceScale.lua or TerrainEditorMod.lua

	- a STRING representing a number
		ex.: 	["LINE_OFFSET"] 	= "-15",
	- "" or (if used) +/- a STRING integer number of lines from the found line like "+15"
	- If a line is found using the SPECIAL_KEY_WORDS, it is used as the starting point
	- Otherwise, the start line of the SECTION found using the PRECEDING_KEY_WORDS will be used
	- NOTE: with ADD, the line used to ADD is the NEXT line
	- NOTE: with REMOVE, the line used (to define the SECTION or the LINE to REMOVE) is the line found
}

VALUE_CHANGE_TABLE = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- a table of (two STRINGs)table(s)
		ex.:	["VALUE_CHANGE_TABLE"] 	=
				{
					{"Property name/value1","newvalue1",},
					...
				},
	- {"Property name/value1","newvalue1",}, {"Property name/value2","newvalue2",}, ...
	- a table containing one or many "two string" table describing:
		- a "Property name" or "Property value" we want to change the value of
		- and a "newvalue" that will replace the original one in the EXML file
		- one or the other can be "IGNORE" in some cases (like when we use LINE_OFFSET)
		- syntax examples:  {"A","IGNORE",}, or  {"IGNORE","IGNORE",}, or  {"IGNORE","A",},
	- a newvalue == "IGNORE" will make the tool SKIP that line,
		doing NO exchange at all and continuing processing the next Property name/value
	- to update a group of numerical 'Property value=' using (for example) a [MATH_OPERATION] = "*"
		and ["VALUE_CHANGE_TABLE"] = {{"IGNORE","1.5"},},
		to multiply << each >> value by 1.5 without the need for [LINE_OFFSET]
}

ADD = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- Can be of type "string" or [[long string]] or a user named variable of those types (like TEXT_TO_ADD)
		ex.:	["ADD"] = "a short string",
			or	["ADD"] = [[a
								multi-line
									string]],
			or	["ADD"] = MY_USER_NAME_VARIABLE,
	- Used to ADD lines or SECTION inside the EXML file
	- Can be used with a user named variable defined before the opening MODIFICATIONS SECTION
	- See the ADD_REMOVE_TEXT_EXAMPLE.lua example in "ModScriptCollection\LearningExamples\Commented\" folder
	- See also the LearnMoreWords.lua script in "ModScriptCollection" folder
	- Can be used with SPECIAL_KEY_WORDS, PRECEDING_KEY_WORDS, LINE_OFFSET,
		VALUE_MATCH, VALUE_MATCH_TYPE and REPLACE_TYPE
	- Used with LINE_OFFSET, the TEXT_TO_ADD is added EXACTLY AFTER the line found
		WARNING: if you can avoid LINE_OFFSET, it is better. A one line added/removed by NMS in between would kill the script
	- Used with REPLACE_TYPE == "ADDAFTERSECTION", will find the end of the SECTION and then ADD the TEXT_TO_ADD
	- "Property name/value1" of VALUE_CHANGE_TABLE can be used to specify a sub-SECTION of the SPECIAL_KEY_WORDS + PRECEDING_KEY_WORDS SECTION

	NOTE:
	  - PLEASE remember that if you use both ADD and REMOVE inside the same EXML_CHANGE_TABLE
	  - the respective TEXT will be "added" first AND the "removed" done (the LINE or the SECTION)
}

REMOVE = {
	- is OPTIONAL
	- is a member of EXML_CHANGE_TABLE
	- a STRING
		ex.:	["REMOVE"] = "SECTION",
	- "", or {}, or {"",}, ==> all these mean: no REMOVE to use
	- == "SECTION", the SECTION will be REMOVEd
	- == "LINE", the line will be REMOVEd
	- SPECIAL_KEY_WORDS, PRECEDING_KEY_WORDS, LINE_OFFSET
		with VALUE_MATCH, VALUE_MATCH_TYPE and REPLACE_TYPE can be use
	- with LINE_OFFSET, the REMOVE action happens AT the line found for LINE or the SECTION

		WARNING: REMOVE IS POWERFULL AND DANGEROUS, EVEN DESTRUCTIVE IF NOT USED CORRECTLY
		USE WITH GREAT CARE

	NOTE:
	  - PLEASE remember that if you use both ADD and REMOVE inside the same EXML_CHANGE_TABLE
	  - the respective TEXT will be "added" first AND the "removed" done (the LINE or the SECTION)
}

ADD_FILES = {
	- is OPTIONAL if MODIFICATIONS is used
	- a member of NMS_MOD_DEFINITION_CONTAINER

	- can be used with or without MODIFICATIONS
	- see StandardSchemeExtended.lua and ADD_NEW_FILES_EXAMPLE.lua scripts for more details

	- the order of members is not important
	- members of ADD_FILES are:
		- FILE_DESTINATION		OPTIONAL
		- EXTERNAL_FILE_SOURCE	OPTIONAL
		- FILE_CONTENT			OPTIONAL
}

***************************  ADVANCED SCRIPT RULES / TIPS  ****************************

Tip #1: OBSOLETE  *********  NOT USED ANYMORE (AMUMSS ALWAYS DO ONLY ONE PASS NOW)  **************

	What to do when your script spends a lot of time in BUILDMOD.bat at the line:
	">>> B: Executing Lua with LoadScriptAndFilenames.lua, Please wait..."

	Your script probably does a LOT of pre-processing before the NMS_MOD_DEFINITION_CONTAINER definition.
	You can add these code lines in your script
	to skip the long executing code and still load the container:

	--top of example script (see SkippingLongFirstPass.lua in folder ModScriptCollection\LearningExamples\Advanced)

--===============================================================================
   *********  NOT USED ANYMORE (AMUMSS ALWAYS DO ONLY ONE PASS NOW)  **************
--at the top of the script:
--add thess lines to bypass the first pass evaluation of the script
DoFirstPass = (os.getenv("SkipScriptFirstCheck") ~= nil)
--this line is used to jump over all the lengthy code BEFORE the NMS_MOD_DEFINITION_CONTAINER
if not DoFirstPass then
--===============================================================================

  local function sleep(s)
	if s==nil then s=1 end
	local i=os.clock()+s
	print("        waiting for " .. s .. " seconds ...")
	while(os.clock()<i) do
	  --print("wait for " .. i-clock() .. " seconds")
	end
	print("         finished waiting for " .. s .. " seconds")
  end

	--example of long execution code here
	--this will wait for 30 seconds, simulating a long time to execute
	sleep(30)

	ANIM_TEMPLATE_ALL = ""  			--used in the CONTAINER
	ACTION_TRIGGER_COMPONENT = ""		--used in the CONTAINER
	QUICK_ACTION_BUTTON_ALL = ""		--used in the CONTAINER
    SUPER_USER_VARIABLE = ""        --not used in container, no need to duplicate below
	--end of example of long execution code here

--===============================================================================
   *********  NOT USED ANYMORE (AMUMSS ALWAYS DO ONLY ONE PASS NOW)  **************
--Add these lines just before the NMS_MOD_DEFINITION_CONTAINER
else  --if not DoFirstPass then
  print("     Skipping first pass check!")

  --here create ALL "empty user variables" used in EXML_CHANGE_TABLE
  --in order for the script to be valid
  ANIM_TEMPLATE_ALL = ""  			--this user variable is used in the CONTAINER
  ACTION_TRIGGER_COMPONENT = ""		--this user variable is used in the CONTAINER
  QUICK_ACTION_BUTTON_ALL = ""		--this user variable is used in the CONTAINER
  --...                               --as many as there are in CONTAINER
end  --if not DoFirstPass then
--===============================================================================

	NMS_MOD_DEFINITION_CONTAINER =
	{
	["MOD_FILENAME"] 			= "SkippingLongFirstPass.pak",
	["MOD_AUTHOR"]				= "Wbertro",
	["MOD_DESCRIPTION"]			= "",
	["NMS_VERSION"]				= "2.0+",
	["MODIFICATIONS"] 			=
		{
			{
				["MBIN_CHANGE_TABLE"] =
				{
					{
						["MBIN_FILE_SOURCE"] 	= "MODELS\COMMON\PLAYER\PLAYERCHARACTER\PLAYERCHARACTER\ENTITIES\PLAYERCHARACTER.ENTITY.MBIN",
						["EXML_CHANGE_TABLE"] =
						{
							{
								["PRECEDING_KEY_WORDS"] = {"Anims"},
								["LINE_OFFSET"] 		= "+0",
								["ADD"] 				= ANIM_TEMPLATE_ALL, --a user variable
							},
							{
								["PRECEDING_KEY_WORDS"] = {"LodDistances"},
								["LINE_OFFSET"] 		= "-2",
								["ADD"] 				= ACTION_TRIGGER_COMPONENT, --a user variable
							}
						}
					},
					{
						["MBIN_FILE_SOURCE"] 	= "METADATA\UI\EMOTEMENU.MBIN",
						["EXML_CHANGE_TABLE"] 	=
						{
							{
								["PRECEDING_KEY_WORDS"] = {"Emotes"},
								["LINE_OFFSET"] 		= "+0",
								["ADD"] 				= QUICK_ACTION_BUTTON_ALL, --a user variable
							}
						}
					},
				}
			},
		}
	}
	--NOTE: ANYTHING NOT in table NMS_MOD_DEFINITION_CONTAINER IS IGNORED AFTER THE SCRIPT IS LOADED
	--IT IS BETTER TO ADD THINGS AT THE TOP IF YOU NEED TO
	--DON'T ADD ANYTHING PASS THIS POINT HERE

	--end of example script
   *********  NOT USED ANYMORE (AMUMSS ALWAYS DO ONLY ONE PASS NOW)  **************

Tip #2:
	-In a loop, it is much faster to use a table to store strings and do a table.concat()
	  than to concatenate strings.  As an example:

	  function UsingConcatenation() -- may take 50 sec to complete
		  local NbIteration = 200000
		  print("NbIteration = "..NbIteration)
		  local a = "MyString"
		  local b = a
		  for i=1,NbIteration do
			b = b..a
		  end
		  print(#b)
	  end

	  function UsingTable()       -- takes only less than 1 sec to complete for the same result
		  local NbIteration = 200000
		  print("NbIteration = "..NbIteration)
		  local a = "MyString"
		  local T = {}
		  T[1] = a
		  for i=1,NbIteration do
			T[#T+1] = a
		  end
		  b = table.concat(T)
		  print(#b)
	  end


Tip #3:
	-Conflicts:
	
	Conflicts may come from the fact that a pak (from a .lua script) is already in your MODS folder 
	AND you asked AMUMSS to also check Conflicts against the MODS folder.
	
	Since AMUMSS cannot know if this pak is in fact from this .lua script 
	(the pak name could have been renamed by the user), it flags it as 'in conflict'.  
	
	But since you know this is not the case, you can safely disregard these conflicts in this case.

***************************  DEPRICATED (do not use)  ****************************
REPLACE_AFTER_ENTRY = {
	- NOT USED ANYMORE - XXXXX depricated XXXXX
	- is an older version of PRECEDING_KEY_WORDS (left for backward compatibility)
}


