From 1b3cf45bf60d1958269d0c2e0d11941a8faac6ff Mon Sep 17 00:00:00 2001 From: mithral Date: Thu, 27 Aug 2026 00:59:15 -0400 Subject: [PATCH] =?UTF-8?q?perf(server):=20optimization=20stack=201.0.1=20?= =?UTF-8?q?=E2=80=94=20Lithium=200.15.4,=20FerriteCore=207.0.3,=20C2ME=200?= =?UTF-8?q?.4.0-alpha.0.27,=20ChunkSmith=203.14.0=20+=20Spark,=20tuned=20c?= =?UTF-8?q?onfigs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - server_pack: bump 1.0 → 1.0.1 (patch, optimization-only) - Lithium 0.15.0→0.15.4 (gvQqBUqZ/N08Z8wog) - FerriteCore 7.0.2-hotfix→7.0.3 (uXXizFIs/sOzRw3CG) - C2ME 0.3.0+alpha.0.364→0.4.0-alpha.0.27 (VSNURh3q/gRm1ZAvc) fixes drift, async gen for Tectonic 1.28 - ChunkSmith 3.13.0→3.14.0 (4BeAEBIb/iBSiBgt7) - Add Spark 1.10.109 (l6YH9Als/cALUj9l1) server-only for profiling - Tune chunksmith/config.json: targetMspt 45, tickBudget 10, heap 75, dispatch 100, settle 20 - Tune c2me-notes.txt + modernfix-mixins.properties with documented safe defaults - Add optimization-manifest.json + mod-version-policy.json (FROZEN 31/OPT 11) + audit/drift/benchmark tools + baseline + report - Packwiz is source of truth; client_pack unchanged (server-only Spark) - Validate: packwiz refresh OK 144 mods, index adccf3bb..., manifest in-sync - Drift: LOCAL test still 142 vs 144 (needs reinstall from Packwiz export); PACKWIZ internal OK --- baseline.json | 26 + mod-version-policy.json | 785 ++++++++++++++++++ optimization-manifest.json | 407 +++++++++ optimization-report.md | 145 ++++ releases/1.0.0/README.md | 14 + server_pack/config/c2me-notes.txt | 10 +- server_pack/config/chunksmith/config.json | 20 +- .../config/modernfix-mixins.properties | 9 +- server_pack/index.toml | 19 +- server_pack/mods/c2me-fabric.pw.toml | 8 +- server_pack/mods/chunksmith.pw.toml | 8 +- server_pack/mods/ferrite-core.pw.toml | 8 +- server_pack/mods/lithium.pw.toml | 8 +- server_pack/mods/spark.pw.toml | 13 + server_pack/pack.toml | 4 +- tools/audit.fish | 25 + tools/audit.py | 406 +++++++++ tools/benchmark.fish | 73 ++ tools/drift-check.fish | 94 +++ tools/worldgen-test.fish | 23 + 20 files changed, 2065 insertions(+), 40 deletions(-) create mode 100644 baseline.json create mode 100644 mod-version-policy.json create mode 100644 optimization-manifest.json create mode 100644 optimization-report.md create mode 100644 releases/1.0.0/README.md create mode 100644 server_pack/mods/spark.pw.toml create mode 100755 tools/audit.fish create mode 100755 tools/audit.py create mode 100755 tools/benchmark.fish create mode 100755 tools/drift-check.fish create mode 100755 tools/worldgen-test.fish diff --git a/baseline.json b/baseline.json new file mode 100644 index 0000000..ef5d02c --- /dev/null +++ b/baseline.json @@ -0,0 +1,26 @@ +{ + "generated_at": "2026-08-27T04:50:00Z", + "pack_version": "1.0", + "packwiz_revision": "14b5dc3", + "index_hash": "fc014e14c3a8f5c4fcd1cea684ee1bb5ac7d70a8e76387dc106d46d5295d2f07", + "environment": "local", + "server": "~/.auto-mcs/Servers/FKRPG", + "minecraft": "1.21.1", + "fabric_loader": "0.19.3", + "tps": 20.0, + "mspt": 25.4, + "memory_gb": 7.1, + "gc_pause_ms": 3.2, + "cpu_percent": null, + "chunk_generation_per_second": 0, + "status": "PLACEHOLDER — replace with real Spark data", + "notes": "Run local test server, then: /spark profiler --timeout 300, /spark tps, /spark health. Paste TPS/MSPT/CPU/RAM/GC. See tools/benchmark.fish", + "how_to_capture": [ + "fish tools/benchmark.fish --baseline # re-creates skeleton with correct pack_version", + "Start local server: ./Start.sh in ~/.auto-mcs/Servers/FKRPG", + "In-game or RCON: spark profiler start --timeout 300", + "spark tps, spark healthreport", + "Update tps/mspt/memory_gb/gc_pause_ms/cpu_percent/chunk_generation_per_second here", + "Commit baseline.json as known-good before any optimization" + ] +} diff --git a/mod-version-policy.json b/mod-version-policy.json new file mode 100644 index 0000000..ab6cf12 --- /dev/null +++ b/mod-version-policy.json @@ -0,0 +1,785 @@ +{ + "additionalentityattributes": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Attribute library \u2014 Ranged Weapon / RPG deps" + }, + "alloy-forgery": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 alloy forging" + }, + "alternate-current": { + "automatic_updates": false, + "policy": "OPTIMIZATION", + "reason": "Redstone optimization \u2014 non-locational", + "requires_approval": false, + "test_before_production": true + }, + "another-furniture": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 furniture/decoration" + }, + "archers": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "archers-expansion": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "architectury-api": { + "policy": "LIBRARY", + "reason": "Shared library \u2014 review required before update (may affect FROZEN deps)" + }, + "armory-rpg-series": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "arsenal-rpg-series": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "azurelib-armor": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 animated armor (RPG classes)" + }, + "balm": { + "policy": "LIBRARY", + "reason": "Shared library \u2014 review required before update (may affect FROZEN deps)" + }, + "berserker-rpg-class": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "better-combat": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "bottle-your-xp": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 XP storage" + }, + "bottled-air": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 bottled air" + }, + "bountiful": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 bounty board" + }, + "bundle-api": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 bundle API" + }, + "bushier-flowers": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "c2me-fabric": { + "automatic_updates": false, + "policy": "OPTIMIZATION", + "reason": "Concurrent chunk generation/IO \u2014 requires compat testing with Tectonic", + "requires_approval": false, + "test_before_production": true + }, + "chunksmith": { + "automatic_updates": false, + "policy": "OPTIMIZATION", + "reason": "Pregeneration + CSLOD \u2014 throttle-controlled", + "requires_approval": false, + "test_before_production": true + }, + "cloth-config": { + "policy": "LIBRARY", + "reason": "Shared library \u2014 review required before update (may affect FROZEN deps)" + }, + "collective": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 Collective shared code" + }, + "comforts": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 hammock/sleep" + }, + "common-network": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 networking helpers" + }, + "continents": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "coolrain": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 rain visuals" + }, + "critical-strike": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 critical strike mechanics; review combat balance" + }, + "crying-portals": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 crying obsidian portals" + }, + "ct-overhaul-village": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "debugify": { + "automatic_updates": false, + "policy": "OPTIMIZATION", + "reason": "Vanilla bug fixes", + "requires_approval": false, + "test_before_production": true + }, + "diagonal-fences": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 diagonal fences" + }, + "dragon-scale": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 dragon scale items" + }, + "dragonsteel-more-magic-series": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "dynamiccrosshair": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 dynamic crosshair client-leaning; server safe" + }, + "easy-anvils": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 anvil UX" + }, + "easy-magic": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 enchanting UX" + }, + "edibles": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 food" + }, + "elemental-wizards-rpg": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "every-compat": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "extra-origins": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "fabric-api": { + "policy": "LIBRARY", + "reason": "Shared library \u2014 review required before update (may affect FROZEN deps)" + }, + "fabric-language-kotlin": { + "policy": "LIBRARY", + "reason": "Shared library \u2014 review required before update (may affect FROZEN deps)" + }, + "ferrite-core": { + "automatic_updates": false, + "policy": "OPTIMIZATION", + "reason": "Memory optimization \u2014 safe opts", + "requires_approval": false, + "test_before_production": true + }, + "fish-of-thieves": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 fishing" + }, + "fish-on-the-line": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 fishing" + }, + "forcemaster-rpg-class": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "forge-config-api-port": { + "policy": "LIBRARY", + "reason": "Shared library \u2014 review required before update (may affect FROZEN deps)" + }, + "frozenlib": { + "policy": "LIBRARY", + "reason": "Shared library \u2014 review required before update (may affect FROZEN deps)" + }, + "fzzy-config": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 Fzzy config" + }, + "geophilic": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "glitchcore": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 GlitchCore" + }, + "grass-overhaul": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "healing-campfire": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 campfire regen" + }, + "herdspanic": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 animal panic AI" + }, + "iceberg": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 Iceberg" + }, + "jei": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 JEI recipe viewer; safe on server" + }, + "jewelry": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "kambrik": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 Kambrik" + }, + "kiwi": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 Kiwi/Snow creator lib" + }, + "krypton": { + "automatic_updates": false, + "policy": "OPTIMIZATION", + "reason": "Network \u2014 Netty flush consolidation", + "requires_approval": false, + "test_before_production": true + }, + "leaves-be-gone": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 leaf decay" + }, + "libz": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 LibZ" + }, + "lithium": { + "automatic_updates": false, + "policy": "OPTIMIZATION", + "reason": "Server performance \u2014 tick optimizations", + "requires_approval": false, + "test_before_production": true + }, + "lithostitched": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "maplink": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 MapLink live map bridge (client)" + }, + "mapsyncer": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 MapSyncer sync; review chunk IO" + }, + "midnightlib": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 MidnightLib" + }, + "modernfix": { + "automatic_updates": false, + "policy": "OPTIMIZATION", + "reason": "Performance and memory \u2014 safe defaults only", + "requires_approval": false, + "test_before_production": true + }, + "moonlight": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 Moonlight shared code (Pehkui etc.)" + }, + "more-mobs": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 additional mobs; affects entity tick" + }, + "more-rpg-classes": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "more-runes-more-magic-series": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "more-spell-attributes-more-magic-series": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "moreladders": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 ladders" + }, + "mru": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 MRU utility" + }, + "mythicmetals": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 ore/metal generation; touches worldgen loot \u2014 review" + }, + "necronomicon": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 Necronomicon API (Spell Power)" + }, + "new-lodestone-recipe": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 recipe" + }, + "nodurability": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 durability tweak" + }, + "noisium": { + "automatic_updates": false, + "policy": "OPTIMIZATION", + "reason": "World generation noise optimization", + "requires_approval": false, + "test_before_production": true + }, + "origins": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "owo-lib": { + "policy": "LIBRARY", + "reason": "Shared library \u2014 review required before update (may affect FROZEN deps)" + }, + "packet-fixer": { + "automatic_updates": false, + "policy": "OPTIMIZATION", + "reason": "Network \u2014 packet handling", + "requires_approval": false, + "test_before_production": true + }, + "paladins-and-priests": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "pandalib": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 PandaLib" + }, + "pandas-falling-trees": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 falling trees; affects block tick" + }, + "passable-foliage": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 foliage collision" + }, + "paxi": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 datapack loader" + }, + "peaceful-nights": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 peaceful nights (side server)" + }, + "pehkui": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "pick-up-notifier": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 pickup notifier; client HUD" + }, + "placeholder-api": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 placeholder API" + }, + "playeranimator": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "pneumono_core": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 Pneumono core" + }, + "pneumono_gravestones": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 gravestones" + }, + "polymorph": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 recipe conflict resolver" + }, + "puzzles-lib": { + "policy": "LIBRARY", + "reason": "Shared library \u2014 review required before update (may affect FROZEN deps)" + }, + "ranged-weapon-api": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "relics-rpg": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "resourceful-config": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 Resourceful Config" + }, + "revive": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 revive/downing" + }, + "river-redux": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "rogues-and-warriors": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "runes": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat \u2014 IMMUTABLE (Runes series)", + "requires_approval": true + }, + "seasonal-lets-do": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "serene-seasons": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "shield-api": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 shield API (combat)" + }, + "simply-swords": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "simply-tooltips": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 tooltips; client-side but on server for JEI" + }, + "skill-tree": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "skills": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "sleep-warp-updated": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 sleep warp; affects time tick" + }, + "snow-real-magic": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 snow behavior" + }, + "sound-physics-remastered": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 sound physics; mostly client" + }, + "spark": { + "automatic_updates": false, + "policy": "OPTIMIZATION", + "reason": "Profiling \u2014 Spark for TPS/MSPT/GC baselines and regression testing", + "requires_approval": false, + "side": "server", + "test_before_production": true + }, + "sparkweave": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 Sparkweave" + }, + "spell-engine": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "spell-power": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "squaremap": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 Squaremap web map; server-side rendering (see optimization-report)" + }, + "stone-is-stone": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "stone-zone": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "stoneworks": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "structure-pool-api": { + "automatic_updates": false, + "policy": "LIBRARY", + "reason": "Library \u2014 structure pool API" + }, + "supermartijn642s-config-lib": { + "policy": "LIBRARY", + "reason": "Shared library \u2014 review required before update (may affect FROZEN deps)" + }, + "supermartijn642s-core-lib": { + "policy": "LIBRARY", + "reason": "Shared library \u2014 review required before update (may affect FROZEN deps)" + }, + "tectonic": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "terrablender": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "terralith": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "tieredz": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 tiered item reforge" + }, + "trashslot": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 trash slot" + }, + "trinkets": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "universal-sawmill": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 sawmill" + }, + "unoriginal": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "RPG/magic/combat related \u2014 treated as FROZEN by default", + "requires_approval": true + }, + "village-taverns": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "waystones": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 teleport network; review chunk delivery" + }, + "wilder-wild": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "witcher-rpg-class": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "wizards": { + "automatic_updates": false, + "policy": "FROZEN", + "reason": "Hand-crafted RPG/magic/combat stack \u2014 IMMUTABLE; do not update/reconfigure without explicit approval", + "requires_approval": true + }, + "xaeros-minimap": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 minimap (client-leaning, bundled for MapLink)" + }, + "xaeros-world-map": { + "automatic_updates": false, + "policy": "GAMEPLAY", + "reason": "Gameplay \u2014 world map (client-leaning)" + }, + "yacl": { + "policy": "LIBRARY", + "reason": "Shared library \u2014 review required before update (may affect FROZEN deps)" + }, + "yungs-api": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "yungs-better-ocean-monuments": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + }, + "yungs-better-witch-huts": { + "automatic_updates": false, + "policy": "WORLDGEN", + "reason": "Terrain/biome/structure generation \u2014 may alter seeds/chunks; explicit approval required", + "requires_approval": true + } +} diff --git a/optimization-manifest.json b/optimization-manifest.json new file mode 100644 index 0000000..6fd6bf0 --- /dev/null +++ b/optimization-manifest.json @@ -0,0 +1,407 @@ +{ + "minecraft": "1.21.1", + "loader": "fabric", + "loader_version": "0.19.3", + "fabric_api": "0.116.15+1.21.1", + "fabric_api_mod_id": "P7dR8mSH", + "fabric_api_version_id": "Nlt8gI9z", + "pack": { + "name": "F##KRPG - Server", + "version": "1.0.1", + "pack_format": "packwiz:1.1.0", + "packwiz_version": "unknown (binary /usr/bin/packwiz 2026-08-19)", + "packwiz_revision": "14b5dc3", + "index_hash": "adccf3bb09cf02c5da9f414777ae8c3a80125aa863f318ff729b787b5137b4f2", + "index_hash_format": "sha256", + "generated_at": "2026-08-27T04:59:05Z", + "git_revision": "14b5dc363c6cfd0967e09c2e60e77a1dcbe81685", + "git_short": "14b5dc3" + }, + "policy": { + "rpg_magic_combat": "FROZEN", + "optimization_mods": "TEST_BEFORE_PRODUCTION", + "worldgen_mods": "EXPLICIT_APPROVAL_REQUIRED" + }, + "optimization_mods": { + "lithium": { + "filename": "lithium-fabric-0.15.4+mc1.21.1.jar", + "version": "0.15.4+mc1.21.1", + "mod_id": "gvQqBUqZ", + "version_id": "N08Z8wog", + "side": "both", + "hash_format": "sha512", + "hash": "182064b00e6315e2255b857eaab8eb759e6b042ebd4cc8b855ff0d93f875a5a7188fac49f878d7b29d4ef7e6b6341190ad7f6f6f39f4a6d2c62003468b08e4c6", + "status": "installed", + "notes": "Updated 2026-08-27 to 0.15.4+mc1.21.1 via Packwiz \u2014 tuned configs (see c2me-notes.txt, chunksmith/config.json, modernfix-mixins.properties)", + "url": "https://cdn.modrinth.com/data/gvQqBUqZ/versions/N08Z8wog/lithium-fabric-0.15.4%2Bmc1.21.1.jar" + }, + "modernfix": { + "filename": "modernfix-fabric-5.25.1+mc1.21.1.jar", + "version": "5.25.1+mc1.21.1", + "mod_id": "nmDcB62a", + "version_id": "NnNX8LBn", + "side": "both", + "hash_format": "sha512", + "hash": "dc67d6e023e1fcdeaf7837917c477cba212c611dfc2463c6ea021319c644087c79b477e0ea8194e113ddd7332fd5c6d82baa47c291eaac7f4a86252507b4e19f", + "status": "installed", + "notes": "Audit mixins config/modernfix-mixins.properties; prefer safe server defaults" + }, + "ferritecore": { + "filename": "ferritecore-7.0.3-fabric.jar", + "version": "7.0.3-fabric", + "mod_id": "uXXizFIs", + "version_id": "sOzRw3CG", + "side": "both", + "hash_format": "sha512", + "hash": "3ad31620fac4ff44327dc7dedbe162b2d978f3f246dc16255a6e400ce9592a0d326fe36a626f3c1bf30a11f813093cbb4dcc107af039cff724d0cdf648541fdf", + "status": "installed", + "notes": "Updated 2026-08-27 to 7.0.3-fabric via Packwiz \u2014 tuned configs (see c2me-notes.txt, chunksmith/config.json, modernfix-mixins.properties)", + "url": "https://cdn.modrinth.com/data/uXXizFIs/versions/sOzRw3CG/ferritecore-7.0.3-fabric.jar" + }, + "noisium": { + "filename": "noisium-fabric-2.3.0+mc1.21-1.21.1.jar", + "version": "2.3.0+mc1.21-1.21.1", + "mod_id": "KuNKN7d2", + "version_id": "4sGQgiu2", + "side": "server", + "hash_format": "sha512", + "hash": "606ba78cf7f30d99e417c96aa042f600c1b626ed9c783919496d139de650013f1434fcf93545782e3889660322837ce6e85530d9e1a5cc20f9ad161357ede43e", + "status": "installed", + "notes": "Worldgen noise optimization; verify enabled and compatible" + }, + "c2me": { + "filename": "c2me-fabric-mc1.21.1-0.4.0-alpha.0.27.jar", + "version": "0.4.0-alpha.0.27", + "mod_id": "VSNURh3q", + "version_id": "gRm1ZAvc", + "side": "both", + "hash_format": "sha512", + "hash": "8ecfb2cc5daff31d0ccf30021c31ac31ca845ad7c9eaa1a436f106279e00b79d5d75a325ebf9f9373ef0199864f073e6315a6b9f0d5a51332c906a81c50dcb9e", + "status": "installed", + "notes": "Updated 2026-08-27 to 0.4.0-alpha.0.27 via Packwiz \u2014 tuned configs (see c2me-notes.txt, chunksmith/config.json, modernfix-mixins.properties)", + "url": "https://cdn.modrinth.com/data/VSNURh3q/versions/gRm1ZAvc/c2me-fabric-mc1.21.1-0.4.0-alpha.0.27.jar" + }, + "chunksmith": { + "filename": "chunksmith-3.14.0+1.21.1.jar", + "version": "3.14.0+1.21.1", + "mod_id": "4BeAEBIb", + "version_id": "iBSiBgt7", + "side": "both", + "hash_format": "sha512", + "hash": "682667c3858adeac0ebb7340b91d02bd1c6ec52a0637d88bb9b27bebf71c5264ef922a14fe03731f312b9e3e79bd11207558662308f513bd69bd2931a39e1d83", + "status": "installed", + "notes": "Updated 2026-08-27 to 3.14.0+1.21.1 via Packwiz \u2014 tuned configs (see c2me-notes.txt, chunksmith/config.json, modernfix-mixins.properties)", + "url": "https://cdn.modrinth.com/data/4BeAEBIb/versions/iBSiBgt7/chunksmith-3.14.0%2B1.21.1.jar" + }, + "alternate-current": { + "filename": "alternate-current-mc1.21-1.9.0.jar", + "version": "mc1.21-1.9.0", + "mod_id": "r0v8vy1s", + "version_id": "78P98rac", + "side": "server", + "hash_format": "sha512", + "hash": "8b2899de60af229e911bf45d10f71e624910e8df555aad94cb4e590f052ca5dae102f366a883a0c17a3821fbb086c587b5b9286b70502c09d51f4d60dd02ab77", + "status": "installed", + "notes": "Redstone optimization; keep enabled true nonLocational true" + }, + "krypton": { + "filename": "krypton-0.2.8.jar", + "version": "0.2.8", + "mod_id": "fQEb0iXm", + "version_id": "Acz3ttTp", + "side": "both", + "hash_format": "sha512", + "hash": "5f8cf96c79bfd4d893f1d70da582e62026bed36af49a7fa7b1e00fb6efb28d9ad6a1eec147020496b4fe38693d33fe6bfcd1eebbd93475612ee44290c2483784", + "status": "installed", + "notes": "Netty flush consolidation; zero-conf" + }, + "packet-fixer": { + "filename": "packetfixer-3.3.1-1.20.5-1.21.X-merged.jar", + "version": "3.3.1", + "mod_id": "c7m1mi73", + "version_id": "2C41Q8WX", + "side": "both", + "hash_format": "sha512", + "hash": "d0acfaa6ef394fc7d9e677022bda06a6c8be7851ba8860897999775b657b5e10878578fe626505b0c9dbc01d26f559dbb1214aabb081d076824648047094e2e1", + "status": "installed", + "notes": "Network packet handling; audit compression thresholds" + }, + "debugify": { + "filename": "Debugify-1.21.1+1.0.jar", + "version": "1.21.1+1.0", + "mod_id": "LQ3K6Qk9", + "version_id": "query-required", + "side": "both", + "hash_format": "sha512", + "hash": "from-index", + "status": "installed", + "notes": "Fixes vanilla bugs; overlaps partially with ModernFix/Lithium \u2014 keep safe defaults" + }, + "spark": { + "filename": "spark-1.10.109-fabric.jar", + "version": "1.10.109-fabric", + "mod_id": "l6YH9Als", + "version_id": "cALUj9l1", + "side": "server", + "hash_format": "sha512", + "hash": "367f574f6d28432067f09737577d799ced9c309c1725da1d09ffdfe10eacf461a66967205cc938131afbcc8b8255c8c25f8aa516e15f061c6481b6e7b8c94250", + "url": "https://cdn.modrinth.com/data/l6YH9Als/versions/cALUj9l1/spark-1.10.109-fabric.jar", + "status": "installed", + "notes": "Added 2026-08-27 for profiling (server-only Spark) \u2014 TPS/MSPT baseline. Client does not need Spark." + } + }, + "worldgen_mods": { + "tectonic": { + "filename": "tectonic-3.0.22-fabric-21.1.jar", + "version": "3.0.22-fabric-21.1", + "mod_id": "lWDHr9jE", + "version_id": "cXSQRWNy", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "config": "config/tectonic.json (tuned vertical_scale 1.28, continents_scale 0.19)", + "notes": "Terrain generation; WORLDGEN \u2014 never auto-update; may alter seeds/terrain" + }, + "terralith": { + "filename": "Terralith_1.21.x_v2.6.2.jar", + "version": "2.6.2", + "mod_id": "8oi3b5Wu", + "version_id": "query-required", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "config": "config/terralith.json (skylands false)", + "notes": "Biome injection via Lithostitched" + }, + "continents": { + "filename": "Continents_26.2_v1.1.14.jar", + "version": "26.2_v1.1.14", + "mod_id": "bQ5TJA1E", + "version_id": "bVXaqvWr", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed \u2014 WRONG GAME VERSION (26.2 snapshot build)", + "notes": "DRIFT: Should be 1.21.x_v1.1.12 (3hhSlpEU) per docs. Causes compat warning; flagged REVIEW_REQUIRED" + }, + "lithostitched": { + "filename": "lithostitched-1.8.0+beta5-fabric-21.1.jar", + "version": "1.8.0+beta5", + "mod_id": "query-required", + "version_id": "query-required", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "config": "config/lithostitched.json (breaks_seed_parity true)", + "notes": "Glue for Tectonic+Terralith" + }, + "terrablender": { + "filename": "TerraBlender-fabric-1.21.1-4.1.0.8.jar", + "version": "4.1.0.8", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "notes": "Biome API" + }, + "geophilic": { + "filename": "Geophilic v3.4.1 f15-71.mod.jar", + "version": "v3.4.1 f15-71", + "mod_id": "hl5OLM95", + "version_id": "P4R9W6RV", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "notes": "Biome placement" + }, + "wilder-wild": { + "filename": "WilderWild-4.2.1-mc1.21.1.jar", + "version": "4.2.1-mc1.21.1", + "mod_id": "xeH6ik1d", + "version_id": "query-required", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "config": "config/wilderwild/worldgen.json5", + "notes": "Biome/worldgen; depends on FrozenLib 2.2.4" + }, + "ct-overhaul-village": { + "filename": "[Fabric]ctov-3.6.3.jar", + "version": "3.6.3", + "side": "server", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "config": "config/ctov.json", + "notes": "Village structures" + }, + "river-redux": { + "filename": "riverredux-fabric-0.4.1.jar", + "version": "0.4.1", + "side": "server", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "notes": "River generation" + }, + "stone-zone": { + "filename": "stonezone-1.21-2.11.17-fabric.jar", + "version": "1.21-2.11.17", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "notes": "Stone generation variants" + }, + "stoneworks": { + "filename": "Stoneworks-v21.1.0-1.21.1-Fabric.jar", + "version": "v21.1.0-1.21.1", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "notes": "Stoneworks structures/features" + }, + "every-compat": { + "filename": "everycomp-1.21-2.11.50-fabric.jar", + "version": "1.21-2.11.50", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "notes": "Wood compat for terrain mods" + }, + "yungs-api": { + "filename": "YungsApi-1.21.1-Fabric-5.1.5.jar", + "version": "5.1.5", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "notes": "YUNG structure framework" + }, + "yungs-better-ocean-monuments": { + "filename": "YungsBetterOceanMonuments-1.21.1-Fabric-4.1.2.jar", + "version": "4.1.2", + "side": "server", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "notes": "Structure generation" + }, + "yungs-better-witch-huts": { + "filename": "YungsBetterWitchHuts-1.21.1-Fabric-4.1.1.jar", + "version": "4.1.1", + "side": "server", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "notes": "Structure generation" + }, + "serene-seasons": { + "filename": "SereneSeasons-fabric-1.21.1-10.1.0.1.jar", + "version": "10.1.0.1", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "config": "config/sereneseasons/seasons.toml, fertility.toml", + "notes": "Seasons \u2014 affects world tick + fertility" + }, + "village-taverns": { + "filename": "village_taverns-1.0.6+1.21.1.jar", + "version": "1.0.6+1.21.1", + "side": "both", + "automatic_updates": false, + "requires_approval": true, + "status": "installed", + "notes": "Structure" + } + }, + "dependencies": { + "fabric-api": { + "filename": "fabric-api-0.116.15+1.21.1.jar", + "version": "0.116.15+1.21.1", + "mod_id": "P7dR8mSH", + "version_id": "Nlt8gI9z", + "side": "both" + }, + "fabric-language-kotlin": { + "filename": "fabric-language-kotlin-1.13.13+kotlin.2.4.10.jar", + "version": "1.13.13+kotlin.2.4.10", + "side": "both" + }, + "forge-config-api-port": { + "filename": "ForgeConfigAPIPort-v21.1.3-1.21.1-Fabric.jar", + "version": "v21.1.3-1.21.1", + "side": "both" + }, + "frozenlib": { + "filename": "FrozenLib-2.2.4-mc1.21.1.jar", + "version": "2.2.4-mc1.21.1", + "side": "both", + "notes": "Required by WilderWild; JarInJar nested" + }, + "terrablender": { + "filename": "TerraBlender-fabric-1.21.1-4.1.0.8.jar", + "version": "4.1.0.8", + "side": "both" + }, + "lithostitched": { + "filename": "lithostitched-1.8.0+beta5-fabric-21.1.jar", + "version": "1.8.0+beta5", + "side": "both" + }, + "yungs-api": { + "filename": "YungsApi-1.21.1-Fabric-5.1.5.jar", + "version": "5.1.5", + "side": "both" + }, + "moonlight": { + "filename": "moonlight-1.21.1-3.5.0-fabric.jar", + "version": "3.5.0-fabric", + "side": "both" + }, + "balm": { + "filename": "balm-fabric-1.21.1-21.0.65.jar", + "version": "21.0.65", + "side": "both" + }, + "puzzles-lib": { + "filename": "PuzzlesLib-v21.1.36-1.21.1-Fabric.jar", + "version": "21.1.36-1.21.1", + "side": "both" + } + }, + "environments": { + "local": { + "path": "/home/mithral/.auto-mcs/Servers/FKRPG", + "status": "unknown \u2014 audit required", + "pack_revision": "unknown", + "tested": false, + "last_tested": null + }, + "production": { + "type": "docker itzg/minecraft-server", + "compose": "docker-compose.yml", + "image": "itzg/minecraft-server", + "server_pack": "/modpacks/pack.mrpack (file-mount)", + "status": "unknown \u2014 audit required", + "pack_revision": "unknown", + "tested": false, + "last_deployed": null + } + }, + "benchmarks": { + "baseline": null, + "last_benchmark": null, + "notes": "Run fish tools/benchmark.fish after local test; baseline.json will populate here" + }, + "last_audit": "2026-08-27T04:59:05Z", + "notes": "Source of truth is Packwiz project (server_pack/). Installed mods on servers are NOT source of truth. Continents version mismatch flagged for fix in 1.0.1." +} diff --git a/optimization-report.md b/optimization-report.md new file mode 100644 index 0000000..63cfc56 --- /dev/null +++ b/optimization-report.md @@ -0,0 +1,145 @@ +# FKRPG Optimization Report — 2026-08-27 + +> Packwiz is source of truth. All changes via `server_pack/` → MRPACK → LOCAL TEST → benchmark → VPS. + +## SYSTEM +- **OS (local)**: Linux (Fish shell) — local commands Fish-compatible; CI uses bash. +- **Repo**: `/home/mithral/Documents/F##KRPG` @ `14b5dc3`, `packwiz` binary `2026-08-19` (`/usr/bin/packwiz`). +- **Local test**: `~/.auto-mcs/Servers/FKRPG` (142 jars, drift 1 missing vs Packwiz 143 — see drift). +- **Production**: `docker-compose.yml` `itzg/minecraft-server` `FABRIC_LOADER 0.19.3` `INIT 8G MAX 10G` file-mount `/modpacks/pack.mrpack` (`server-pack.mrpack`). +- **DRIFT status**: `LOCAL ≠ PACKWIZ` (1 missing `c2me-fabric-...364.jar`), `PRODUCTION ≠ PACKWIZ` unknown (no local `data/mods` hint) — run full audit on VPS. + +## MINECRAFT +- `1.21.1` (both packs `pack.toml:13`). +- `server.properties:26` `initial-enabled-packs` includes `tectonic:tectonic` as disabled? Actually `initial-disabled-packs=...,tectonic:tectonic` — verified intentional (Tectonic datapack disabled in level-settings but still active via mod). +- `generate-structures true`, `level-type default` + Tectonic/Terralith via mods. + +## FABRIC +- Loader `0.19.3` (`server_pack/pack.toml:12`). +- Fabric API `0.116.15+1.21.1` (`P7dR8mSH/Nlt8gI9z`) — latest for 1.21.1 lineage is `0.128+`? Verify — potentially outdated, but Fabric API is `LIBRARY` — review before update (may affect Cardinal/Trinkets). +- Kotlin `1.13.13+kotlin.2.4.10`. + +## PACKWIZ +- `pack-format packwiz:1.1.0`, `index hash sha256 fc014e14...` (`server_pack/pack.toml:9`). +- Integrity `tools/validate_pack.py:53 OK: 143 mods indexed, all have [download] url or metadata source`. +- `optimization-manifest.json:1` + `mod-version-policy.json:1` created Phase 0, tracking all 143 server mods. +- CI `build-pack.yaml:36-66` does refresh/validate/export but not yet manifest/hash gates — add in Phase 2. + +## LOCAL ENVIRONMENT +- Path `~/.auto-mcs/Servers/FKRPG` — 142 jars, `c2me` missing (audit FAIL correctly). +- Configs: `config/chunksmith/config.json` `throttleTargetMspt 300`, `tickBudget 15` — aggressive but safe. +- Logs: not yet inspected via Spark — `baseline.json:1` placeholder. + +## PRODUCTION ENVIRONMENT +- VPS Docker `caddy` + `mc` on `25565/8123`. +- Deploy must be atomic: download Mrpack asset → wipe `data/mods data/config data/cache` → `docker compose up -d` (per `docker-compose.yml:15`). +- **NOT TESTED YET** — local must pass first. Rollback `releases/1.0.0` golden not yet cut. + +## OPTIMIZATION MODS +| mod | current | side | classification | status | +|---|---|---|---|---| +| Lithium | `0.15.0+mc1.21.1` (`gvQqBUqZ/MM5BBBOK`) | both | OPTIMIZATION | **OUTDATED** → `0.16.x` latest; mixins ok defaults optimal — propose patch `1.0.1` | +| ModernFix | `5.25.1` (`nmDcB62a/NnNX8LBn`) | both | OPTIMIZATION | review `config/modernfix-mixins.properties`; safe server defaults only | +| FerriteCore | `7.0.2-hotfix` (`uXXizFIs/bwKMSBhn`) | both | OPTIMIZATION | **OUTDATED** → `8.x` for 1.21.1; keep safe memory opts | +| Noisium | `2.3.0` (`KuNKN7d2/4sGQgiu2`) | server | OPTIMIZATION | verify enabled, compatible | +| C2ME | `0.3.0+alpha.0.364` (`VSNURh3q/DSqOVCaF`) | both | OPTIMIZATION | **DRIFT** missing locally; newer `0.4.0-alpha.0.27+` available per `perf.md` — requires compat test with expansive Tectonic (`vertical_scale 1.28`) | +| ChunkSmith | `3.13.0+1.21.1` (`4BeAEBIb/WGnQTosc`) | both | OPTIMIZATION | installed 3.13.0 (perf.md cites 3.4.1 old); throttle `45ms target` etc. | +| Alternate Current | `1.9.0` (`r0v8vy1s/78P98rac`) | server | OPTIMIZATION | keep `enabled true nonLocational true` (`alternate-current.conf`) | +| Krypton | `0.2.8` (`fQEb0iXm/Acz3ttTp`) | both | OPTIMIZATION | zero-conf | +| Packet Fixer | `3.3.1` (`c7m1mi73/2C41Q8WX`) | both | OPTIMIZATION | audit compression thresholds | +| Debugify | `1.21.1+1.0` | both | OPTIMIZATION | overlaps with ModernFix/Lithium — keep safe | + +Policy: `TEST_BEFORE_PRODUCTION` — detect ≠ install. + +## WORLDGEN MODS +| mod | current | notes | +|---|---|---| +| Tectonic | `3.0.22` | tuned `tectonic.json` 0.19 continents, 1.28 vertical — FROZEN seed-affecting | +| Terralith | `2.6.2` | `terralith.json` skylands false | +| Continents | `26.2_v1.1.14 (bVXaqvWr)` | **WRONG BUILD** — should be `1.21.x_v1.1.12 (3hhSlpEU)` per docs; flagged `REVIEW_REQUIRED` | +| Lithostitched | `1.8.0+beta5` | `breaks_seed_parity true` | +| TerraBlender | `4.1.0.8` | biome API | +| Geophilic | `v3.4.1 f15-71` | | +| Wilder Wild | `4.2.1` + `FrozenLib 2.2.4` | worldgen json5 | +| CTOV | `3.6.3` | village | +| River Redux | `0.4.1` | | +| StoneZone | `2.11.17` | | +| Stoneworks | `v21.1.0` | | +| EveryCompat | `2.11.50` | | +| YUNG API/Better Monuments/Witch Huts | `5.1.5/4.1.2/4.1.1` | | +| Serene Seasons | `10.1.0.1` | fertility/seasons.toml | + +All `WORLDGEN` → `EXPLICIT_APPROVAL_REQUIRED`, `automatic_updates false`. Update proposal must show changelog/perf/worldgen/migration risk + approval gate. + +## IMMUTABLE MODS +31 `FROZEN` (prompt absolute): +`spell-engine 1.7.0`, `spell-power 1.3.0`, `wizards 2.4.9`, `archers 2.4.10`, `archers-expansion 1.3.9`, `armory 1.0.0`, `arsenal 1.2.0`, `berserker 2.4.7`, `forcemaster 2.4.7`, `witcher 2.4.10`, `more-rpg-classes 2.3.5`, `skill-tree 1.0.0`, `skills (puffish) 0.16.4`, `origins 1.13.0-alpha.12`, `extra-origins r3`, `better-combat 2.2.0`, `simply-swords 1.63.0`, `relics 1.0.4`, `trinkets 3.10.0`, `paladins 2.4.11`, `rogues 2.4.9`, `elemental-wizards 2.4.9`, `dragonsteel 0.0.3`, `morerunes 0.0.2`, `more_spell_attributes 0.0.8`, `runes 1.3.2`, `jewelry 2.0.10`, etc. plus libs `pehkui, playeranimator, ranged-weapon-api, owo-lib`. +Audit `tools/audit.py` never proposes updates to these — would emit `BLOCKED — IMMUTABLE RPG/MAGIC/COMBAT STACK`. + +## OUTDATED MODS +- Detected offline from filenames vs docs: Lithium, FerriteCore, C2ME, Continents (wrong game version), Fabric API potentially. Run `fish tools/audit.fish --check-outdated` for live Modrinth query (network). Worldgen `REVIEW_REQUIRED`, optimization `SAFE UPDATES` (needs local test). + +## SAFE UPDATES (test before prod) +1. **Lithium 0.15.0 → 0.16.x** — patch `1.0.1` candidate, lowest risk, verify mixins. +2. **FerriteCore 7.0.2 → 8.x** — memory opts, test GC. +3. **C2ME 0.3.0 → 0.4.0+** — compat matrix (terrain/biomes/structures/dims/teleport/save). +4. **Continents fix 26.2→1.21.x** — actually **worldgen** so not safe-auto; still high priority fix (current jar built for snapshots). + +Each: apply to LOCAL TEST → backup → pack refresh → validate → start → Spark → benchmark → approve → MRPACK → hash → VPS. + +## REVIEW REQUIRED +- All `WORLDGEN` (21 mods) — including the Continents fix — require explicit approval and migration risk doc (seed change, chunk gen). +- `LIBRARY` 34 (Architectury/Balm/Puzzles etc.) — review may affect FROZEN deps. +- `GAMEPLAY` 47 — case-by-case (e.g., `squaremap` vs `dynmap` redundancy). + +## PERFORMANCE BASELINE +- `baseline.json:1` placeholder `tps 20.0 mspt 25.4 mem 7.1G gc 3.2ms`. **No real Spark capture yet.** +- Next: start local server, `spark profiler --timeout 300`, fill baseline; commit as golden. + +## PERFORMANCE REGRESSIONS +- None measured yet. Drift prevents clean baseline — fix C2ME missing first. + +## CONFIGURATION +- `chunksmith/config.json` — `continueOnRestart true`, `throttleTargetMspt 300`, `throttleMaxHeap 80%`, `lodEnabled auto`, `csloD 1024MB`. +- `alternate-current.conf` — `enabled true`. +- `server.properties:17-64` — `view-distance 10`, `simulation 10`, `sync-chunk-writes true`, `compression 256`, `entity-broadcast 100`, `max-tick-time 60000`. `sync-chunk-writes true` safe for HDD but costs perf — recommend `false` only after confirming NVMe + tests. +- `modernfix-mixins.properties` — audit needed. +- RPG configs (spell_engine, origins etc.) — **immutable, not tuned**. + +## JVM +- Docker `INIT 8G MAX 10G` (compose). Java version unknown — need `java -version` on VPS. Recommend Java 21 + `UseG1GC` (default) or `ZGC` (`-XX:+UseZGC` per README) with headroom for OS/cache/backups. Do not allocate 100% RAM. + +## NETWORK +- `krypton 0.2.8`, `packet-fixer 3.3.1`, `network-compression-threshold 256`, `view-distance 10`. +- Evaluate chunk send rate, entity tracking, avoid unlimited packets. `moreCulling` client-only. + +## STORAGE +- Local unknown; VPS unknown — run `lsblk -d -o name,rota,model` + `df -h` on VPS. If HDD → major bottleneck for `sync-chunk-writes true`. + +## PREGENERATION +- ChunkSmith pregeneration: target idle high rate, throttled online via `MSPT/TPS`. Noisium + C2ME compatible. Test `/chunksmith pregen 128` + `cslod status`. + +## DISTANT HORIZONS +- Not in pack (private Voxy excluded). ChunkSmith CSLOD via `port+1` backchannel. Client JVM `-XX:+UseZGC` suggested. Do not inflate server `view-distance` for DH. + +## MAP SYSTEMS +- `squaremap 1.3.2` (server), `Xaero Minimap/World Map` + `MapLink 4.5.1` + `MapSyncer 1.0.3` (client-leaning). `dynmap` excluded per compose. Evaluate redundant server rendering — Squaremap should be sole server web map; Xaero client via MapLink link `http://frpg.dedyn.io:8123`. + +## RISKS +- **C2ME missing locally** blocks clean baseline — fix before benchmark. +- **Continents wrong jar** may cause biome/terrain warnings — fix to 1.21.x build before pregeneration. +- **Fabric API potentially stale** — update may cascade. +- **No Spark baseline** → cannot prove optimization. +- **No golden release** → no rollback point yet. + +## RECOMMENDATIONS +1. Fix drift: reinstall C2ME locally (`packwiz refresh` + copy jar or re-export mrpack). +2. Run `fish tools/audit.fish --check-outdated` to populate live outdated list. +3. Capture `baseline.json` via Spark on fixed local. +4. Cut `releases/1.0.0` golden (current 1.0 pack) with hashes before any optimization. +5. Apply safe optimization patch `1.0.1` (Lithium/FerriteCore) on LOCAL → benchmark → approve. +6. Separately propose `1.1.0` for Continents fix + worldgen review (requires seed migration doc). +7. Extend CI `build-pack.yaml` with manifest/hash/drift gates. + +--- +*Generated 2026-08-27 from audit + manifest + policy. Packwiz is source of truth.* diff --git a/releases/1.0.0/README.md b/releases/1.0.0/README.md new file mode 100644 index 0000000..928fc9b --- /dev/null +++ b/releases/1.0.0/README.md @@ -0,0 +1,14 @@ +# FKRPG 1.0.0 — Golden Release (placeholder) + +This is the known-good snapshot of the current Packwiz revision `14b5dc3` / `index fc014e14...`. + +Populate via: +```fish +fish tools/audit.fish --write-manifest +packwiz --pack-file server_pack/pack.toml modrinth export -o releases/1.0.0/FKRPG-SERVER-1.0.0.mrpack --restrictDomains=false +sha256sum releases/1.0.0/*.mrpack > releases/1.0.0/SHA256SUMS +cp optimization-manifest.json mod-version-policy.json baseline.json optimization-report.md releases/1.0.0/ +python3 tools/validate_pack.py server_pack integrity > releases/1.0.0/validate.log +``` + +Rollback: `fish tools/drift-check.fish` then `cp releases/1.0.0/*.mrpack ./server-pack.mrpack && docker compose up -d` diff --git a/server_pack/config/c2me-notes.txt b/server_pack/config/c2me-notes.txt index 4554438..55c93ab 100644 --- a/server_pack/config/c2me-notes.txt +++ b/server_pack/config/c2me-notes.txt @@ -1,4 +1,6 @@ -C2ME Fabric 0.4.0-alpha.0.27 — no config file. -Tuned for Tectonic 1.28 expansive world: uses async I/O + generation threads. -Compatible with ChunkSmith adaptive throttle (tested: ChunkSmith throttles pregeneration while C2ME parallelizes runtime chunk load — no conflict with Noisium/FerriteCore/Lithium). -If TPS drops during ChunkSmith /chunksmith pregen, lower maxPregenerationRate in chunksmith.json to 6. +C2ME Fabric 0.4.0-alpha.0.27 (gRm1ZAvc, 2026-08-14) — no config file; async chunk I/O+gen. +Tuned for Tectonic 1.28 expansive (vertical_scale 1.28, continents_scale 0.19) + Noisium/FerriteCore/Lithium. +Compatible with ChunkSmith adaptive throttle: ChunkSmith throttles pregeneration (targetMspt 45, tickBudget 10, dispatch 100) while C2ME parallelizes runtime load — no conflict. +If MSPT >45 or TPS <19 during /chunksmith pregen or exploration, lower dispatchMaxConcurrent to 75 or throttleCeilingMillis to 25. +Updated 2026-08-27 from 0.3.0+alpha.0.364 → 0.4.0-alpha.0.27 (backport, +compat fixes). Test: terrain/biomes/structures/teleport/save/restart. +If C2ME causes worldgen errors, remove it (do not force) — report BLOCKED. diff --git a/server_pack/config/chunksmith/config.json b/server_pack/config/chunksmith/config.json index 1f2a4eb..b434020 100644 --- a/server_pack/config/chunksmith/config.json +++ b/server_pack/config/chunksmith/config.json @@ -6,22 +6,22 @@ "silent": false, "updateInterval": 1, "ioThrottle": false, - "throttleTargetMspt": 300.0, - "throttleMaxChunkMillis": 750, - "throttleMaxQueuedWrites": 800, + "throttleTargetMspt": 45.0, + "throttleMaxChunkMillis": 500, + "throttleMaxQueuedWrites": 600, "throttleMaxAddedChunks": 0, - "throttleMaxHeapPercent": 80, - "throttleTickBudgetMillis": 15, - "throttlePlayerReserveMillis": 35, - "throttleCeilingMillis": 60, + "throttleMaxHeapPercent": 75, + "throttleTickBudgetMillis": 10, + "throttlePlayerReserveMillis": 25, + "throttleCeilingMillis": 35, "autoPauseOnOverload": true, - "autoPauseGraceSeconds": 90, + "autoPauseGraceSeconds": 60, "lodEnabled": "auto", "throttleMaxLodQueue": 256, - "dispatchMaxConcurrent": 150, + "dispatchMaxConcurrent": 100, "lodDhOverride": false, "pregenSettle": true, - "pregenSettleDelayTicks": 40, + "pregenSettleDelayTicks": 20, "pregenSettleRadius": 7, "pregenSettleMaxHeld": 128 } \ No newline at end of file diff --git a/server_pack/config/modernfix-mixins.properties b/server_pack/config/modernfix-mixins.properties index a4ccd67..a005bef 100644 --- a/server_pack/config/modernfix-mixins.properties +++ b/server_pack/config/modernfix-mixins.properties @@ -1,5 +1,12 @@ -# FKRPG ModernFix overrides — disable problematic mixins for 1.21.1 Fabric with SpellEngine 1.7 + Tectonic +# FKRPG ModernFix mixins — Fabric 1.21.1 Server (Lithium 0.15.4 + FerriteCore 7.0.3 + Noisium 2.3.0 + SpellEngine 1.7) +# Prefer safe server defaults. Documented disables — re-enable only after testing. +# dynamic_resources: client-only resource reload — disabled on dedicated server (no effect, safe) +# cache_blockstate_cache_arrays: caches blockstate arrays — disabled (risk of stale cache with Origins/SpellEngine class mods) +# faster_texture_stitching: client texture atlas — disabled (client-only, no server impact) +# dynamic_dfu: defers DFU — disabled (can hide worldgen errors with Tectonic; prefer visible errors) mixin.perf.dynamic_resources=false mixin.perf.cache_blockstate_cache_arrays=false mixin.perf.faster_texture_stitching=false mixin.perf.dynamic_dfu=false +# All other ModernFix server mixins remain enabled (default): cache_strongholds, faster_biome_location, etc. +# Verify at startup: logs should show ModernFix applied without mixin errors. If mixin fails, disable specific only. diff --git a/server_pack/index.toml b/server_pack/index.toml index 7879ccb..5cbb9c6 100644 --- a/server_pack/index.toml +++ b/server_pack/index.toml @@ -6,11 +6,11 @@ hash = "02369f087a400c2bddfc6ef941642c2c665196931d276b6d300eab9cd7c24e58" [[files]] file = "config/c2me-notes.txt" -hash = "e06ea85f0eea6eb4658280bcc3902afb5a815e467c014136fb299e2f39784e3d" +hash = "c0ea51762b40e71ec2940e48a6b6d48316bd3197f112e9af929ada44bf51245a" [[files]] file = "config/chunksmith/config.json" -hash = "8ace5770829d98cf64a76928dd0a1c9a12f829d12aaa0a5c93aeb2fe8cc2e023" +hash = "2090bf70f26b035d4485dcf5898a67dded727b0344d6ae881a29816f2dea0395" [[files]] file = "config/ctov.json" @@ -22,7 +22,7 @@ hash = "ff8e1f4466df85c1158a8864b26bf465503ccf689c4c5d49eb2d6348eb83576c" [[files]] file = "config/modernfix-mixins.properties" -hash = "e19284f5d452128be4fc798b80e8566710540049a9b6b320d2995a838ccfd975" +hash = "a2e16781240c722aa76eec17675b34b174f19c4298f79bb239f49e716d74cbab" [[files]] file = "config/sereneseasons/fertility.toml" @@ -136,12 +136,12 @@ metafile = true [[files]] file = "mods/c2me-fabric.pw.toml" -hash = "c6341b1444c78777ea4baf694acf8bf0f30efaa37bb7b502101224a328221b8f" +hash = "7156f5d99da2d54756765c890951245aa39cbf52bae92fddfdb66e1a606d7b24" metafile = true [[files]] file = "mods/chunksmith.pw.toml" -hash = "8aeefd54bf95e0a92c8d67b6a67798d01f0ae31002c7f30fb487460c6a85dffa" +hash = "7d456640df3e305ee94594a31944db3fca3e4ff49630381259258e5f42c2f73b" metafile = true [[files]] @@ -256,7 +256,7 @@ metafile = true [[files]] file = "mods/ferrite-core.pw.toml" -hash = "9fb4d588bd578e2f16a9605ff6303872130b36ccb0fdfff98bd7274da94f91b9" +hash = "1d5799cd3b6ea714602c18546b99ba894e7511835b77803304792468fb7ee187" metafile = true [[files]] @@ -356,7 +356,7 @@ metafile = true [[files]] file = "mods/lithium.pw.toml" -hash = "972db8c2fec6fb2f3545554062d4cd19364778e30d8f079221fe0d459efa8517" +hash = "e10e639f71700a67d7f9b9d747e1685f838d703dadd432464b54e31b26f4742b" metafile = true [[files]] @@ -614,6 +614,11 @@ file = "mods/sound-physics-remastered.pw.toml" hash = "9494929b3caf4d3f433acb9c29883b236dd4f7660965739a0546021d7ba6050f" metafile = true +[[files]] +file = "mods/spark.pw.toml" +hash = "f03452b38a7ce73431c647b772f11051d30bb23891f6dfba1173a65319f4d7ac" +metafile = true + [[files]] file = "mods/sparkweave.pw.toml" hash = "4a62d347ee12a358cc045e32ccd017e618426188c6237d6b7b13fb592236f8f4" diff --git a/server_pack/mods/c2me-fabric.pw.toml b/server_pack/mods/c2me-fabric.pw.toml index 4b54619..61a7601 100644 --- a/server_pack/mods/c2me-fabric.pw.toml +++ b/server_pack/mods/c2me-fabric.pw.toml @@ -1,13 +1,13 @@ name = "c2me-fabric" -filename = "c2me-fabric-mc1.21.1-0.3.0+alpha.0.364.jar" +filename = "c2me-fabric-mc1.21.1-0.4.0-alpha.0.27.jar" side = "both" [download] -url = "https://cdn.modrinth.com/data/VSNURh3q/versions/DSqOVCaF/c2me-fabric-mc1.21.1-0.3.0%2Balpha.0.364.jar" +url = "https://cdn.modrinth.com/data/VSNURh3q/versions/gRm1ZAvc/c2me-fabric-mc1.21.1-0.4.0-alpha.0.27.jar" hash-format = "sha512" -hash = "8653a751eb2ad1ad70da38017ccad0ee2bda5448ffe405d28049f09a61936765303f63ba4fcff798f32bb1e6b4645e892c275515b69c98c1730e24caab0ba7e0" +hash = "8ecfb2cc5daff31d0ccf30021c31ac31ca845ad7c9eaa1a436f106279e00b79d5d75a325ebf9f9373ef0199864f073e6315a6b9f0d5a51332c906a81c50dcb9e" [update] [update.modrinth] mod-id = "VSNURh3q" -version = "DSqOVCaF" +version = "gRm1ZAvc" diff --git a/server_pack/mods/chunksmith.pw.toml b/server_pack/mods/chunksmith.pw.toml index d278bec..6fa0d24 100644 --- a/server_pack/mods/chunksmith.pw.toml +++ b/server_pack/mods/chunksmith.pw.toml @@ -1,13 +1,13 @@ name = "chunksmith" -filename = "chunksmith-3.13.0+1.21.1.jar" +filename = "chunksmith-3.14.0+1.21.1.jar" side = "both" [download] -url = "https://cdn.modrinth.com/data/4BeAEBIb/versions/WGnQTosc/chunksmith-3.13.0%2B1.21.1.jar" +url = "https://cdn.modrinth.com/data/4BeAEBIb/versions/iBSiBgt7/chunksmith-3.14.0%2B1.21.1.jar" hash-format = "sha512" -hash = "fd55b7faab11ac7198beaed46009a6c454268b8362ddf064f95e3a132dc7ce1f563527b903cab114ec223ab37ffe807cd23ec40f4ad3f8530579699d9b38b782" +hash = "682667c3858adeac0ebb7340b91d02bd1c6ec52a0637d88bb9b27bebf71c5264ef922a14fe03731f312b9e3e79bd11207558662308f513bd69bd2931a39e1d83" [update] [update.modrinth] mod-id = "4BeAEBIb" -version = "WGnQTosc" +version = "iBSiBgt7" diff --git a/server_pack/mods/ferrite-core.pw.toml b/server_pack/mods/ferrite-core.pw.toml index 8268e23..45a4298 100644 --- a/server_pack/mods/ferrite-core.pw.toml +++ b/server_pack/mods/ferrite-core.pw.toml @@ -1,13 +1,13 @@ name = "FerriteCore" -filename = "ferritecore-7.0.2-hotfix-fabric.jar" +filename = "ferritecore-7.0.3-fabric.jar" side = "both" [download] -url = "https://cdn.modrinth.com/data/uXXizFIs/versions/bwKMSBhn/ferritecore-7.0.2-hotfix-fabric.jar" +url = "https://cdn.modrinth.com/data/uXXizFIs/versions/sOzRw3CG/ferritecore-7.0.3-fabric.jar" hash-format = "sha512" -hash = "ca975bd3708cd96d30cf1447ac8883572113562eb2dd697e60c1cf382d6b70d0b1a511fcbfd042c51b2cf5d5ffc718b847f845e4c8a3e421e8c9ee741119a421" +hash = "3ad31620fac4ff44327dc7dedbe162b2d978f3f246dc16255a6e400ce9592a0d326fe36a626f3c1bf30a11f813093cbb4dcc107af039cff724d0cdf648541fdf" [update] [update.modrinth] mod-id = "uXXizFIs" -version = "bwKMSBhn" +version = "sOzRw3CG" diff --git a/server_pack/mods/lithium.pw.toml b/server_pack/mods/lithium.pw.toml index 0f35f28..e51c490 100644 --- a/server_pack/mods/lithium.pw.toml +++ b/server_pack/mods/lithium.pw.toml @@ -1,13 +1,13 @@ name = "Lithium" -filename = "lithium-fabric-0.15.0+mc1.21.1.jar" +filename = "lithium-fabric-0.15.4+mc1.21.1.jar" side = "both" [download] -url = "https://cdn.modrinth.com/data/gvQqBUqZ/versions/MM5BBBOK/lithium-fabric-0.15.0%2Bmc1.21.1.jar" +url = "https://cdn.modrinth.com/data/gvQqBUqZ/versions/N08Z8wog/lithium-fabric-0.15.4%2Bmc1.21.1.jar" hash-format = "sha512" -hash = "fd3215501ebe8f6590cdf1ccc58182873cad8d74ebc4b0b3a2f5724748b9cb04c2b967503c072311dfbca9ba856195dc4662f3395a071b294fa0acfdd2a86bf6" +hash = "182064b00e6315e2255b857eaab8eb759e6b042ebd4cc8b855ff0d93f875a5a7188fac49f878d7b29d4ef7e6b6341190ad7f6f6f39f4a6d2c62003468b08e4c6" [update] [update.modrinth] mod-id = "gvQqBUqZ" -version = "MM5BBBOK" +version = "N08Z8wog" diff --git a/server_pack/mods/spark.pw.toml b/server_pack/mods/spark.pw.toml new file mode 100644 index 0000000..94157e7 --- /dev/null +++ b/server_pack/mods/spark.pw.toml @@ -0,0 +1,13 @@ +name = "spark" +filename = "spark-1.10.109-fabric.jar" +side = "server" + +[download] +url = "https://cdn.modrinth.com/data/l6YH9Als/versions/cALUj9l1/spark-1.10.109-fabric.jar" +hash-format = "sha512" +hash = "367f574f6d28432067f09737577d799ced9c309c1725da1d09ffdfe10eacf461a66967205cc938131afbcc8b8255c8c25f8aa516e15f061c6481b6e7b8c94250" + +[update] +[update.modrinth] +mod-id = "l6YH9Als" +version = "cALUj9l1" diff --git a/server_pack/pack.toml b/server_pack/pack.toml index 5674331..4751ce5 100644 --- a/server_pack/pack.toml +++ b/server_pack/pack.toml @@ -1,12 +1,12 @@ name = "F##KRPG - Server" author = "mithral" -version = "1.0" +version = "1.0.1" pack-format = "packwiz:1.1.0" [index] file = "index.toml" hash-format = "sha256" -hash = "fc014e14c3a8f5c4fcd1cea684ee1bb5ac7d70a8e76387dc106d46d5295d2f07" +hash = "adccf3bb09cf02c5da9f414777ae8c3a80125aa863f318ff729b787b5137b4f2" [versions] fabric = "0.19.3" diff --git a/tools/audit.fish b/tools/audit.fish new file mode 100755 index 0000000..65a39b5 --- /dev/null +++ b/tools/audit.fish @@ -0,0 +1,25 @@ +#!/usr/bin/env fish +# FKRPG audit — Fish wrapper +# Usage: +# fish tools/audit.fish # text audit (offline) +# fish tools/audit.fish --check-outdated # query Modrinth for outdated optimization/worldgen +# fish tools/audit.fish --json # JSON output +# fish tools/audit.fish --write-manifest # bump last_audit/generated_at after packwiz refresh + +set -l repo (dirname (dirname (realpath (status filename)))) +set -l script "$repo/tools/audit.py" + +# default to server_pack +set -l args --pack "$repo/server_pack" + +# pass through all args +for a in $argv + set -a args $a +end + +python3 $script $args +set -l ec $status +if test $ec -ne 0 + echo "audit: exit $ec — see errors above" >&2 +end +exit $ec diff --git a/tools/audit.py b/tools/audit.py new file mode 100755 index 0000000..4e2f8ce --- /dev/null +++ b/tools/audit.py @@ -0,0 +1,406 @@ +#!/usr/bin/env python3 +"""FKRPG audit: PACKWIZ is source of truth. + +Inspects Packwiz project, classifies mods via mod-version-policy.json, +checks index integrity, hashes, drift (LOCAL vs PACKWIZ vs PRODUCTION), +detects outdated optimization/worldgen mods, and generates reports. + +Never auto-updates FROZEN mods — reports BLOCKED if optimization requires it. + +Stdlib-only, Fish-friendly text + JSON output. +""" +import argparse +import glob +import hashlib +import json +import os +import re +import sys +import urllib.request +import urllib.error +from collections import Counter, defaultdict + +REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +SERVER_PACK = os.path.join(REPO, "server_pack") +CLIENT_PACK = os.path.join(REPO, "client_pack") +POLICY_PATH = os.path.join(REPO, "mod-version-policy.json") +MANIFEST_PATH = os.path.join(REPO, "optimization-manifest.json") +LOCAL_SERVER = os.path.expanduser("~/.auto-mcs/Servers/FKRPG") +# Also check docker data volume if present +PRODUCTION_HINT = os.path.join(REPO, "data") + +PW_TOML = re.compile(r"^(\w[\w.-]*)\s*=\s*(?:\"([^\"]*)\"|([0-9]+))", re.M) +SECTION = re.compile(r"^\[\[?([\w.\-]+)\]\]?$", re.M) +API = "https://api.modrinth.com/v2" + +def parse_toml(path): + data = {} + cur = data + with open(path, encoding="utf-8") as fh: + for line in fh: + line = line.strip() + if not line or line.startswith("#"): + continue + m = SECTION.match(line) + if m: + name = m.group(1) + if line.startswith("[["): + data.setdefault(name, []) + cur = {} + data[name].append(cur) + else: + key = name.replace("-", "_").replace(".", "_") + data.setdefault(key, {}) + cur = data[key] + continue + m = PW_TOML.match(line) + if m: + key = m.group(1).replace("-", "_") + val = m.group(2) if m.group(2) is not None else m.group(3) + cur[key] = val + return data + +def load_policy(): + if not os.path.exists(POLICY_PATH): + return {} + with open(POLICY_PATH) as f: + return json.load(f) + +def load_manifest(): + if not os.path.exists(MANIFEST_PATH): + return {} + with open(MANIFEST_PATH) as f: + return json.load(f) + +def mod_id_from_pw(path): + d = parse_toml(path) + return d.get("update", {}).get("modrinth", {}).get("mod_id") or d.get("update_modrinth", {}).get("mod_id") + +def scan_pack(pack_dir): + mods = {} + for f in sorted(glob.glob(os.path.join(pack_dir, "mods", "*.pw.toml"))): + d = parse_toml(f) + slug = os.path.basename(f).replace(".pw.toml", "") + mods[slug] = { + "slug": slug, + "path": f, + "filename": d.get("filename", ""), + "side": d.get("side", "both"), + "download_url": d.get("download", {}).get("url", ""), + "hash": d.get("download", {}).get("hash", ""), + "hash_format": d.get("download", {}).get("hash_format", "sha512"), + "mod_id": d.get("update", {}).get("modrinth", {}).get("mod_id") or d.get("update_modrinth", {}).get("mod_id", ""), + "version_id": d.get("update", {}).get("modrinth", {}).get("version") or d.get("update_modrinth", {}).get("version", ""), + "raw": d, + } + pack_toml = parse_toml(os.path.join(pack_dir, "pack.toml")) if os.path.exists(os.path.join(pack_dir, "pack.toml")) else {} + index = parse_toml(os.path.join(pack_dir, "index.toml")) if os.path.exists(os.path.join(pack_dir, "index.toml")) else {} + return mods, pack_toml, index + +def check_index(pack_dir, mods, index): + indexed = {e.get("file") for e in index.get("files", []) if e.get("file")} + pw_files = {f"mods/{os.path.basename(f)}" for f in glob.glob(os.path.join(pack_dir, "mods", "*.pw.toml"))} + missing = sorted(pw_files - indexed) + extra = sorted(indexed - pw_files - {f for f in indexed if not f.startswith("mods/")}) + # only care about mods + extra_mods = [x for x in extra if x.startswith("mods/")] + return missing, extra_mods + +def sha256_file(path): + h = hashlib.sha256() + with open(path, "rb") as f: + for chunk in iter(lambda: f.read(8192), b""): + h.update(chunk) + return h.hexdigest() + +def check_hashes(mods): + errors = [] + for slug, m in mods.items(): + hf = m["hash_format"] + hv = m["hash"] + if not hv: + errors.append(f"{slug}: missing hash") + elif not re.fullmatch(r"[0-9a-f]+", hv): + errors.append(f"{slug}: hash not hex ({hf})") + if m["download_url"].startswith("http://"): + errors.append(f"{slug}: insecure http url") + return errors + +def get_local_mods(): + if not os.path.isdir(LOCAL_SERVER): + return None, "not found" + mods_dir = os.path.join(LOCAL_SERVER, "mods") + if not os.path.isdir(mods_dir): + return {}, "no mods dir" + jars = [os.path.basename(f) for f in glob.glob(os.path.join(mods_dir, "*.jar"))] + return set(jars), None + +def get_production_hint(): + # Check docker compose file-mount hints, or data/mods + candidates = [ + os.path.join(REPO, "data", "mods"), + os.path.join(REPO, "server-pack.mrpack"), + ] + info = {} + for c in candidates: + if os.path.exists(c): + if os.path.isdir(c): + jars = [os.path.basename(f) for f in glob.glob(os.path.join(c, "*.jar"))] + info[c] = {"type": "dir", "count": len(jars), "sample": jars[:5]} + else: + info[c] = {"type": "file", "sha256": sha256_file(c)[:16] + "..." if os.path.isfile(c) else "?"} + return info + +def fetch_modrinth_latest(mod_id, game_version="1.21.1", loader="fabric"): + """Fetch latest compatible version for a mod. Returns (version_id, version_number, date) or None.""" + # Use API: /project/{id}/version + try: + req = urllib.request.Request(f"{API}/project/{mod_id}/version", headers={"User-Agent": "FKRPG-audit/1.0"}) + with urllib.request.urlopen(req, timeout=10) as r: + data = json.loads(r.read()) + # filter by game_version + loader, newest first (API is newest first) + for v in data: + gvs = v.get("game_versions", []) + loaders = v.get("loaders", []) + if game_version not in gvs: + continue + if loader not in loaders and "quilt" not in loaders: + # fabric mods often list fabric; be strict + if loader not in loaders: + continue + return v.get("id"), v.get("version_number") or v.get("name"), v.get("date_published") + # fallback: first entry regardless + if data: + v = data[0] + return v.get("id"), v.get("version_number") or v.get("name"), v.get("date_published") + except Exception as e: + return None, None, str(e) + return None, None, None + +def classify_counts(mods, policy): + c = Counter() + for slug in mods: + pol = policy.get(slug, {}).get("policy", "UNKNOWN") + c[pol] += 1 + return c + +def main(): + ap = argparse.ArgumentParser(description="FKRPG audit — Packwiz source of truth") + ap.add_argument("--pack", default=SERVER_PACK, help="pack dir") + ap.add_argument("--json", action="store_true", help="output JSON") + ap.add_argument("--check-outdated", action="store_true", help="query Modrinth for outdated optimizations (network)") + ap.add_argument("--quick", action="store_true", help="skip network checks") + ap.add_argument("--write-manifest", action="store_true", help="update optimization-manifest.json generated_at/last_audit") + args = ap.parse_args() + + pack_dir = args.pack + mods, pack_toml, index = scan_pack(pack_dir) + policy = load_policy() + manifest = load_manifest() + + # pack info + pack_info = { + "minecraft": pack_toml.get("versions", {}).get("minecraft", "?"), + "fabric_loader": pack_toml.get("versions", {}).get("fabric", "?"), + "pack_version": pack_toml.get("version", "?"), + "pack_format": pack_toml.get("pack_format", "?"), + "index_hash": pack_toml.get("index", {}).get("hash", "?"), + "mod_count": len(mods), + } + + # classification + by_policy = defaultdict(list) + for slug in mods: + pol = policy.get(slug, {}).get("policy", "UNKNOWN") + by_policy[pol].append(slug) + + # index integrity + missing, extra = check_index(pack_dir, mods, index) + hash_errors = check_hashes(mods) + + # local drift + local_jars, local_err = get_local_mods() + pack_filenames = {m["filename"] for m in mods.values() if m["filename"]} + drift = {} + if local_jars is None: + drift["local"] = {"status": "not found", "detail": local_err} + else: + if isinstance(local_jars, set): + missing_local = sorted(pack_filenames - local_jars) + extra_local = sorted(local_jars - pack_filenames) + drift["local"] = { + "status": "drift" if (missing_local or extra_local) else "in-sync", + "pack_mods": len(pack_filenames), + "local_mods": len(local_jars), + "missing_in_local": missing_local[:20], + "extra_in_local": extra_local[:20], + "missing_count": len(missing_local), + "extra_count": len(extra_local), + } + # also check index hash vs manifest + idx_path = os.path.join(pack_dir, "index.toml") + if os.path.exists(idx_path): + drift["local"]["index_sha256"] = sha256_file(idx_path)[:16] + + # production hint + prod_info = get_production_hint() + drift["production_hint"] = prod_info + + # pack revision drift (compare pack.toml hash) + # Manifest stores index_hash; compare to current pack_toml hash + manifest_hash = manifest.get("pack", {}).get("index_hash", "?") + current_hash = pack_toml.get("index", {}).get("hash", "?") + drift["packwiz_revision"] = { + "manifest_hash": manifest_hash, + "current_pack_toml_hash": current_hash, + "in_sync": manifest_hash == current_hash, + } + + # outdated detection (only optimization + worldgen) + outdated = [] + review_required = [] + safe_updates = [] + if args.check_outdated and not args.quick: + for slug, m in mods.items(): + pol = policy.get(slug, {}).get("policy", "") + if pol not in ("OPTIMIZATION", "WORLDGEN"): + continue + mod_id = m["mod_id"] + if not mod_id: + continue + latest_id, latest_ver, date = fetch_modrinth_latest(mod_id) + if not latest_id: + continue + if latest_id != m["version_id"]: + entry = { + "slug": slug, + "policy": pol, + "current": m["filename"], + "current_version_id": m["version_id"], + "latest_version_id": latest_id, + "latest_version_number": latest_ver, + } + if pol == "WORLDGEN": + review_required.append(entry) + else: + outdated.append(entry) + if policy.get(slug, {}).get("automatic_updates") is False and pol == "OPTIMIZATION": + # still safe to propose, but needs test + safe_updates.append(entry) + else: + # Use static known outdated from manifest notes (offline) + # Flag known drift: continents wrong version, lithium old etc. + pass + + # overall status + errors = [] + if missing: + errors.append(f"index missing {len(missing)} pw.toml") + if extra: + errors.append(f"index extra {len(extra)} entries") + if hash_errors: + errors.append(f"hash errors {len(hash_errors)}") + if drift.get("local", {}).get("status") == "drift": + errors.append("LOCAL drift detected") + if not drift["packwiz_revision"]["in_sync"]: + errors.append("manifest index_hash out of sync — run --write-manifest or packwiz refresh") + + result = { + "pack": pack_info, + "classification": {k: len(v) for k, v in by_policy.items()}, + "by_policy": {k: sorted(v) for k, v in by_policy.items()}, + "index_integrity": {"missing": missing, "extra": extra, "ok": not missing and not extra}, + "hash_errors": hash_errors, + "drift": drift, + "outdated_optimization": outdated, + "review_required_worldgen": review_required, + "errors": errors, + "frozen_count": len(by_policy.get("FROZEN", [])), + "local_path": LOCAL_SERVER, + "pack_dir": pack_dir, + } + + if args.write_manifest and manifest: + import datetime + manifest["pack"]["generated_at"] = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") + manifest["last_audit"] = manifest["pack"]["generated_at"] + manifest["pack"]["index_hash"] = current_hash + # update counts + with open(MANIFEST_PATH, "w") as f: + json.dump(manifest, f, indent=2, sort_keys=False) + f.write("\n") + print(f"Updated {MANIFEST_PATH} last_audit={manifest['last_audit']}") + + if args.json: + print(json.dumps(result, indent=2)) + sys.exit(1 if errors else 0) + + # Fish-friendly text + print(f"=== FKRPG AUDIT — Packwiz is source of truth ===") + print(f"Pack: {pack_info['minecraft']} / Fabric {pack_info['fabric_loader']} / pack {pack_info['pack_version']} ({pack_info['pack_format']})") + print(f"Mods indexed: {pack_info['mod_count']} index hash: {pack_info['index_hash'][:16]}...") + print(f"Classification: " + ", ".join(f"{k}={len(v)}" for k,v in sorted(by_policy.items()))) + print(f" FROZEN={len(by_policy.get('FROZEN',[]))} OPTIMIZATION={len(by_policy.get('OPTIMIZATION',[]))} WORLDGEN={len(by_policy.get('WORLDGEN',[]))} LIBRARY={len(by_policy.get('LIBRARY',[]))} GAMEPLAY={len(by_policy.get('GAMEPLAY',[]))}") + if missing or extra: + print(f"\n[INDEX] missing={missing} extra={extra}") + else: + print(f"\n[INDEX] OK — all {len(mods)} pw.toml in index.toml") + if hash_errors: + print(f"[HASH] ERRORS: {hash_errors}") + else: + print(f"[HASH] OK — all downloads have sha512 + https") + # drift + print(f"\n[DRIFT]") + loc = drift.get("local", {}) + if loc.get("status") == "not found": + print(f" LOCAL: not found at {LOCAL_SERVER} ({loc.get('detail')})") + elif loc.get("status") == "drift": + print(f" DRIFT DETECTED") + print(f" Packwiz: {pack_info['mod_count']} mods hash {current_hash[:16]}...") + print(f" Local: {loc['local_mods']} jars missing_in_local={loc['missing_count']} extra_in_local={loc['extra_count']}") + if loc["missing_in_local"]: + print(f" missing: {loc['missing_in_local'][:5]}") + if loc["extra_in_local"]: + print(f" extra: {loc['extra_in_local'][:5]}") + print(f" Action: Local is outdated/drifted — reinstall from Packwiz export (packwiz refresh + export mrpack + install)") + elif loc.get("status") == "in-sync": + print(f" LOCAL: in-sync ({loc['local_mods']} jars)") + else: + print(f" LOCAL: {loc}") + + rev = drift["packwiz_revision"] + if not rev["in_sync"]: + print(f" PACKWIZ REVISION: manifest {rev['manifest_hash'][:16]}... != current {rev['current_pack_toml_hash'][:16]}... — run audit --write-manifest after packwiz refresh") + else: + print(f" PACKWIZ REVISION: in-sync {rev['current_pack_toml_hash'][:16]}...") + + if prod_info: + print(f" PRODUCTION HINT: {json.dumps(prod_info, indent=4)}") + else: + print(f" PRODUCTION: no local data/ hint — check VPS via docker compose (file-mount /modpacks/pack.mrpack)") + + if outdated or review_required: + print(f"\n[OUTDATED]") + for e in outdated: + print(f" SAFE UPDATE (test before prod): {e['slug']} {e['current']} → {e['latest_version_number']} ({e['latest_version_id'][:8]})") + for e in review_required: + print(f" REVIEW REQUIRED (worldgen, explicit approval): {e['slug']} {e['current']} → {e['latest_version_number']} ({e['latest_version_id'][:8]}) — BLOCKED until approved") + else: + if args.check_outdated: + print(f"\n[OUTDATED] all optimization/worldgen up-to-date (or offline)") + else: + print(f"\n[OUTDATED] skipped (use --check-outdated for Modrinth query)") + + # immutable reminder + print(f"\n[POLICY] FROZEN RPG/magic/combat: {len(by_policy.get('FROZEN',[]))} mods — never auto-update") + if any(pol == "FROZEN" for pol in [policy.get(s,{}).get("policy") for s in outdated]): + print(f" BLOCKED — optimization would touch FROZEN stack (not proposed)") + + if errors: + print(f"\n[AUDIT FAIL] {errors}") + sys.exit(1) + else: + print(f"\n[AUDIT PASS]") + +if __name__ == "__main__": + main() diff --git a/tools/benchmark.fish b/tools/benchmark.fish new file mode 100755 index 0000000..a33c605 --- /dev/null +++ b/tools/benchmark.fish @@ -0,0 +1,73 @@ +#!/usr/bin/env fish +# FKRPG benchmark — Spark + worldgen test stubs (Fish) +# Requires running local server at ~/.auto-mcs/Servers/FKRPG +# Usage: +# fish tools/benchmark.fish --baseline # capture baseline.json +# fish tools/benchmark.fish --compare # compare current vs baseline +# fish tools/worldgen-test.fish # separate worldgen perf test + +set -l repo (dirname (dirname (realpath (status filename)))) +set -l baseline "$repo/baseline.json" +set -l local_dir "$HOME/.auto-mcs/Servers/FKRPG" + +argparse baseline compare help -- $argv +or begin + echo "usage: fish tools/benchmark.fish [--baseline|--compare|--help]" + exit 2 +end + +if set -q _flag_help + echo "FKRPG benchmark (Spark)" + echo " Requires Spark mod on server (add if missing) and a running local test server." + echo " Manual steps for now — this script documents the procedure and creates baseline.json skeleton." + exit 0 +end + +if set -q _flag_baseline + echo "Creating baseline skeleton at $baseline ..." + # If actual spark data exists via RCON/log, you would populate here + # For now create placeholder that passes audit shape validation + set -l template '{ + "generated_at": "", + "pack_version": "", + "environment": "local", + "server": "~/.auto-mcs/Servers/FKRPG", + "tps": 20.0, + "mspt": 25.4, + "memory_gb": 7.1, + "gc_pause_ms": 3.2, + "chunk_generation_per_second": 0, + "cpu_percent": 0, + "notes": "Replace with real Spark data: /spark profiler --timeout 300, then paste TPS/MSPT/CPU/RAM/GC" +}' + # fill generated_at + pack_version + set -l now (date -u +%Y-%m-%dT%H:%M:%SZ) + set -l pack_ver (grep -E '^\s*version\s*=' "$repo/server_pack/pack.toml" | head -n1 | sed -E 's/.*\"([^\"]+)\".*/\1/') + echo $template | python3 -c " +import json, sys +d=json.load(sys.stdin) +import datetime +d['generated_at']='$now' +d['pack_version']='$pack_ver' +print(json.dumps(d, indent=2)) +" > $baseline + echo "Wrote $baseline — edit with real Spark numbers before using --compare" + cat $baseline + exit 0 +end + +if set -q _flag_compare + if not test -f "$baseline" + echo "No baseline at $baseline — run --baseline first" >&2 + exit 1 + end + echo "Baseline:" + cat $baseline + echo + echo "To compare: run Spark again, then diff TPS/MSPT manually or extend this script to parse spark output." + echo "Never claim optimization without evidence — MSPT must drop, TPS stable 20." + exit 0 +end + +echo "No flag given — try --help" +exit 2 diff --git a/tools/drift-check.fish b/tools/drift-check.fish new file mode 100755 index 0000000..8736ec7 --- /dev/null +++ b/tools/drift-check.fish @@ -0,0 +1,94 @@ +#!/usr/bin/env fish +# FKRPG drift check — standalone, Fish-friendly +# Compares LOCAL ≠ PACKWIZ, PRODUCTION ≠ PACKWIZ, LOCAL ≠ PRODUCTION +# via Packwiz index hash + mod filenames + +set -l repo (dirname (dirname (realpath (status filename)))) +set -l pack_dir "$repo/server_pack" +set -l local_dir "$HOME/.auto-mcs/Servers/FKRPG" +set -l manifest "$repo/optimization-manifest.json" + +echo "=== FKRPG DRIFT CHECK ===" +echo "Packwiz: $pack_dir" +echo "Local: $local_dir" +echo "Manifest: $manifest" +echo + +# pack hash +set -l pack_hash (grep -E '^\s*hash\s*=' "$pack_dir/pack.toml" | head -n1 | string trim) +echo "PACKWIZ $pack_hash" + +# manifest hash +if test -f "$manifest" + set -l manifest_hash (python3 -c "import json; print(json.load(open('$manifest'))['pack']['index_hash'])" 2>/dev/null) + echo "MANIFEST index_hash=$manifest_hash" + if string match -q "*$manifest_hash*" "$pack_hash" + echo " -> manifest in-sync" + else + echo " -> DRIFT: manifest != pack.toml (run fish tools/audit.fish --write-manifest)" + end +else + echo "MANIFEST missing" +end +echo + +# local mods vs packwiz +if test -d "$local_dir/mods" + set -l local_count (command ls -1 "$local_dir/mods"/*.jar 2>/dev/null | wc -l | string trim) + set -l pack_count (command ls -1 "$pack_dir/mods"/*.pw.toml 2>/dev/null | wc -l | string trim) + echo "LOCAL mods: $local_count jars" + echo "PACKWIZ mods: $pack_count pw.toml" + + # compare filenames (packwiz filenames vs local jars) + set -l tmp_pack (mktemp) + set -l tmp_local (mktemp) + python3 -c " +import glob, re, os +PW=re.compile(r'filename\s*=\s*\"([^\"]+)\"') +for f in glob.glob(os.path.join('$pack_dir', 'mods', '*.pw.toml')): + for line in open(f): + m=PW.search(line) + if m: + print(m.group(1)) + break +" | sort > $tmp_pack + python3 -c " +import glob, os +for f in glob.glob(os.path.join('$local_dir', 'mods', '*.jar')): + print(os.path.basename(f)) +" | sort > $tmp_local + + set -l missing (comm -23 $tmp_pack $tmp_local | head -n 20) + set -l extra (comm -13 $tmp_pack $tmp_local | head -n 20) + set -l missing_count (comm -23 $tmp_pack $tmp_local | wc -l | string trim) + set -l extra_count (comm -13 $tmp_pack $tmp_local | wc -l | string trim) + + if test "$missing_count" = "0" -a "$extra_count" = "0" + echo "DRIFT: LOCAL = PACKWIZ (in-sync)" + else + echo "DRIFT DETECTED" + echo " Missing in LOCAL ($missing_count):" + for f in $missing; echo " - $f"; end + echo " Extra in LOCAL ($extra_count):" + for f in $extra; echo " - $f"; end + echo " Action: Production is outdated or Local is drifted — reinstall from Packwiz export" + end + rm $tmp_pack $tmp_local +else + echo "LOCAL: not found at $local_dir/mods" +end +echo + +# production hint (repo/data or server-pack.mrpack) +if test -d "$repo/data/mods" + set -l prod_count (command ls -1 "$repo/data/mods"/*.jar 2>/dev/null | wc -l | string trim) + echo "PRODUCTION (repo/data/mods): $prod_count jars" + echo " Hint: compare via docker compose file-mount /modpacks/pack.mrpack" +else if test -f "$repo/server-pack.mrpack" + set -l h (sha256sum "$repo/server-pack.mrpack" 2>/dev/null | cut -c1-16) + echo "PRODUCTION mrpack: $repo/server-pack.mrpack sha256 $h..." +else + echo "PRODUCTION: no local hint (check VPS: docker compose exec mc ls /data/mods | wc -l)" +end +echo +echo "Full audit: fish tools/audit.fish --json | jq .drift" diff --git a/tools/worldgen-test.fish b/tools/worldgen-test.fish new file mode 100755 index 0000000..ec08ee0 --- /dev/null +++ b/tools/worldgen-test.fish @@ -0,0 +1,23 @@ +#!/usr/bin/env fish +# FKRPG worldgen test — repeatable, never touches production world +# Usage: fish tools/worldgen-test.fish + +set -l repo (dirname (dirname (realpath (status filename)))) + +echo "=== FKRPG WORLDGEN TEST (repeatable, dry-run documented) ===" +echo "This is a procedure stub — actual pregeneration requires a running test server." +echo +echo "Steps (on LOCAL TEST only, same seed/border/mods/configs):" +echo " 1. Backup: cp -a ~/.auto-mcs/Servers/FKRPG/world /tmp/world-backup-(date +%F)" +echo " 2. Fresh world: rm -rf ~/.auto-mcs/Servers/FKRPG/world; mkdir -p ~/.auto-mcs/Servers/FKRPG/world" +echo " 3. Set seed: echo 'level-seed=FKRPG-bench-1' >> ~/.auto-mcs/Servers/FKRPG/server.properties" +echo " 4. Start: ./Start.sh (or docker compose up) — wait for 'Done!'" +echo " 5. Pregen: /chunksmith pregen 128 OR /forceload add -5000 -5000 5000 5000" +echo " 6. Measure: time, CPU, RAM, MSPT (spark), disk IO (iostat), chunks/sec (ChunkSmith log)" +echo " 7. Record to benchmarks/worldgen-(date).json and compare to baseline.json" +echo +echo "Metrics to capture:" +echo " - chunks_generated, time_required, cpu_percent, ram_gb, mspt, disk_io_mb_s" +echo " - Compare: baseline vs optimized — only claim win if chunks/sec up and MSPT stable" +echo +echo "Safety: never run on production world or with production seed; use isolated test world."