perf(server): optimization stack 1.0.1 — Lithium 0.15.4, FerriteCore 7.0.3, C2ME 0.4.0-alpha.0.27, ChunkSmith 3.14.0 + Spark, tuned configs
All checks were successful
Build & Release Pack / build (push) Successful in 1m24s
All checks were successful
Build & Release Pack / build (push) Successful in 1m24s
- 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
This commit is contained in:
parent
14b5dc363c
commit
1b3cf45bf6
20 changed files with 2065 additions and 40 deletions
26
baseline.json
Normal file
26
baseline.json
Normal file
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
785
mod-version-policy.json
Normal file
785
mod-version-policy.json
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
407
optimization-manifest.json
Normal file
407
optimization-manifest.json
Normal file
|
|
@ -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."
|
||||
}
|
||||
145
optimization-report.md
Normal file
145
optimization-report.md
Normal file
|
|
@ -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.*
|
||||
14
releases/1.0.0/README.md
Normal file
14
releases/1.0.0/README.md
Normal file
|
|
@ -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`
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
13
server_pack/mods/spark.pw.toml
Normal file
13
server_pack/mods/spark.pw.toml
Normal file
|
|
@ -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"
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
25
tools/audit.fish
Executable file
25
tools/audit.fish
Executable file
|
|
@ -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
|
||||
406
tools/audit.py
Executable file
406
tools/audit.py
Executable file
|
|
@ -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()
|
||||
73
tools/benchmark.fish
Executable file
73
tools/benchmark.fish
Executable file
|
|
@ -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
|
||||
94
tools/drift-check.fish
Executable file
94
tools/drift-check.fish
Executable file
|
|
@ -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"
|
||||
23
tools/worldgen-test.fish
Executable file
23
tools/worldgen-test.fish
Executable file
|
|
@ -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."
|
||||
Loading…
Add table
Reference in a new issue