# Creating assets

Patching edits content that already exists. Sometimes you want to add content that does not: a new resource, a new moon, a new mission step. That is a separate operation. Instead of registering a patch against existing assets, you queue a brand new asset for creation.

## Two ways to create

There are two different ways to create an asset from scratch, and which one you use depends on the kind of content. A third, copying an asset that already exists, is covered [below](#copying-an-existing-asset).

### A new top-level asset

For a standalone asset under a label, the typed modules give you a `New` method. The resource module, for instance, has `NewResource` and `NewRecipe`. The generic JSON API has `PM.JSON:New`. You give the new asset a name (its globally unique address) and a callback that fills it in:

```lua
PM.JSON:New("my_label", "MyNewThing", function(value)
    value.someField = 1
    value.anotherField = "hello"
end)
```

The name must be unique across everything under that label, since it is the address the game and other patches use to find your asset. Once created, your new asset is a normal asset: other patches (yours or other mods') can target it by that name.

The creation helpers return the queued asset. The queued asset accepts `:Feature` and `:NoFeature`, the same as a patch. Thus, a new asset can belong to one of your [features](/doc/features-geboWdIiDN):

```lua
PM.JSON:New("my_label", "MyHardModeThing", function(value)
    value.someField = 2
end):Feature("HardMode")
```

### A new entry inside an existing asset

Some content is not a top-level asset but a member of a container that already exists. A new celestial body is added to the galaxy, not dropped in as a loose asset. For these you patch the container and call an `Add` helper on it. This is how Redux adds the moon Drast to Dres:

```lua
PM.Planets:PatchDefaultGalaxy("AddDrast"):Do(function(galaxy)
    galaxy:Add("Drast", function(body)
        body.PrefabKey = "Celestial.Drast.Local"
        body.referenceBodyGuid = "Dres"
        body.OrbitProperties = {
            referenceBodyGuid = "Dres",
            inclination = 0,
            eccentricity = 0,
            semiMajorAxis = 434400,
            longitudeOfAscendingNode = 0,
            argumentOfPeriapsis = 0,
            meanAnomalyAtEpoch = 0,
            epoch = 0,
        }
    end)
end)
```

This is a normal patch (`PatchDefaultGalaxy` against the galaxy), and inside the callback `galaxy:Add("Drast", ...)` adds a new body. The `Add` callback fills in the new body the same way a `Do` callback fills in an existing one.

## Filling in a new asset

A new asset starts close to empty, so you usually set more fields than you would when editing. The callback receives the new value, and you build it up with plain assignments and tables, exactly as in [the Do callback](/doc/the-do-callback-Qq6LNtj9BT):

```lua
body.OrbiterProperties = {
    orbitColor = { r = 0.86, g = 0.38, b = 0.18, a = 0.03 },
    autoTextureOffset = false,
    textureOffset = 0,
}
```

The hard part of creating content is rarely the PatchManager call. It is knowing which fields the game needs for the content to work. The best reference is an existing asset of the same kind: find a stock body, resource, or mission and copy its form, then change what you need. The typed module pages call out the load-bearing fields for each kind of content.

The patch cache is the easiest place to read an existing asset's form. After a run, the cache holds one archive per label with the final JSON of every asset in it, so opening the archive for the kind of content you are creating (parts are under the `parts_data` label) and reading a similar asset's entry shows you exactly which fields it sets and how. Copy that as your starting point. See [Inspecting the cache](/doc/caching-and-invalidation-QifFi4oev9) for the location of the archive of each label.

## Copying an existing asset

Often the easiest new asset is a copy of an old one. Every typed module has a `Duplicate` method (`PM.Parts:Duplicate`, `PM.Planets:Duplicate`, `PM.Missions:Duplicate`, and so on), and `PM.JSON:Duplicate(label, source, newName)` covers any label. It copies each asset it matches into a new asset under the same label, and the chained `:Do` callback runs on the copy:

```lua
PM.Parts:Duplicate("fueltank_1v_inline_methalox_1x2", "fueltank_1v_inline_methalox_1x2_heavy")
        :Do(function(part)
            part.partName = "fueltank_1v_inline_methalox_1x2_heavy"
            part.PrefabAddress = "fueltank_1v_inline_methalox_1x2.prefab"
            part.IconAddress = "fueltank_1v_inline_methalox_1x2_icon.png"
            part.mass = part.mass * 1.5
        end)
```

* `source` supports `*` and `?` wildcards, so one call can copy many assets.
* `newName` names each copy, with `{name}` standing in for the source's name.
* `:Do` is optional. Without one the copy is unchanged. Returning `"remove"` from it drops that copy.
* Each `Duplicate` method also takes the callback as an optional last argument, as shorthand for `:Do`. Chaining `:Do` is the canonical form.
* A duplicate is an ordinary patch, so it chains like one. [Gates](/doc/gates-Zh2sLnyxZX) such as `:Has` decide which sources get copied at all, `:Feature` decides which campaigns get the copy, and the pass and ordering methods decide when the copy is made. Patches ordered after the duplicate also run against the copy, unless they target the source by name.

The copy keeps the source's internal ids (`partName`, `bodyName`, a mission's id). If you do not give the copy a new id, it defines the same part or body as its source. The game then sees two definitions of one item. It keeps the first and logs an error. When you copy an asset to make a new asset, set the new id in the callback. The example above sets `partName`.

The game finds the model and icon of a part by its name: `<partName>.prefab` and `<partName>_icon.png`. A copied part with a new name has no model or icon at these addresses. Thus, set `PrefabAddress` and `IconAddress` to the model and icon of the original part, as in the example above. If your mod ships its own prefab and icon with the new name, do not set them.

To change an existing asset for some campaigns only, do not copy it. Patch it in place under a [feature](/doc/features-geboWdIiDN). Campaigns without the feature keep the original.

## When the typed module has no helper

If there is no `New`, `Add` or `Duplicate` for what you want to create, drop to the [generic JSON API](/doc/generic-json-api-fqEwMuvrGb) and `PM.JSON:New` with the right label. You will have to spell the asset out as raw JSON, but it always works.

And also if you think a typed module would help, reach out to the Redux team or the author of the mod you are patching and ask them. :3