4 Tutorial 12 Mini Total Conversion
bryanthaboi edited this page 2026-10-20 17:01:40 -04:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Tutorial 12: Mini total conversion

Make: Start a new save in your own small cove, receive an original Emberkit, and play a sample wild battle.

Before you start: Advanced capstone. Complete Tutorial 03, Tutorial 06, and Tutorial 07. This is an independent mod with its own assets; earlier tutorial mods must be disabled.

Game: Red, local single-player. Use a practice save for experiments. If file creation is new to you, start with Tutorial 00; unfamiliar words are in the Glossary.

1. Set up the files

Create a new tutorial_12 folder in your mod location. Disable earlier tutorial mods for this exercise. The starting state is this empty folder; the finished state is all the files below.

This is a mod folder, not the engine root. Do not replace the engine's own main.lua. Preserve filenames and avoid an extra .txt extension.

Finished folder layout:

mods/tutorial_12/
  assets/emberkit_back.png
  assets/emberkit_front.png
  assets/emberkit_icon.png
  main.lua
  manifest.json

Each link opens a complete file you can save at the matching path. The JSON and Lua are also printed in full below; do not append them to another lesson's entry function.

File in this mod Complete example
assets/emberkit_back.png Download emberkit_back.png
assets/emberkit_front.png Download emberkit_front.png
assets/emberkit_icon.png Download emberkit_icon.png
main.lua Download main.lua
manifest.json Download manifest.json

Original sample front sprite (40×40 pixels):

Emberkit original sample front sprite

The back image is 32×32; the party icon is 16×32 with two stacked frames. Save the PNG files as images, keeping their exact names.

2. Describe the mod

Complete file: replace tutorial_12/manifest.json:

{
  "id": "tutorial_12",
  "name": "Tutorial 12 Cove",
  "version": "1.0.0",
  "entry": "main.lua",
  "api": 2,
  "profile": "total_conversion",
  "priority": 900,
  "games": [
    "red"
  ]
}

id is the stable internal name, name is the label in MODS, and entry tells the loader which Lua file to open. games limits these examples to Red. Keep commas between JSON fields and no comma after the last field.

3. Write the change

Complete file: replace tutorial_12/main.lua:

local MAP = "TUTORIAL_COVE"
local STARTER = "TUTORIAL_COVE_EMBERKIT"

return function(mod)
  local blocks = {}
  for i = 1, 30 do blocks[i] = 1 end

  mod.content.pokemon:register(STARTER, {
    id = STARTER,
    name = "EMBERKIT",
    dex = 152,
    types = { "FIRE" },
    baseStats = { hp = 45, attack = 60, defense = 40, speed = 65, special = 50 },
    catchRate = 190,
    baseExp = 64,
    growthRate = "MEDIUM_FAST",
    level1Moves = { "TACKLE" },
    learnset = { { level = 7, move = "GROWL" } },
    evolutions = {},
    spriteFront = mod.assets:path("assets/emberkit_front.png"),
    spriteBack = mod.assets:path("assets/emberkit_back.png"),
    frontSize = 5,
  })
  mod.content.icons:register(STARTER, {
    image = mod.assets:path("assets/emberkit_icon.png"),
    frames = 2,
  })

  mod.content.maps:register(MAP, {
    id = MAP,
    label = "TutorialCove",
    index = 1000,
    tileset = "OVERWORLD",
    width = 6,
    height = 5,
    blocks = blocks,
    borderBlock = 1,
    warps = {},
    signs = {},
    objects = {
      {
        index = 1,
        x = 3,
        y = 1,
        sprite = "SPRITE_OAK",
        movement = "STAY",
        range = "NONE",
        text = "TEXT_TUTORIAL_COVE_STARTER",
        name = "TUTORIAL_COVE_GUIDE",
      },
    },
  })
  mod.content.map_scripts:register(MAP, {
    talk = {
      TEXT_TUTORIAL_COVE_STARTER = {
        { "check_flag", "mod:starter_taken" },
        { "jump_if_true", "after" },
        { "show_text", "Choose this\nEMBERKIT!" },
        { "give_pokemon", STARTER, 5, true },
        { "jump_if_false", "full_party" },
        { "set_field", "mod:starter_taken", true },
        { "show_text", "EMBERKIT is now\nyour partner!" },
        { "start_battle", "wild", "RATTATA", 3 },
        { "show_text", "A wild RATTATA\nchallenged you!" },
        { "jump", "end" },
        { "label", "full_party" },
        { "show_text", "Make room and\ntalk to me again." },
        { "jump", "end" },
        { "label", "after" },
        { "show_text", "Take care of\nEMBERKIT!" },
        { "label", "end" },
      },
    },
  })
  mod.content.field:patch("boot", {
    startMap = MAP,
    startX = 3,
    startY = 3,
    startFacing = "up",
    lastHeal = { map = MAP, x = 3, y = 3 },
    playerName = "COVE",
    rivalName = "TIDE",
  })
end

Understand what you wrote

A total conversion changes the starting world and enough content to create a different game experience. This example is deliberately small: one room-sized outdoor map, one starter interaction, and one battle. It still uses the imported Red engine content, tiles, existing UI, and Rattata; it is not a standalone game or a replacement for the required import.

The top-level MAP and STARTER variables hold IDs reused below. The species and icon registrations bring Emberkit into this independent mod. Copying the original images into this mod's own assets folder removes any dependency on Tutorial 03 being enabled.

The map supplies a 6×5-block floor and an Oak-looking guide at player cell (3, 1). The script first checks its private starter flag. A successful give_pokemon sets that flag and starts a level-3 wild Rattata battle. Failure to give the starter goes to the retry text instead of marking the gift complete.

The field patch changes the boot settings: the starting map, player coordinates, facing, names, and return point after a loss. These settings apply when creating a new game. Loading an existing Pallet Town save does not move it into the cove.

The manifest's total_conversion profile describes this mod's role; its priority orders its content changes. Neither is a reason to leave every previous example enabled. A clean test uses this finished folder by itself.

4. Load and check it

Save every file, restart the app, enable the mod for Red in the launcher's MODS panel, and launch. Resolve any load error before checking gameplay. Troubleshooting shows where errors appear. With default desktop bindings, A is Z/Enter/Space, B is X/Backspace, and Start is Escape/keypad Enter; use your configured controls if different.

Optional source-checkout validation

If you have Python 3, LuaJIT, and the engine source with Red imported, open a terminal in the engine root containing tools/. For a mod installed in that checkout's mods directory, run:

python3 tools/modkit.py validate tutorial_12 --base imported

If you saved it elsewhere, replace the mod ID with the quoted full path to its folder. A validation error identifies a file or content rule to fix; a pass means you can continue to the in-game checks. It does not prove rendering, sound, or the entire playthrough works. Packaged-app users can use MODS errors and the checkpoints without setting up these command-line tools.

Checkpoint

  1. Put this finished bundle in its own tutorial_12 folder, including all three assets. Disable earlier tutorial mods, especially tutorial_world and Tutorial 03, and restart.
  2. Create a new practice save slot in Red. You should start in Tutorial Cove at player cell (3, 3), facing north. Keep your original Red saves separate.
  3. Move one cell north to (3, 2), face the guide, and press A. Receive Emberkit. Continue the dialogue into the level-3 Rattata battle and use Tackle.
  4. After the battle, inspect Emberkit's front picture, back picture, and party icon as applicable. Talk again: the starter should not be granted twice.
  5. Save and reload with the mod still enabled. Confirm the location and starter persist. This is the full first playable loop; expanding the story comes afterward.

Common pitfalls

What you see What to check
I start in Pallet Town Create a new game with only this mod enabled; boot settings do not relocate an existing save.
Missing Emberkit picture Copy this bundle's assets too. It does not load images from an earlier tutorial's folder.
Starter repeats or disappears on reload Keep tutorial_12's manifest ID stable and reload the same save with the mod enabled.

For syntax, missing-file, and restart problems, use Troubleshooting. Compare the whole finished file before changing several things at once.

Undo and continue

Keep the practice save and its matching mod files together. Saves can contain this example's custom content or progress. To compare with vanilla Red, disable the mod, restart, and open a separate unmodified practice slot. Do not overwrite the only copy of a modded save while its content is disabled. Save recovery explains backups.

Consolidate before expanding or sharing

Piece This capstone owns What to check when copying your own work
World TUTORIAL_COVE map and script All map IDs, entry coordinates, exits, and return points resolve.
Roster TUTORIAL_COVE_EMBERKIT and its icon Starting moves exist and every referenced asset is included.
Progress mod:starter_taken Keep the same mod ID across releases; plan migrations before changing saved fields.
Startup field.boot Test a new slot and a resumed slot separately.
Package One manifest, entry, three original images Disable previous examples and test the copied folder by itself.

The cove is a starting exercise, not a finished campaign: it has no onward story, custom title screen, shops, or repeatable encounter area. Use Total Conversions for that roadmap, Publishing for packaging, and Cartkit if you later distribute a sealed custom cart. Link play uses the launcher and a vanilla or sealed custom cart; authored mods may be included in the sealed cart.

The cove is also Red only: Gen 3 has no field target and Gold reads only part of boot, so a cove for another generation needs that game's own start settings. Gen 2 and Gen 3 lists the other per-game parts, and Portable Mods across Gen 1, 2 and 3 covers "api": 3.

Return to the tutorial index to choose the next lesson.