- General Best Practices
- Construction Menu
- Shared Product Mods
- Shared Production Mods
- Shared Item Effect Pools
- Shared Assets between Mods
- Hotel Needs
- Make changes to existing assets as small as possible.
Don't
replace
the whole thing. - Avoid removing stuff. You never know who used that as an anker to insert new stuff.
- DO NOT remove entries from
Template
s. You may crash other mods with that. - Use unique names for new
Template
s. Best use your name or the mod name as a prefix. - Use
Text/TextOverride
to rename vanilla text with new assets. You don't know who is using the original text in another context.
A common problem are mods replacing entries in the construction menus. Imagine there's a mod replacing the fishery with a fishery menu, but your mod relies on that fishery entry to position itself after it. Your entry won't show as a result.
- Don't replace/remove menus. Hide them instead
- Insert with
shared-pools-and-definitions
- Add
compact-menu
group tag - Insert into production chains instead of replacing the whole chain
Hide entries by adding PlatformVisibility
like this:
<ModOp Type="merge" GUID="500094"
Path="/Values/ConstructionCategory/BuildingList/Item[Building='1010372']">
<PlatformVisibility>Console</PlatformVisibility>
</ModOp>
Reason: other mods may use those entries to insert their building.
Insert into progression menus by unlock condition instead of GUID.
<ModOp Type="addNextSibling" GUID="25000190"
Path="/Values/ConstructionCategory/BuildingList/Item[Worker<=400][last()]">
<Item>
<Building>1500010111</Building>
<Worker>400</Worker>
</Item>
</ModOp>
The mod shared-pools-and-definitions
adds unlock conditions for all vanilla buildings. You need to load after it.
Check shared-pools-and-definitions guide for details.
Add tags to ensure your mod buildings are inserted into the correct groups up by the Compact Menu mod.
The following for example makes the building show up as part of the administration group (town hall, guild house and harbor master).
<Item>
<Building>123</Building>
<CompactAdministration />
</Item>
Check compact-menu guide for details.
A good way to share products between sevaral mods is to use a shared product mod.
A shared product mod should contain:
- a single complete
Product
template asset - an icon and all translations
- storage
120055
listing - expedition values, if applicable
- ideally, a hidden fake factory with
IsMainFactory=1
. Users must use0
. - Docklands entries, if applicable
A shared product mod SHOULD NOT contain:
- a production building
- fertility entries
- anything that is not explicitely mentioned above
Use the product name as the ModID
(product-author
), e.g. product-author
.
See tea-jakob for an example / template.
Especially raw material production is also good to share between mods.
A shared production mod should contain:
- a single production or production chain
- icons, all translations
- product listings and unlocks
- a production chain menu and construction menu entry, if it produces an product
- fertility entries, if applicable
- it may or may not include the product. Be clear about it, and don't remove it in future versions.
Use the product name plus producing region as the ModID
(region-product-author
), e.g. ow-hemp-jakob
.
The reason for unlocks is to keep product listings and unlock aligned. Also balancing is easier if everyone has the same base.
You may unlock a shared production earlier, if you really have to.
See ow-hemp-jakob for an example / template.
Use ItemEffectTargetPool
s from shared-pools-and-definitions
to avoid many, very similar building names in buff InfoTips.
<!-- add to pools having sand mine -->
<ModOp Type="add"
Path="//ItemEffectTargetPool/EffectTargetGUIDs[Item/GUID='1010560']">
<Item>
<GUID>1500010708</GUID> <!-- NW Sand Pit -->
</Item>
</ModOp>
Check shared-pools-and-definitions guide for details and a list of all new available pools.
Products, effect pools and build menus are good examples of assets you want to include in several mods but add only once to the game.
You find community shared assets here - for use and as examples: shared-resources.
The following adds Cheese 1500010102
to the market storage list 120057
after sausages 1010238
, but only if it is not already there.
<ModOp Type="addNextSibling" GUID="120057" Path="/Values/ProductStorageList/ProductList/Item[Product='1010238' and not(../Item/Product='1500010102')] | //Values[Standard/GUID='1500010221']/ProductStorageList/ProductList/Item[last()]">
<Item>
<Product>1500010102</Product>
</Item>
</ModOp>
Here we select the item 1010238
and then do and not(../Item/Product='1500010102')
to make sure the list does not include Cheese already.
If you want to avoid modloader warnings (recommended), then you can do one more trick with | //Values[Standard/GUID='1500010221']/ProductStorageList/ProductList/Item[last()]
. You can basically select an alternative node with |
to insert your product. You only need to make sure to add a fake storage list your self - and delete it afterwards like below:
<ModOp Type="addNextSibling" GUID="120055">
<Asset>
<Template>fallback</Template>
<Values>
<Standard>
<GUID>1500010221</GUID>
</Standard>
<ProductStorageList>
<ProductList>
<Item />
</ProductList>
</ProductStorageList>
</Values>
</Asset>
</ModOp>
<!-- ... add product with fallbacks here ... -->
<ModOp Type="remove" GUID="1500010221" />
Generally, adding multiple versions of the same asset is ot a problem. But if you want to have a shared list like an effect pool or a construction category you need to make sure it's only one entry and every mod adds to that.
<!-- add dummy + default list -->
<ModOp Type="addNextSibling" GUID="190886">
<Asset>
<Template>ItemEffectTargetPool</Template>
<Values>
<Standard>
<GUID>1500010714</GUID>
<Name>duplicate</Name>
</Standard>
</Values>
</Asset>
<Asset>
<Template>ItemEffectTargetPool</Template>
<Values>
<Standard>
<GUID>1500010714</GUID>
<Name>all sand mines</Name>
</Standard>
<ItemEffectTargetPool>
<EffectTargetGUIDs>
<Item>
<GUID>1010560</GUID>
</Item>
</EffectTargetGUIDs>
</ItemEffectTargetPool>
</Values>
</Asset>
</ModOp>
<!-- remove duplicate -->
<ModOp Type="remove" Path="//Asset[Values/Standard/GUID='1500010714'][position() & last()]"/>
<!-- add -->
<ModOp Type="add" Path="//ItemEffectTargetPool/EffectTargetGUIDs[Item/GUID='1010560']">
<Item>
<GUID>1500010708</GUID>
</Item>
</ModOp>
You add your empty/default list and then remove every entry except the last. Important always do it at the same spot, so that the last entry is always the first that has been added.
Then you can add your non-shared entries to the list with another ModOp.
Note the dummy list: this is to prevent the remove ModOp doesn't find anything to remove if your mod is the first to add this shared list.
If your product is available in Docklands you need to make sure it has the IsMainFactory
set in one production building.
If you set none you will get corrupt pricing, if you have 2 or more all production buildings will disappear.
<Asset>
<Template>FactoryBuilding7</Template>
<Values>
<!-- ... -->
<FactoryBase>
<!-- ... -->
<IsMainFactory>1</IsMainFactory>
</FactoryBase>
<!-- ... -->
</Values>
</Asset>
Hint: you can also provide a fake factory that is always locked and not added to construction menus if you want to provide Docklands only products.
If you want to create hotels in any region you should include assets-hotel-needs.include.xml.
It is a shared include that allows for easier compatibility handling between Old World and New World hotels.
The include adds RequiredToBeBuilding
and a region (e.g. <Region>Colony01</Region>
) to all Tourist needs.
Instead of working with single hotel GUIDs you can use the Region
now as an anker for your ModOp queries.