[[TOC]] = Modding Resources = As of r18964, the code base of 0AD attempts to deal with gatherable/tradable/tributable resources (e.g. `food`, `wood`) in an agnostic fashion. In other words, the resources are not hardcoded inside simulation components, the GUI or the AI. This means that adding or removing resources are somewhat easier for modders to do, should they wish. The following guide attempts to show how to do just that. **Please Note:** The process of adding a resource, although a lot easier than before, is still not very modder friendly, particularly in the later sections, and you may get errors that might seem confusing. Please visit the 0ad-dev irc channel if you have questions (and please stick around long enough for an answer). == Resources == #resourceTypes 0 A.D. currently has several different types of resources: * four normal resources: food, wood, stone, and metal * a special resource: population * a local resource (affecting only individual units): experience * a fundamental resource: time (time can not be edited, neither in 0 A.D. nor outside) This page simply considers modifying normal resources and ignores all others. == How to edit an existing resource == #editResource === Change a resource icon === #resourceIcon Suppose you want to replace the meat icon used by “food” with a different one (because you care about historical accuracy and realize most people living in Antiquity could not afford meat even a single day in the year; or because you are a vegetarian and are opposed to the use of meat as generic food; or because you simply like to know how to change an icon; or for any other reason), all you have to do is create or edit two images: * `food.png` (the convention is 64×64 pixels) * `food_small.png` (16×16 pixels) and place those in `art/textures/ui/session/icons/resources/` Then launch the game and admire your icon being used everywhere for food. === Change a resource name or other aspects === #resourceData The resources themselves are defined each in a separate `{resource}.json` file in `simulation/data/resources/` Let's have a look at the complete file of resource number one, food, to see how it works; `food.json`: {{{ #!js { "code": "food", "name": "Food", "description": "Harvest from animals, berry bushes, fish, or fields.", "order": 1, "subtypes": { "fish": "Fish", "fruit": "Fruit", "grain": "Grain", "meat": "Meat" }, "properties": ["barterable", "tradable", "tributable"], "truePrice": 100, "aiAnalysisInfluenceGroup": "ignore" } }}} It contains the following elements: * **`code`** - Internal identifying code for this resource. Cannot be the same as another resource * **`name`** - Player-friendly name of the resource. This will be localized into the player's chosen language (if localizing data exists for it) * **`order`** - The order it appears in the in-game GUI. Resources will appear in numerical order of this attribute. * **`subtypes`** - An object of Subtypes of this resource. At least one must be specified. The entries within this object follow the form `"{subtype-code}": "{subtype-name}"` where `subtype-code` is the internal reference to this subtype, and `subtype-name` is the user-friendly translatable name of the subtype. Resources can have the same subtype codes (e.g. both `wood` and `stone` both possess a `ruin` subtype). * **`properties`** - An array of properties of this resource. Currently implemented are `barterable`, `tradable`, `tributable` to allow the specified action to be performed with the resource. * **`truePrice`** - This is the true worth of the resource. This is used in calculating how much should be exchanged per click in the markets' Barter dialogue compared to other resources. See the `Barter` component for further details. * **`aiAnalysisInfluenceGroup`** - This is used by the AI to help determine where to build resource deposit sites and where to allocate workers. There are three possible values: * **`ignore`** - The AI will ignore this resource when it comes to planning where to build gather sites. This could be for several reasons, for instance that supplies of this resource move around (e.g. animals) or can be built by the player (e.g. farms) * **`abundant`** - This resource is abundant (very common) on the average map, but each deposit only contains a small amount of the given resource. (e.g. `wood`) * **`scarce`** - The resource has few deposits on the average map, but each deposit contains a fair to large quantity of the given resource. (e.g. `stone` or `metal`) **NB** It is imperative that a `{resource.json}` file contains all these entries. So even if you do not want to use any subtype resources, you can not simply remove the `"subtypes"` element; a resource has to contain at least one subtype (the name does not really matter). Examples of things you can easily change here: * add a “cheese” subtype in `food.json` * display “stone” consistently before “wood” everywhere in the game by swapping the `order` values in `stone.json` and `wood.json` * rename all entries of “Metal” in the game into “Iron” (0 A.D. is situated in the Iron Age) by changing the `"name":` element into `"Iron",` in `metal.json` * making a resource twice as expensive or half as valuable by changing the ``truePrice:`` element into `200,` respectively `50,` == How to remove a resource == #removeResource Substraction is the inverse of addition. To remove a resource, in short, follow the instructions to add a resource (below), but in reverse making sure to remove all reference to the resource. Although not really difficult, it is a lot of work. Suppose you would want to remove a certain resource, e.g. food (because your units are not children anymore, they can look after themselves, and get their own food; just because AoE includes food as a resource doens't mean 0 A.D. has to as well). A sensible, though not necessary complete approach, could be: * remove all entries (e.g. Cost, Loot, ResourceGatherer, etc.) in all `simulation/data/` and `simulation/templates/` (e.g. using `grep food *` is very helpful) * edit the `simulation/ai` files to prevent the AI from looking for the resource * remove the resource (objects) from the `maps/` files * edit the `gui/session/` files * edit `gui/common/setup_resources.xml` * finally, remove the file in `simulation/data/resources/` by adding “.DELETED” behind the file name (e.g. create an empty file called `food.json.DELETED`) == How to add a new resource == #addResource Adding resources is not particularly difficult, provided you do not overlook any files (and there are quite a few you have to edit). Suppose you would want to add a new resource, e.g. “water”, then here is what you have to do. === Create the resource === 1. Create two icons: * `art/textures/ui/session/icons/resources/water.json` (64×64 pixels) * `art/textures/ui/session/icons/resources/water_small.json` (16×16 pixels) 2. Create a new resource file: `simulation/data/resources/water.json`, e.g.: {{{ #!js { "code": "water", "name": "Water", "order": 1.1, "subtypes": { "well": "Well Water" }, "truePrice": 50, "aiAnalysisInfluenceGroup": "ignore", } }}} 3. Add a e.g. "water.xml" to `gui/common/resources/` so that you can use the icon in game UI texts (e.g. tech tree, tooltips); insert e.g.: {{{ #!xml }}} 4. Modify the following files to a display a number of resources larger than four: * `gui/session/selection_panels.js`: search for `g_SelectionPanels.Barter` (currently line 79) and change the `"getMaxNumberOfItems"` and `"rowLength"` elements, e.g.: {{{ #!js { return 5; }, "rowLength": 5, }}} * `gui/session/selection_panels_left/barter_panel.xml` (currently line 6): e.g. `` (this value must match the return value of the JS file) * `gui/session/top_panel/counters.xml` (currently line 5): e.g. `` (Note that due to 0 A.D.'s requirement to support a minimum screen resolution of 1024x768px, there isn't really enough space in the top panel for more than four resources plus the population count, nor is their in the market barter panel. If you do not care about this, the easiest solution, perfectly fine. If you do care, then the harder solution is to redesign the session UI. Good luck with that.) 5. Insert `Player/BarterMultiplier/` `Buy/` and `Sell/` elements, e.g. `1.0`, into: * `simulation/templates/special/player.xml` * `simulation/templates/special/player_gaia.xml` 6. Insert a `Production/TechCostMultiplier/` element, e.g. `1.0`, into: * `simulation/templates/template_structure.xml` (you can also do it in any of its descendants instead, but better do it here, in case you forget later) * any trainer unit templates (use `grep TechCostMultiplier *` to find them), e.g. `simulation/templates/units/athen_ship_trireme.xml` Congratulations! You can now have, display, trade, barter, tribute, and spend “water”! You can now also “water” in technologies and templates (e.g. as costs, loot, resource trickle rate, etc.). === Gathering the new resource (in the normal way) === #gatherResource 1. Supply at least two cursors: one that shows when you want a unit to return with a stack of resources, the others are used for tasking a unit to gather. In 0AD, a cursor is comprised of two files: a `.png` and a `.txt`. The first is the actual image displayed on screen, whilst the second marks the co-ordinates that should be considered the "point" of the cursor. Both files are named almost identically with the only difference being their given extension. The cursor used when tasking a unit to gather follows the pattern `action-gather-{res}.{ext}`. So to create a gather cursor for the `water` resource, the `.png` will be called `action-gather-water.png`, and the `.txt` `action-gather-water.txt`. In a similar fashion, the cursor used when tasking a unit to return with their stack of the gathered resource follows the pattern `action-return-{res}.{ext}`. All four new files should be placed within `art/textures/cursors/`. They'll get included by 0AD automagically. You will also need to provide gather (but not return) icons for each of your resource's subtypes. These follow the same pattern as before: `action-gather-{subtype}.{ext}`. These can just be renamed copies of your `action-gather-{res}.{ext}` icon. (Remember you'll need both a `.png` and a `.txt`) 2. Provide something to gather from. For this you will need to create or modify an xml file to define the entity that will be your gather-site. The parent template you may wish to inherit from will differ depending on your resource, for instance if your resource is something mined then inheriting from `template_gaia_geo` would be a good start, or if your resource comes from a plant then inherit from `template_gaia_flora`, or if gathered from some kind of structure (e.g. a farm) `template_structure_resource`. Either way, in order to make the gather-site provide your resource you must include the `ResourceSupply` component into the template of your gather-site: {{{ #!xml false Infinity water.well 1 }}} For the specifics of what tag does what here, see the schema of the [source:/ps/trunk/binaries/data/mods/public/simulation/components/ResourceSupply.js ResourceSupply] component. 3. To the templates of the units that will be doing the gathering (or the parent templates of those units), add a gather rate and carry capacity to the `ResourceGatherer` component. For example: {{{ #!xml 1 10 }}} 4. Your units will then need to drop the resource off somewhere. If the resource is to be dropped off at a structure (or worker elephant) that already permits resource dropping off, add your resource type to the existing `Types` list inside the `ResourceDropsite` component. Else add the component to the structure: {{{ #!xml water true }}} 5. Lastly, modify the `art/actor` xml files of **all** the actors of **all** the units you wish to gather this new resource so as to tell the game which animations and props to use on units for gathering and returning with your new resource. Every civ that has that unit, every promotion level. The easiest way to do this is to use `variants` (see the contents of the `art/variants` folder for some idea of how this works), but it will still require modifying a lot of actor templates. This step could be seen as optional, as the gathering will still take place without error, but without it units will just stand at the resource (playing the idle animation) until their resource capacity is full. === Teaching the AI to gather the new resource === #ai For this you will have to edit some of the `simulation/ai/` files. === Including your resource objects on maps === #maps If you have created new objects from which your new resource can be gathered (e.g. water wells), you might want to include these into the `maps/` files. === Summary === #summary In short, to add a resource you need at least to create: * `art/textures/ui/session/icons/resources/{newresource}.png` * `art/textures/ui/session/icons/resources/{newresource}_small.png` * `simulation/data/resources/{newresource}.json` and to edit: * `gui/common/setup_resources.xml` * `gui/session/selection_panels.js` * `gui/session/selection_panels_left/barter_panel.xml` * `gui/session/top_panel/counters.xml` * `simulation/templates/special/player.xml` * `simulation/templates/special/player_gaia.xml` * `simulation/templates/template_structure.xml` This is sufficient for having, displaying, trading, bartering, tributing, and using a resource. If you also want to make your resource gatherable, you'll need more icons, create templates, and edit AI files and maps; see the relevant sections (above). == Known Issues or Problems == #problems * The session gui is limited to displaying four resources (plus population count) in the top bar. * Modifying countless actor files to add animations and props is not very mod-friendly.