Using semantic delta operators in Rubble as a flexible way of doing control of versions. While not a perfect system I am working around the patch conflicts between mods like this: 1. I use the addon.meta "LoadPriority": value, to indicate the required order of application of mods. Using the following table of priorities and separators:
9 -> Critical Base Libs 400 -> Composable mods 1999 -> Final or not composable mods 2999 -> Toolbox 3999 -> Tilesets 4999 -> Graphics ¨ -> Tutorials 62000 -> Tests In resume: when a mod applies changes to some part of vanilla I calculate those changes in relation to what is already done by the modest mod (making button the subsidiary maintainer of vanilla raws after Toady one, no problem as soon as both workings are perfectly separated and distinguishable), generalizing this process to other mods you have a formal model of building mods upon the hard work of your precursors instead of fighting them. 2. Then I use delta operators (aka semantic diff) as defined by Martin Fowler
So, while textual diff works with a context of files and lines inside them to define where to apply the delta. my DF aware delta operators define this context in terms of DF rubble objects and tokens inside them to define where to apply the deltas. This makes the system more reliable, as you will modify the targetted object independently of in which file it is being defined. 3. The temporal definition (local non committed version) of those operators is:
------------------------------------------------------------------------------------------------------------------------------------------- -- Semantic Delta operators -- {@CONTEXT;objectid;wheretoappend} -- Fixes the objectid (for example ENTITY:MOUNTAIN) where the delta will be applied and also if the appended preraws go before or after (this is the default) the attachment token. -- {@DELTA;token;value;preraws} -- Modifies the end value of a token inside an object and eventually attach before or after it the preraws, if the token id is given but not the value the token is killed. -- if not token is given the preraws are appended at the end of the object. When no object is found a detailed DELTA warning is generated. ------------------------------------------------------------------------------------------------------------------------------------------- ___rubble_object_cursor = "" ___rubble_attach_after = true local socontext = [[ local value, after = rubble.targs({...}, {"", "AFTER"}) ___rubble_object_cursor = rubble.expandvars(value, "$", true) if after == "BEFORE" then ___rubble_attach_after = false else ___rubble_attach_after = true end ]] rubble.template("!CONTEXT", socontext) rubble.template("@CONTEXT", socontext) rubble.template("CONTEXT", socontext) rubble.template("#CONTEXT", socontext) rubble.template("#C", socontext) local sodelta = [[ local token, value, preraws = rubble.targs({...}, {"", "", ""}) if token == "" then local data = rubble.registry["Libs/Base:SHARED_OBJECT_ADD"].table data[___rubble_object_cursor] = (data[___rubble_object_cursor] or "").."\n\t"..rubble.parse(preraws) return end token = string.split(token, ":") rubble.libs_base.sharedobject_walk(___rubble_object_cursor, function(tag) if rubble.libs_base.matchtag(tag, token) then if value == "" then local preraws = "-"..tag.ID for _, v in ipairs(tag.Params) do preraws = preraws..":"..v end tag.Comments = preraws.."-"..tag.Comments else local fulltoken = "["..token..":"..value.."]" if ___rubble_attach_after == true then tag.Comments = preraws..fulltoken..tag.Comments else tag.Comments = fulltoken..preraws..tag.Comments end end tag.CommentsOnly = true else rubble.warning("OBJECT: "..___rubble_object_cursor.." NOT found, {@DELTA;"..token..";"..value.."} mal formed or incorrect order of application of mods") end end) ]] rubble.template("!DELTA", sodelta) rubble.template("@DELTA", sodelta) rubble.template("DELTA", sodelta) rubble.template("#DELTA", sodelta) rubble.template("@D", sodelta) 4. As they log with enough detail each DELTA failure, modders are guaranted in absence of these warning that ALL intended changes to the vanilla raws have been effectively applied in the order specified by the mods and their dependencies. 5. Some examples of use of the actual DELTA operator applying some changes in vanilla required by the modest mod maintained by Button:
-- less fuel required to do a bar of iron {@CONTEXT;REACTION:PIG_IRON_MAKING} {@DELTA;REAGENT:A;300:BAR:NO_SUBTYPE:METAL:IRON} {@DELTA;PRODUCT:100;2:BAR:NO_SUBTYPE:METAL:PIG_IRON} -- less fuel required to do a bar of steel {@CONTEXT;REACTION:STEEL_MAKING} {@DELTA;REAGENT:A;300:BAR:NO_SUBTYPE:METAL:IRON} {@DELTA;REAGENT:B;300:BAR:NO_SUBTYPE:METAL:PIG_IRON} {@DELTA;PRODUCT:100;4:BAR:NO_SUBTYPE:METAL:STEEL} 6. The complete All races playable maintained by Lovechid using commited old delta operators (those have been deprecated)
{!TEMPLATE;!SET_VALUE;token;value;preraws;{@SHARED_OBJECT_REPLACE_TAG;$OBJECT_CURSOR;%{token};[%{token}:%{value}]%{preraws}}} {!TEMPLATE;@ATTACH_BEFORE_TAG;token;preraws;{@SHARED_OBJECT_REPLACE_TAG;$OBJECT_CURSOR;%{token};%{preraws}[%{token}:%{value}]}} {!TEMPLATE;@ATTACH_AFTER_TAG;token;preraws;{@SHARED_OBJECT_REPLACE_TAG;$OBJECT_CURSOR;%{token};[%{token}:%{value}]%{preraws}}} {!TEMPLATE;@REPLACE_TAG;token;preraws;{@SHARED_OBJECT_REPLACE_TAG;$OBJECT_CURSOR;%{token};%{preraws}}} #In the files creature_standard.txt and creature_subterranean.txt {@FOREACH;DWARF=0|ELF=0|GOBLIN=0|KOBOLD=0|CAVE_FISH_MAN=0|OLM_MAN=0|BAT_MAN=0|CAVE_SWALLOW_MAN=0|AMPHIBIAN_MAN=0|REPTILE_MAN=0|SERPENT_MAN=0|ANT_MAN=0|RODENT MAN=0; {SHARED_OBJECT_ADD;CREATURE:%{key}; [OUTSIDER_CONTROLLABLE]}} {@FOREACH;TROLL=500|OGRE=500|BLIZZARD_MAN=500|GRIMELING=250; {SHARED_OBJECT_ADD;CREATURE:%{key}; [PET_EXOTIC] [TRAINABLE] [PETVALUE:%{val}]}} {@FOREACH;WOLF_ICE=0|BLENDEC_FOUL=0|STRANGLER=0|NIGHTWING=0|HARPY=0|SEA_MONSTER=0; {SHARED_OBJECT_ADD;CREATURE:%{key}; [PET_EXOTIC] [TRAINABLE]}} {SHARED_OBJECT_ADD;BEAK_DOG;[PET_EXOTIC][TRAINABLE][PACK_ANIMAL][WAGON_PULLER][TRADE_CAPACITY:2000]} #In the file item_weapon.txt {@FOREACH;PIKE=0|HALBERD=0|SWORD=0|MAUL=0|AXE_GREAT=0; {@SET;OBJECT_CURSOR;ITEM_WEAPON:ITEM_WEAPON_%{key}} {!SET_VALUE;MINIMUM_SIZE;57500}} #In the file entity_default.txt {ENTITY_PLAYABLE_EDIT;FOREST;FORT;true} {ENTITY_PLAYABLE_EDIT;PLAINS;FORT;true} {ENTITY_PLAYABLE_EDIT;EVIL;FORT;true} {@SET;DWARF_PLAYABLE;true} {@SET;ELF_PLAYABLE;true} {@SET;HUMAN_PLAYABLE;true} {@SET;GOBLIN_PLAYABLE;true} {SHARED_OBJECT_ADD;FOREST; [SITE_CONTROLLABLE] [TOOL:ITEM_TOOL_STEPLADDER] [PERMITTED_JOB:CARPENTER] [PERMITTED_JOB:ANIMAL_TRAINER] [PERMITTED_JOB:THRESHER] [PERMITTED_JOB:BREWER] [PERMITTED_JOB:MECHANIC] [PERMITTED_JOB:ARCHITECT] [PERMITTED_REACTION:MAKE_WOODEN_SWORD_SHORT_ARP] [PERMITTED_REACTION:MAKE_WOODEN_SPEAR_ARP] [PERMITTED_REACTION:MAKE_WOODEN_BREASTPLATE_ARP] [PERMITTED_REACTION:MAKE_WOODEN_MAIL_SHIRT_ARP] [PERMITTED_REACTION:MAKE_WOODEN_HELM_ARP] [PERMITTED_REACTION:MAKE_WOODEN_CAP_ARP] [PERMITTED_REACTION:MAKE_WOODEN_GAUNTLETS_ARP] [PERMITTED_REACTION:MAKE_WOODEN_BOOTS_ARP] [PERMITTED_REACTION:MAKE_WOODEN_BOOTS_LOW_ARP] [PERMITTED_REACTION:MAKE_WOODEN_GREAVES_ARP] [PERMITTED_REACTION:MAKE_WOODEN_LEGGINGS_ARP] [PERMITTED_REACTION:MAKE_WOODEN_MECHANISMS_ARP] [PERMITTED_REACTION:GROW_WOOD_ARP]} {SHARED_OBJECT_KILL_TAG;PLAINS;SITE_VARIABLE_POSITIONS} {SHARED_OBJECT_ADD;PLAINS;[SITE_CONTROLLABLE][TOOL:ITEM_TOOL_STEPLADDER]} {SHARED_OBJECT_KILL_TAG;EVIL;SITE_VARIABLE_POSITIONS} {SHARED_OBJECT_ADD;EVIL;[SITE_CONTROLLABLE][ALL_MAIN_POPS_CONTROLLABLE][COMMON_DOMESTIC_PULL][TOOL:ITEM_TOOL_STEPLADDER]} {SHARED_OBJECT_ADD;SKULKING;[SITE_CONTROLLABLE][TOOL:ITEM_TOOL_STEPLADDER]}
{!TEMPLATE;ADD_NOBLE_POSITION;name;number;precedence;soldier; [POSITION:{@STR_TO_ID;%{name}}] [NAME:%{name}:%{name}s] [NUMBER:%{name}] [PRECEDENCE:%{precedence}] [SITE] [DO_NOT_CULL] [DUTY_BOUND] {@IF;%{soldier};{@VOID};{@VOID};[SQUAD:10:%{soldier}:%{soldier}s]}} {!TEMPLATE;ADD_LAND_POSITION;landholder;landname;replaced; [LAND_HOLDER:%{landholder}] [LAND_NAME:%{landname}] {@IF;%{replaced};{@VOID};{@VOID};[REPLACED_BY:%{replaced}]}} {!TEMPLATE;ADD_LAND_RESPONSABILITY;responsability1;responsability2;responsability3;responsability4; [RESPONSIBILITY:%{responsability1}] {@IF;%{responsability2};{@VOID};{@VOID};[RESPONSIBILITY:%{responsability2}]} {@IF;%{responsability3};{@VOID};{@VOID};[RESPONSIBILITY:%{responsability3}]} {@IF;%{responsability4};{@VOID};{@VOID};[RESPONSIBILITY:%{responsability4}]}} {!TEMPLATE;ADD_LAND_APPOINTER;appointer1;appointer2;appointer3;rappointer4; [APPOINTED_BY:%{appointer1}] {@IF;%{appointer2};{@VOID};{@VOID};[RESPONSIBILITY:%{appointer2}]} {@IF;%{appointer3};{@VOID};{@VOID};[RESPONSIBILITY:%{appointer3}]} {@IF;%{appointer4};{@VOID};{@VOID};[RESPONSIBILITY:%{appointer4}]}} [SUCCESSION:BY_HEIR] [SPECIAL_BURIAL] [MENIAL_WORK_EXEMPTION] [MENIAL_WORK_EXEMPTION_SPOUSE] [SLEEP_PRETENSION] [PUNISHMENT_EXEMPTION] [FLASHES] [BRAG_ON_KILL] [CHAT_WORTHY] [DO_NOT_CULL] [KILL_QUEST] [COLOR:5:0:0] [ACCOUNT_EXEMPT] [DUTY_BOUND] {!TEMPLATE;ADD_REQUIRED;demands;mandates;boxes;cabinets;racks;stands;roomvalue;replaced; [DEMAND_MAX:%{demands}] [MANDATE_MAX:%{mandates}] [REQUIRED_BOXES:%{boxes}] [REQUIRED_CABINETS:%{cabinets}] [REQUIRED_RACKS:%{racks}] [REQUIRED_STANDS:%{stands}] [REQUIRED_OFFICE:%{roomvalue}] [REQUIRED_BEDROOM:%{roomvalue}] [REQUIRED_DINING:%{roomvalue}] [REQUIRED_TOMB:%{roomvalue}]}
{!TEMPLATE;MILITIA_COMMANDER;name;plural;soldier;soldiers; [POSITION:MILITIA_COMMANDER] [NAME:%{name}:%{plural}] [SITE] [NUMBER:1] [SQUAD:10:%{soldier}:%{soldiers}] [APPOINTED_BY:EXPEDITION_LEADER] [APPOINTED_BY:MAYOR] [RESPONSIBILITY:MILITARY_STRATEGY] [COMMANDER:MILITIA_CAPTAIN:ALL] [PRECEDENCE:120] [DO_NOT_CULL] [DUTY_BOUND]} {!TEMPLATE;MILITIA_CAPTAIN;name;plural;soldier;soldiers; [POSITION:MILITIA_CAPTAIN] [NAME:%{name}:%{plural}] [SITE] [NUMBER:AS_NEEDED] [SQUAD:10:%{soldier}:%{soldiers}] [APPOINTED_BY:MILITIA_COMMANDER] [PRECEDENCE:200] [DO_NOT_CULL] [DUTY_BOUND] [MILITARY_SCREEN_ONLY]} {!TEMPLATE;SHERIFF;name;plural; [POSITION:SHERIFF] [NAME:%{name}:%{plural}] [SITE] [NUMBER:1] [RESPONSIBILITY:LAW_ENFORCEMENT] [APPOINTED_BY:EXPEDITION_LEADER] [APPOINTED_BY:MAYOR] [REPLACED_BY:CAPTAIN_OF_THE_GUARD] [PRECEDENCE:130] [DO_NOT_CULL] [COLOR:1:0:1] [ACCOUNT_EXEMPT] [DUTY_BOUND] [REQUIRED_BOXES:1] [REQUIRED_CABINETS:1] [REQUIRED_RACKS:1] [REQUIRED_STANDS:1] [REQUIRED_OFFICE:100] [REQUIRED_BEDROOM:100] [REQUIRED_DINING:100]} {!TEMPLATE;CAPTAIN_OF_THE_GUARD;name;plural;soldier;soldiers; [POSITION:CAPTAIN_OF_THE_GUARD] [NAME:%{name}:%{plural}] [SITE] [NUMBER:1] [RESPONSIBILITY:LAW_ENFORCEMENT] [SQUAD:10:%{soldier}:%{soldiers}] [APPOINTED_BY:EXPEDITION_LEADER] [APPOINTED_BY:MAYOR] [REQUIRES_POPULATION:50] [REQUIRES_MARKET] [PRECEDENCE:105] [DO_NOT_CULL] [COLOR:1:0:1] [ACCOUNT_EXEMPT] [DUTY_BOUND] [REQUIRED_BOXES:1] [REQUIRED_CABINETS:1] [REQUIRED_RACKS:1] [REQUIRED_STANDS:1] [REQUIRED_OFFICE:250] [REQUIRED_BEDROOM:250] [REQUIRED_DINING:250]} {!TEMPLATE;EXPEDITION_LEADER;name;plural; [POSITION:EXPEDITION_LEADER] [NAME:%{name}:%{plural}] [SITE] [NUMBER:1] [REPLACED_BY:MAYOR] [RULES_FROM_LOCATION] [RESPONSIBILITY:MEET_WORKERS] [RESPONSIBILITY:RECEIVE_DIPLOMATS] [RESPONSIBILITY:MILITARY_GOALS] [PRECEDENCE:110] [DO_NOT_CULL] [ACCOUNT_EXEMPT] [DUTY_BOUND]} {!TEMPLATE;MAYOR;name;plural; [POSITION:MAYOR] [NAME:%{name}:%{plural}] [SITE] [NUMBER:1] [RESPONSIBILITY:MEET_WORKERS] [RESPONSIBILITY:RECEIVE_DIPLOMATS] [RESPONSIBILITY:MILITARY_GOALS] [REQUIRES_POPULATION:50] [RULES_FROM_LOCATION] [ELECTED] [PRECEDENCE:60] [FLASHES] [BRAG_ON_KILL] [CHAT_WORTHY] [DO_NOT_CULL] [KILL_QUEST] [COLOR:5:0:0] [ACCOUNT_EXEMPT] [DUTY_BOUND] [DEMAND_MAX:2] [MANDATE_MAX:1] [REQUIRED_BOXES:2] [REQUIRED_CABINETS:1] [REQUIRED_RACKS:1] [REQUIRED_STANDS:1] [REQUIRED_OFFICE:500] [REQUIRED_BEDROOM:500] [REQUIRED_DINING:500]} {!TEMPLATE;MANAGER;name;plural; [POSITION:MANAGER] [NAME:%{name}:%{plural}] [SITE] [REQUIRES_MARKET] [NUMBER:1] [RESPONSIBILITY:MANAGE_PRODUCTION] [APPOINTED_BY:EXPEDITION_LEADER] [APPOINTED_BY:MAYOR] [PRECEDENCE:160] [DO_NOT_CULL] [COLOR:5:0:0] [DUTY_BOUND] [REQUIRED_OFFICE:1]} {!TEMPLATE;CHIEF_MEDICAL_DWARF;name;plural; [POSITION:CHIEF_MEDICAL_DWARF] [NAME:%{name}:%{plural}] [SITE] [REQUIRES_MARKET] [NUMBER:1] [RESPONSIBILITY:HEALTH_MANAGEMENT] [APPOINTED_BY:EXPEDITION_LEADER] [APPOINTED_BY:MAYOR] [PRECEDENCE:165] [DO_NOT_CULL] [COLOR:5:0:0] [DUTY_BOUND]} {!TEMPLATE;BROKER;name;plural; [POSITION:BROKER] [NAME:%{name}:%{plural}] [SITE] [REQUIRES_MARKET] [NUMBER:1] [RESPONSIBILITY:TRADE] [APPOINTED_BY:EXPEDITION_LEADER] [APPOINTED_BY:MAYOR] [PRECEDENCE:170] [DO_NOT_CULL] [COLOR:5:0:0] [DUTY_BOUND]} {!TEMPLATE;BOOKKEEPER;name;plural; [POSITION:BOOKKEEPER] [NAME:%{name}:%{plural}] [SITE] [REQUIRES_MARKET] [NUMBER:1] [RESPONSIBILITY:ACCOUNTING] [APPOINTED_BY:EXPEDITION_LEADER] [APPOINTED_BY:MAYOR] [PRECEDENCE:180] [DO_NOT_CULL] [COLOR:5:0:0] [DUTY_BOUND] [REQUIRED_OFFICE:1]} {!TEMPLATE;OUTPOST_LIAISON;name;plural; [POSITION:OUTPOST_LIAISON] [NAME:%{name}:%{plural}] [NUMBER:1] [RESPONSIBILITY:ESTABLISH_COLONY_TRADE_AGREEMENTS] [APPOINTED_BY:DRUID] [PRECEDENCE:80] [MENIAL_WORK_EXEMPTION] [SLEEP_PRETENSION] [PUNISHMENT_EXEMPTION] [ACCOUNT_EXEMPT] [DO_NOT_CULL] [COLOR:7:0:1] [DUTY_BOUND] [DEMAND_MAX:3] [REQUIRED_BOXES:3] [REQUIRED_CABINETS:2] [REQUIRED_RACKS:2] [REQUIRED_STANDS:2] [REQUIRED_OFFICE:1500] [REQUIRED_BEDROOM:1500] [REQUIRED_DINING:1500]} {!TEMPLATE;HAMMERER;name;plural; [POSITION:HAMMERER] [NAME:%{name}:%{plural}] [SITE] [REQUIRES_MARKET] [NUMBER:1] [RESPONSIBILITY:EXECUTIONS] [EXECUTION_SKILL:AXE] [APPOINTED_BY:EXPEDITION_LEADER] [APPOINTED_BY:MAYOR] [PRECEDENCE:150] [DO_NOT_CULL] [COLOR:0:0:1] [DUTY_BOUND]} {!TEMPLATE;ADD_POSITION_NOBLE;noble;female;landholder;landname;precedence;demands;mandates;boxes;cabinets;racks;stands;roomvalue;replaced; [POSITION:{@STR_TO_ID;%{noble}}] [NAME_MALE:%{noble}:%{noble}s] [NAME_FEMALE:%{female}:%{female}es] [SPOUSE_MALE:%{noble} consort:%{noble}s consort] [SPOUSE_FEMALE:%{female} consort:%{female}es consort] [NUMBER:AS_NEEDED] [LAND_HOLDER:%{landholder}] [LAND_NAME:%{landname}] [RESPONSIBILITY:LAW_MAKING] [RESPONSIBILITY:RECEIVE_DIPLOMATS] [SUCCESSION:BY_HEIR] [APPOINTED_BY:MONARCH] {@IF;%{replaced};{@VOID};{@VOID};[REPLACED_BY:%{replaced}]} [PRECEDENCE:%{precedence}] [SPECIAL_BURIAL] [MENIAL_WORK_EXEMPTION] [MENIAL_WORK_EXEMPTION_SPOUSE] [SLEEP_PRETENSION] [PUNISHMENT_EXEMPTION] [FLASHES] [BRAG_ON_KILL] [CHAT_WORTHY] [DO_NOT_CULL] [KILL_QUEST] [COLOR:5:0:0] [ACCOUNT_EXEMPT] [DUTY_BOUND] [DEMAND_MAX:%{demands}] [MANDATE_MAX:%{mandates}] [REQUIRED_BOXES:%{boxes}] [REQUIRED_CABINETS:%{cabinets}] [REQUIRED_RACKS:%{racks}] [REQUIRED_STANDS:%{stands}] [REQUIRED_OFFICE:%{roomvalue}] [REQUIRED_BEDROOM:%{roomvalue}] [REQUIRED_DINING:%{roomvalue}] [REQUIRED_TOMB:%{roomvalue}]} {ENTITY_ADD_NOBLE;FOREST; {MILITIA_COMMANDER;militia commander;militia commanders;militia-elf;militia-elves} {MILITIA_CAPTAIN;militia captain;militia captains;militia-elf;militia-elves} {SHERIFF;forest watcher;forest watchers} {CAPTAIN_OF_THE_GUARD;forest guard captain;forest guard captains;forest guard;forest guards} {EXPEDITION_LEADER;expedition leader;expedition leaders} {MAYOR;retreat leader;retreat leaders} {MANAGER;manager;managers} {CHIEF_MEDICAL_DWARF;chief healer;chief healers} {BROKER;broker;brokers} {BOOKKEEPER;record maker;record makers} {OUTPOST_LIAISON;outpost liaison;outpost liaisons} {HAMMERER;seer;seers}} {ENTITY_ADD_NOBLE;PLAINS; {MILITIA_COMMANDER;militia commander;militia commanders;militia-soldier;militia-soldiers} {MILITIA_CAPTAIN;militia captain;militia captains;militia-soldier;militia-soldiers} {SHERIFF;hearthperson;hearthpeople} {CAPTAIN_OF_THE_GUARD;hearthcaptain;hearthcaptains;hearthperson;hearthpersons} {EXPEDITION_LEADER;expedition leader;expedition leaders} {MAYOR;lord;lords} {MANAGER;manager;managers} {CHIEF_MEDICAL_DWARF;chief doctor;chief doctors} {BROKER;broker;brokers} {BOOKKEEPER;bookkeeper;bookkeepers} {OUTPOST_LIAISON;outpost liaison;outpost liaisons} {HAMMERER;executioner;executioners} ADD_POSITION_NOBLE;duke;duchess;3;a duchy;20;5;3;5;3;3;3;2500} ADD_POSITION_NOBLE;baron;baroness;1;a barony;40;2;1;2;1;1;1;500;COUNT}} {ENTITY_ADD_NOBLE;EVIL; {MILITIA_COMMANDER;militia commander;militia commanders;militia-goblin;militia-goblins} {MILITIA_CAPTAIN;militia captain;militia captains;militia-goblin;militia-goblins} {SHERIFF;enforcer;enforcers} {CAPTAIN_OF_THE_GUARD;master of enforcers;masters of enforcers;enforcer;enforcers} {EXPEDITION_LEADER;expedition leader;expedition leaders} {MAYOR;lord;lords} {MANAGER;manager;managers} {CHIEF_MEDICAL_DWARF;chief medicine goblin;chief medicine goblins} {BROKER;broker;brokers} {BOOKKEEPER;bookkeeper;bookkeepers} {OUTPOST_LIAISON;outpost liaison;outpost liaisons} {HAMMERER;torturer;torturers}} KillzEmAllGod: In the long term, I think that your proposal of enabling fine grained import of vanilla objects using the standard module mechanism of lua has a lot of sense, but using what is already disponible in the rubble system we are already able of doing something very similar but a lot less flexible, please have a look at the Vanilla raws library addon. Before release, I have some pending problems with template expansion (metaprogramming is hard to do, and even harder to do it right) that ,maybe , have been resolved by the changes that Milo has done in rubble 7.6
|