mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-20 04:31:09 +02:00
big ass modding update
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
Format: [keep a changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
Version headings match `manifest.json`'s `version`.
|
||||
|
||||
## 1.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- Base speed patches for VENUSAUR, CHARIZARD and BLASTOISE.
|
||||
- TM price halving driven off `content.items:each()`.
|
||||
- Route 1 grass re-slot.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Balance Tweaks Example
|
||||
|
||||
Raises the final-stage Kanto starters to 100 base speed, halves every TM
|
||||
price, and re-slots the Route 1 grass table — all without copying a single
|
||||
record whole.
|
||||
|
||||
**Persona: the Tweaker.** A player who wants one number changed and copies
|
||||
an example to get there. This is the shortest complete mod in the gallery
|
||||
and the one to start from.
|
||||
|
||||
## Try it
|
||||
|
||||
```sh
|
||||
python3 tools/modkit.py validate mods/examples/example_balance_tweaks --base imported
|
||||
luajit mods/examples/example_balance_tweaks/tests/example_balance_tweaks_test.lua
|
||||
```
|
||||
|
||||
Then enable it: add `example_balance_tweaks = true` under `mods` in your
|
||||
`options.lua`, or toggle it in the F10 mod manager.
|
||||
|
||||
## What it demonstrates
|
||||
|
||||
| Seam | Where |
|
||||
|---|---|
|
||||
| `content.pokemon:patch` | `main.lua` — deep-merges one leaf, leaves the rest alone |
|
||||
| `content.items:each` | `main.lua` — walks the merged view to find TMs instead of listing them |
|
||||
| `content.encounters:patch` | `main.lua` — a list leaf replaces wholesale even inside a patch |
|
||||
| `content.<r>:get` | `main.lua` — the guard that turns a missing id into a log line, not a crash |
|
||||
|
||||
`patch` is the point. The legacy `mods/example_mew_starter` has to copy
|
||||
every field of Mew to change two sprite paths, because api 1 only had
|
||||
`override`. With `patch` you name the leaf:
|
||||
|
||||
```lua
|
||||
mod.content.pokemon:patch("VENUSAUR", { baseStats = { speed = 100 } })
|
||||
```
|
||||
|
||||
Everything not named — `learnset`, `types`, `evolutions`, `spriteFront` —
|
||||
keeps its base value, and a second mod patching `baseStats.attack` on the
|
||||
same species composes with this one instead of clobbering it.
|
||||
|
||||
## Exact changes
|
||||
|
||||
- `VENUSAUR` base speed 80 → 100
|
||||
- `BLASTOISE` base speed 78 → 100
|
||||
- `CHARIZARD` base speed 100 → 100 (already there; kept for symmetry)
|
||||
- every item whose `machine.kind == "TM"` has its `price` halved
|
||||
(`TM_TOXIC` 4000 → 2000, and 49 others; HMs carry `machine.kind == "HM"`
|
||||
and are left alone)
|
||||
- `ROUTE_1` grass `rate` 25 → 20, slot table re-weighted to include
|
||||
`SPEAROW`
|
||||
|
||||
Field meanings are in the generated registry reference (`modkit docs`),
|
||||
section `pokemon`, `items` and `encounters`.
|
||||
|
||||
## Credits
|
||||
|
||||
Base stat and mart price tables come from the player's own imported ROM;
|
||||
this mod ships numbers, not data.
|
||||
@@ -0,0 +1,44 @@
|
||||
-- Gallery #1 (Tweaker): pure data, no engine seams. Everything here is
|
||||
-- patch + each, so no record is ever copied whole and another mod editing
|
||||
-- the same species keeps its own fields.
|
||||
return function(mod)
|
||||
-- patch deep-merges only the leaves it names: learnset, sprites, types
|
||||
-- and evolutions all survive this speed change untouched
|
||||
for _, id in ipairs({ "VENUSAUR", "CHARIZARD", "BLASTOISE" }) do
|
||||
if mod.content.pokemon:get(id) then
|
||||
mod.content.pokemon:patch(id, { baseStats = { speed = 100 } })
|
||||
else
|
||||
-- degrade instead of crashing: a species mod loaded ahead of this
|
||||
-- one may have removed the vanilla starter line
|
||||
mod.log:warn("%s missing from the merged view; speed patch skipped", id)
|
||||
end
|
||||
end
|
||||
|
||||
-- each() walks the merged view (engine records plus every mod ahead of
|
||||
-- this one), so the TM list is discovered rather than hard-coded
|
||||
local halved = 0
|
||||
for id, item in mod.content.items:each() do
|
||||
local machine = item.machine
|
||||
if machine and machine.kind == "TM" and type(item.price) == "number"
|
||||
and item.price > 0 then
|
||||
mod.content.items:patch(id, { price = math.floor(item.price / 2) })
|
||||
halved = halved + 1
|
||||
end
|
||||
end
|
||||
mod.log:info("halved %d TM prices", halved)
|
||||
|
||||
-- lists replace wholesale even inside a patch, so a re-slotted encounter
|
||||
-- table is written out in full while the rate rides along as a leaf
|
||||
mod.content.encounters:patch("ROUTE_1", {
|
||||
grass = {
|
||||
rate = 20,
|
||||
slots = {
|
||||
{ level = 3, species = "PIDGEY" }, { level = 3, species = "RATTATA" },
|
||||
{ level = 4, species = "SPEAROW" }, { level = 2, species = "RATTATA" },
|
||||
{ level = 2, species = "PIDGEY" }, { level = 3, species = "SPEAROW" },
|
||||
{ level = 3, species = "PIDGEY" }, { level = 4, species = "RATTATA" },
|
||||
{ level = 4, species = "PIDGEY" }, { level = 5, species = "SPEAROW" },
|
||||
},
|
||||
},
|
||||
})
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"id": "example_balance_tweaks",
|
||||
"name": "Balance Tweaks Example",
|
||||
"version": "1.0.0",
|
||||
"api": 2,
|
||||
"entry": "main.lua",
|
||||
"profile": "content",
|
||||
"category": "BALANCE",
|
||||
"game_version": ">=1.0.0 <2.0.0",
|
||||
"priority": 100,
|
||||
"dependencies": [],
|
||||
"optional_dependencies": [],
|
||||
"conflicts": [],
|
||||
"description": "Tweaker gallery entry: patch and each over the merged view, with no whole-record copies."
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
-- Sharing metadata (25-community-and-ecosystem.md 3.2). Read by tooling
|
||||
-- and the manager detail pane; never by the loader's merge.
|
||||
return {
|
||||
summary = "Faster final starters, half-price TMs, a re-slotted Route 1.",
|
||||
author = "Pokemon Gen 1 Recompilation Project",
|
||||
contact = "https://github.com/bryanthaboi/pokemon-gen1-recomp-project",
|
||||
tags = { "balance", "data-only", "beginner" },
|
||||
differences = {
|
||||
changed = {
|
||||
"VENUSAUR and BLASTOISE base speed raised to 100 (CHARIZARD already was)",
|
||||
"every TM item's price halved",
|
||||
"Route 1 grass rate 25 -> 20 and SPEAROW added to the slot table",
|
||||
},
|
||||
added = {},
|
||||
known = { "TM prices halve once per load, not once per install" },
|
||||
},
|
||||
credits = {
|
||||
{ who = "pret/pokered", for_ = "the base stat and mart price tables this patches over" },
|
||||
},
|
||||
compat = { engine = ">=1.0.0 <2.0.0", modApi = 2 },
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
-- Standalone: luajit mods/examples/example_balance_tweaks/tests/example_balance_tweaks_test.lua
|
||||
-- Loads the mod through the real headless loader and asserts its stated
|
||||
-- effect against the player's imported dataset.
|
||||
package.path = "./?.lua;./?/init.lua;" .. package.path
|
||||
|
||||
local T = require("tests.modkit")
|
||||
local Data = require("src.core.Data")
|
||||
Data:load()
|
||||
|
||||
local run = T.sdk.loadMod("mods/examples/example_balance_tweaks", { data = Data })
|
||||
T.eq(#run.errors, 0, "loads clean (" .. tostring(run.errors[1]) .. ")")
|
||||
T.eq(run.mod and run.mod.state, "loaded", "reached the loaded state")
|
||||
|
||||
T.eq(Data.pokemon.VENUSAUR.baseStats.speed, 100, "VENUSAUR speed patched")
|
||||
T.eq(Data.pokemon.BLASTOISE.baseStats.speed, 100, "BLASTOISE speed patched")
|
||||
-- the patch named one leaf, so everything else survived
|
||||
T.check(#Data.pokemon.VENUSAUR.learnset > 0, "VENUSAUR keeps its learnset")
|
||||
T.eq(Data.pokemon.VENUSAUR.types[1], "GRASS", "VENUSAUR keeps its types")
|
||||
|
||||
T.eq(Data.items.TM_TOXIC.price, 2000, "TM price halved")
|
||||
T.eq(Data.items.POTION.price, 300, "a non-TM item is untouched")
|
||||
|
||||
T.eq(Data.encounters.ROUTE_1.grass.rate, 20, "Route 1 grass rate patched")
|
||||
T.eq(Data.encounters.ROUTE_1.grass.slots[3].species, "SPEAROW",
|
||||
"Route 1 slot table re-slotted")
|
||||
|
||||
run.release()
|
||||
T.finish("example_balance_tweaks")
|
||||
Reference in New Issue
Block a user