Modding: Difference between revisions
Create modding guide |
m Proofread spelling, grammar and sentence flow. |
||
| (6 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
2D Tower supports modding through data-only content packs which can be shared through Steam Workshop. Content packs can add additional variations of rooms, decorations, wallpapers, and custom maps to the game. The modding system is currently unable to allow for new behavior through custom scripts. | |||
== | == Installing mods == | ||
The easiest way to install mods is through Steam Workshop. Browse through the workshop for mods and subscribe to ones that interest you. The next time you start the game through Steam, the subscribed mods will automatically be listed in the mods window, waiting for you to enable them for the game. You can enable the mod by toggling the mod on. | |||
<pre> | == Creating mods == | ||
Mods are data-driven content packs defined through JSON files along with your assets. Creating a new mod involves 3 major steps: | |||
# Create a mod template using the in-game mod template generator | |||
# Make your changes to the template mod pack | |||
# Use the in-game mod window to publish your mod to Steam Workshop | |||
=== Create a mod template === | |||
The easiest way to get started with a new mod is to use the Mods window and its 'Create mod' feature. This menu allows you to create mods for most room types, decorations, and wallpapers. | |||
When you click on create mod, the game will generate a skeleton mod folder with a basic structure of a new content pack containing your room. The directory structure of this mod should look something like this:<pre> | |||
user://mods/ | user://mods/ | ||
└── my_record_store/ | └── my_record_store/ | ||
| Line 18: | Line 28: | ||
</pre> | </pre> | ||
''user://'' is Godot's per-user data folder. From the title screen, use '''Mods → | ''user://'' is Godot's per-user data folder. From the title screen, use '''Mods → Create''', then '''Open mods folder''' in the Edit step to open the correct location; on a standard Windows installation it is normally <code>%APPDATA%\Godot\app_userdata\2D Tower\mods\</code>. Development builds also discover packs in <code>res://mods/</code>. The game discovers only direct subfolders of these directories that contain <code>manifest.json</code>. | ||
=== Edit your new mod === | |||
After locating your new mod template folder, make your changes. Add new assets and define them within the room JSON definition. | |||
Ensure that you add any necessary translations, update the mod pack icon, and update the mod manifest JSON file to include your changes. Refer to the technical details in the sections below. | |||
=== Verify and publish === | |||
If your mod is working, you should be able to see it listed in the mod window. Select your mod and click on 'Verify' to ensure it is readable and compatible with the game. You can then publish the mod by clicking on 'Publish to Steam'. | |||
Open '''Mods''' on the title screen to enable or disable local packs. Restart the game after installing, removing, enabling, disabling or editing a pack because the content catalog is built at startup. | |||
Steam Workshop packs use the same layout: <code>manifest.json</code> sits at the root of the uploaded folder. Workshop installations stay in Steam's managed directory, not in <code>user://mods</code>. New subscriptions start disabled; enable them in '''Mods''' and restart. Use '''Mods → Create''' for templates. In '''Mods → Publish''', select a local pack and choose '''Validate'''; with Steam running, '''Upload to Steam Workshop''' uploads it. New items start private. '''View on Workshop''' opens the item page for review and visibility changes. Use a square preview around 512 × 512 pixels and under 1 MB for Workshop compatibility. Its Workshop sidecar file is stored beside the pack folder; keep it to update the same Workshop item later. | |||
== | Saves record required pack identities, compatibility versions and Workshop IDs. To open a save, keep its required packs installed and enabled with matching <code>save_compatibility_version</code> values and all referenced content IDs available. The game reports missing or incompatible content instead of silently substituting it. A similarly named Workshop item is not a replacement for the original item. | ||
== Technical details == | |||
=== Content pack manifest === | |||
<code>manifest.json</code> is at the root of the pack folder. Paths in the manifest are relative to that folder and may not escape it. | <code>manifest.json</code> is at the root of the pack folder. Paths in the manifest are relative to that folder and may not escape it. | ||
| Line 40: | Line 64: | ||
* '''pack_id''' is the pack's permanent identifier. It must start with a lowercase letter and otherwise use only lowercase letters, numbers, periods, underscores and hyphens. Keep it stable after publishing because saves refer to it. | * '''pack_id''' is the pack's permanent identifier. It must start with a lowercase letter and otherwise use only lowercase letters, numbers, periods, underscores and hyphens. Keep it stable after publishing because saves refer to it. | ||
* '''version''' identifies the | * '''version''' identifies the pack release. | ||
* '''save_compatibility_version''' is a positive integer, defaulting to 1. Save loading requires the recorded compatibility version to match, independently of the release version string. Keep it unchanged for compatible updates; change it when your content breaks the saved-content contract. | |||
* '''enabled''' is optional and sets the initial state for a local pack. The '''Mods''' window stores the player's final selection in <code>user://mods.cfg</code>. | * '''enabled''' is optional and sets the initial state for a local pack. The '''Mods''' window stores the player's final selection in <code>user://mods.cfg</code>. | ||
* '''dependencies''' lists required pack IDs. Most packs depend on <code>base</code>. | * '''dependencies''' lists required pack IDs. Most packs depend on <code>base</code>. | ||
* '''rooms''' | * '''rooms''', '''wallpapers''' and '''maps''' list their definition JSON files relative to the pack folder. A pack does not need all three kinds. | ||
* Optional '''name''', '''description''' and '''author''' describe the pack in the Mods window. Workshop packs show the item owner as their author. | |||
* '''translations''' is optional. Each key is a locale and each value is a JSON translation file. | * '''translations''' is optional. Each key is a locale and each value is a JSON translation file. | ||
Pack folders are scanned in a stable order. Duplicate IDs are rejected; a user pack cannot replace a shipped pack. | Pack folders are scanned in a stable order. Local packs need distinct IDs. Workshop items also use their Workshop item ID, allowing different creators to use the same author-supplied pack ID without colliding. Duplicate effective IDs are rejected; a user pack cannot replace a shipped pack. | ||
== Room definitions == | === Room definitions === | ||
Every room JSON file inherits a registered built-in room. The file name supplies the room's local ID unless it has an explicit <code>id</code>. For example, <code>rooms/record_store.json</code> in the <code>my_record_store</code> pack becomes <code>my_record_store:room:record_store</code>. Moving the file to another subfolder does not change that ID. | Every room JSON file inherits a registered built-in room. The file name supplies the room's local ID unless it has an explicit <code>id</code>. For example, <code>rooms/record_store.json</code> in the <code>my_record_store</code> pack becomes <code>my_record_store:room:record_store</code>. Moving the file to another subfolder does not change that ID. | ||
| Line 68: | Line 94: | ||
"visual": { | "visual": { | ||
"texture": "textures/records.png", | "texture": "textures/records.png", | ||
"region": [0, 0, | "region": [0, 0, 16, 2], | ||
"horizontal_frames": 1, | |||
"vertical_frames": 2, | |||
"frames": [ | |||
{ "variant": 0, "mode": "open", "frame": 0 }, | |||
{ "variant": 0, "mode": "closed", "frame": 1 } | |||
] | |||
} | } | ||
} | } | ||
| Line 75: | Line 107: | ||
<code>extends</code> must name an existing room. The loader makes an independent copy of that parent, so a mod never changes the original room. The supported general overrides are the display name and description, category and palette order, size and entrance, construction/demolition/maintenance costs, worker count, visit duration and custom-entrance setting. Values have to use the required data type; dimensions, coordinates and texture regions are integers. | <code>extends</code> must name an existing room. The loader makes an independent copy of that parent, so a mod never changes the original room. The supported general overrides are the display name and description, category and palette order, size and entrance, construction/demolition/maintenance costs, worker count, visit duration and custom-entrance setting. Values have to use the required data type; dimensions, coordinates and texture regions are integers. | ||
Depending on the inherited runtime, a room may also use supported profiles such as <code>commercial</code>, <code>residential</code>, <code>stock</code>, <code>garbage</code>, <code>demand</code> and <code>evaluation</code>. Unsupported fields or profiles cause validation to fail rather than being silently ignored. | Depending on the inherited runtime, a room may also use supported profiles such as <code>commercial</code>, <code>residential</code>, <code>stock</code>, <code>garbage</code>, <code>demand</code> and <code>evaluation</code>. Unsupported fields or profiles cause validation to fail rather than being silently ignored. Start with the template for the room type you want to inherit. | ||
=== Artwork and translations === | |||
<code>icon</code> is a PNG path inside the pack. A custom <code>visual</code> uses a texture and <code>region</code> in the form <code>[x, y, width, height]</code>, measured in 32 × 128 pixel tile cells, not pixels. The example above selects 512 × 256 pixels. <code>horizontal_frames</code> and <code>vertical_frames</code> split the region into frames; <code>frames</code> maps their indices to cosmetic variants and modes. The store example uses open/closed modes; residential and office artwork use different mappings. Start with the matching template rather than assuming every room uses two open/closed rows. Without a custom visual, the room keeps its parent's artwork, footprint and appearance definitions. | |||
Optional <code>appearances</code> entries define stable cosmetic IDs and a <code>variant</code> matching the visual frame mappings. A custom texture clears inherited appearances unless the mod provides its own entries. Translation files supply localized text; a short appearance <code>display_name_key</code> is scoped automatically to that room's ID. | |||
<code> | |||
=== Wallpaper artwork === | |||
Use the Wallpaper template as a working starting point. Wallpaper textures contain a top row of luminance artwork and a bottom row of RGB recoloring masks. Each cell is 32 × 128 pixels, so the complete image is a multiple of 32 pixels wide and exactly 256 pixels high. Up to 64 cells across are supported. | |||
== | The visual mode is <code>auto_repeat</code> or <code>cap_repeat_cap</code>. The latter needs at least three cells across for the left end, repeating middle and right end. The visual can specify one to three HTML colors, such as <code>"#d99a63"</code>, for the recolorable channels. These dimensions and accepted modes are format requirements; construction cost, environment contribution and colors are editable content values. | ||
List wallpaper JSON files under <code>wallpapers</code> in the manifest, for example <code>"wallpapers": ["wallpapers/my_wallpaper.json"]</code>. | |||
== Custom maps == | |||
Use the Map Mod Kit to create custom maps. This kit is a separate Godot project that you can open. It allows you to use the Godot editor to import assets and draw out the map tilemap. The included scripts will then convert your defined map into a compatible mod content pack. | |||
=== Using the map mod kit === | |||
The visual '''Map Mod Kit''' is supplied in the project's source checkout at <code>tools/map-mod-kit</code>; this wiki currently provides no separate kit download. The game's '''Mods → Create → Map''' template is available for players with only the game. For the visual editor, copy <code>tools/map-mod-kit</code> into your own working folder and import its <code>project.godot</code> in Godot 4.7. Open <code>map.tscn</code> as a separate project. Use its '''Export Map Mod''' command to produce a data-only pack; the editor project itself is not the pack to install. | |||
Choose stable lowercase pack and map IDs, edit the title and gameplay settings, paint the map and export. Use the kit's example as a guide to scenery and entrances. Validate the resulting pack in the game's Mods window before publishing it. Map settings and objective plans are customizable, so a modded map need not share the built-in [[Star rating|star requirements]]. | |||
{{Guide navigation}} | |||
[[Category: | [[Category:Creating mods]] | ||
Latest revision as of 00:03, 12 October 2026
2D Tower supports modding through data-only content packs which can be shared through Steam Workshop. Content packs can add additional variations of rooms, decorations, wallpapers, and custom maps to the game. The modding system is currently unable to allow for new behavior through custom scripts.
Installing mods
The easiest way to install mods is through Steam Workshop. Browse through the workshop for mods and subscribe to ones that interest you. The next time you start the game through Steam, the subscribed mods will automatically be listed in the mods window, waiting for you to enable them for the game. You can enable the mod by toggling the mod on.
Creating mods
Mods are data-driven content packs defined through JSON files along with your assets. Creating a new mod involves 3 major steps:
- Create a mod template using the in-game mod template generator
- Make your changes to the template mod pack
- Use the in-game mod window to publish your mod to Steam Workshop
Create a mod template
The easiest way to get started with a new mod is to use the Mods window and its 'Create mod' feature. This menu allows you to create mods for most room types, decorations, and wallpapers.
When you click on create mod, the game will generate a skeleton mod folder with a basic structure of a new content pack containing your room. The directory structure of this mod should look something like this:
user://mods/
└── my_record_store/
├── manifest.json
├── rooms/
│ └── record_store.json
├── textures/
│ └── records.png
├── i18n/
│ ├── en_US.json
│ └── de_DE.json
└── icon.png
user:// is Godot's per-user data folder. From the title screen, use Mods → Create, then Open mods folder in the Edit step to open the correct location; on a standard Windows installation it is normally %APPDATA%\Godot\app_userdata\2D Tower\mods\. Development builds also discover packs in res://mods/. The game discovers only direct subfolders of these directories that contain manifest.json.
Edit your new mod
After locating your new mod template folder, make your changes. Add new assets and define them within the room JSON definition.
Ensure that you add any necessary translations, update the mod pack icon, and update the mod manifest JSON file to include your changes. Refer to the technical details in the sections below.
Verify and publish
If your mod is working, you should be able to see it listed in the mod window. Select your mod and click on 'Verify' to ensure it is readable and compatible with the game. You can then publish the mod by clicking on 'Publish to Steam'.
Open Mods on the title screen to enable or disable local packs. Restart the game after installing, removing, enabling, disabling or editing a pack because the content catalog is built at startup.
Steam Workshop packs use the same layout: manifest.json sits at the root of the uploaded folder. Workshop installations stay in Steam's managed directory, not in user://mods. New subscriptions start disabled; enable them in Mods and restart. Use Mods → Create for templates. In Mods → Publish, select a local pack and choose Validate; with Steam running, Upload to Steam Workshop uploads it. New items start private. View on Workshop opens the item page for review and visibility changes. Use a square preview around 512 × 512 pixels and under 1 MB for Workshop compatibility. Its Workshop sidecar file is stored beside the pack folder; keep it to update the same Workshop item later.
Saves record required pack identities, compatibility versions and Workshop IDs. To open a save, keep its required packs installed and enabled with matching save_compatibility_version values and all referenced content IDs available. The game reports missing or incompatible content instead of silently substituting it. A similarly named Workshop item is not a replacement for the original item.
Technical details
Content pack manifest
manifest.json is at the root of the pack folder. Paths in the manifest are relative to that folder and may not escape it.
{
"pack_id": "my_record_store",
"version": "1.0.0",
"enabled": true,
"dependencies": ["base"],
"rooms": ["rooms/record_store.json"],
"translations": {
"en_US": "i18n/en_US.json",
"de_DE": "i18n/de_DE.json"
}
}
- pack_id is the pack's permanent identifier. It must start with a lowercase letter and otherwise use only lowercase letters, numbers, periods, underscores and hyphens. Keep it stable after publishing because saves refer to it.
- version identifies the pack release.
- save_compatibility_version is a positive integer, defaulting to 1. Save loading requires the recorded compatibility version to match, independently of the release version string. Keep it unchanged for compatible updates; change it when your content breaks the saved-content contract.
- enabled is optional and sets the initial state for a local pack. The Mods window stores the player's final selection in
user://mods.cfg. - dependencies lists required pack IDs. Most packs depend on
base. - rooms, wallpapers and maps list their definition JSON files relative to the pack folder. A pack does not need all three kinds.
- Optional name, description and author describe the pack in the Mods window. Workshop packs show the item owner as their author.
- translations is optional. Each key is a locale and each value is a JSON translation file.
Pack folders are scanned in a stable order. Local packs need distinct IDs. Workshop items also use their Workshop item ID, allowing different creators to use the same author-supplied pack ID without colliding. Duplicate effective IDs are rejected; a user pack cannot replace a shipped pack.
Room definitions
Every room JSON file inherits a registered built-in room. The file name supplies the room's local ID unless it has an explicit id. For example, rooms/record_store.json in the my_record_store pack becomes my_record_store:room:record_store. Moving the file to another subfolder does not change that ID.
{
"extends": "base:room:store",
"occupancy_mode": "immediate",
"overrides": {
"display_name": "Record Store",
"description": "A specialist shop selling vinyl records.",
"width": 24,
"height": 1,
"entrance_offset": [6, 0],
"construction_cost": 125000,
"maintenance_cost": 100,
"worker_count": 2
},
"icon": "icon.png",
"visual": {
"texture": "textures/records.png",
"region": [0, 0, 16, 2],
"horizontal_frames": 1,
"vertical_frames": 2,
"frames": [
{ "variant": 0, "mode": "open", "frame": 0 },
{ "variant": 0, "mode": "closed", "frame": 1 }
]
}
}
extends must name an existing room. The loader makes an independent copy of that parent, so a mod never changes the original room. The supported general overrides are the display name and description, category and palette order, size and entrance, construction/demolition/maintenance costs, worker count, visit duration and custom-entrance setting. Values have to use the required data type; dimensions, coordinates and texture regions are integers.
Depending on the inherited runtime, a room may also use supported profiles such as commercial, residential, stock, garbage, demand and evaluation. Unsupported fields or profiles cause validation to fail rather than being silently ignored. Start with the template for the room type you want to inherit.
Artwork and translations
icon is a PNG path inside the pack. A custom visual uses a texture and region in the form [x, y, width, height], measured in 32 × 128 pixel tile cells, not pixels. The example above selects 512 × 256 pixels. horizontal_frames and vertical_frames split the region into frames; frames maps their indices to cosmetic variants and modes. The store example uses open/closed modes; residential and office artwork use different mappings. Start with the matching template rather than assuming every room uses two open/closed rows. Without a custom visual, the room keeps its parent's artwork, footprint and appearance definitions.
Optional appearances entries define stable cosmetic IDs and a variant matching the visual frame mappings. A custom texture clears inherited appearances unless the mod provides its own entries. Translation files supply localized text; a short appearance display_name_key is scoped automatically to that room's ID.
Wallpaper artwork
Use the Wallpaper template as a working starting point. Wallpaper textures contain a top row of luminance artwork and a bottom row of RGB recoloring masks. Each cell is 32 × 128 pixels, so the complete image is a multiple of 32 pixels wide and exactly 256 pixels high. Up to 64 cells across are supported.
The visual mode is auto_repeat or cap_repeat_cap. The latter needs at least three cells across for the left end, repeating middle and right end. The visual can specify one to three HTML colors, such as "#d99a63", for the recolorable channels. These dimensions and accepted modes are format requirements; construction cost, environment contribution and colors are editable content values.
List wallpaper JSON files under wallpapers in the manifest, for example "wallpapers": ["wallpapers/my_wallpaper.json"].
Custom maps
Use the Map Mod Kit to create custom maps. This kit is a separate Godot project that you can open. It allows you to use the Godot editor to import assets and draw out the map tilemap. The included scripts will then convert your defined map into a compatible mod content pack.
Using the map mod kit
The visual Map Mod Kit is supplied in the project's source checkout at tools/map-mod-kit; this wiki currently provides no separate kit download. The game's Mods → Create → Map template is available for players with only the game. For the visual editor, copy tools/map-mod-kit into your own working folder and import its project.godot in Godot 4.7. Open map.tscn as a separate project. Use its Export Map Mod command to produce a data-only pack; the editor project itself is not the pack to install.
Choose stable lowercase pack and map IDs, edit the title and gameplay settings, paint the map and export. Use the kit's example as a guide to scenery and entrances. Validate the resulting pack in the game's Mods window before publishing it. Map settings and objective plans are customizable, so a modded map need not share the built-in star requirements.