HappyPeak
Tired of a plain old climb? Spice up every PEAK run with a bunch of toggleable chaos events — random tornadoes, banana rain, lit dynamite, chests that hatch zombies or summon the Scoutmaster, and more.
By Ninex
| Date uploaded | 5 months ago |
| Version | 0.11.6 |
| Download link | Ninex-HappyPeak-0.11.6.zip |
| Downloads | 84 |
| Dependency string | Ninex-HappyPeak-0.11.6 |
This mod requires the following mods to function
BepInEx-BepInExPack_PEAK
BepInEx pack for PEAK. Preconfigured and ready to use.
Preferred version: 5.4.2403README
HappyPeak
Tired of a plain old climb? Spice up every PEAK run with a bunch of toggleable chaos events.
A host-side PEAK mod that randomizes chest loot, scales loot by a configurable multiplier, and adds a handful of independently-toggleable chaos events designed to make co-op runs more unpredictable.
Every event has its own on/off switch and tuning knobs. Don't like banana rain? Turn it off. Want zombies to come out of every chest? Crank ZombieTrapChance. The defaults aim for "noticeable but not run-ruining"; tweak as you like.
Only the host needs to install this mod. Clients see all the effects without installing anything — every spawn / replacement happens host-side and propagates over Photon.
Features
| Section | What it does |
|---|---|
[Randomizer] |
Every chest you open returns a random item from PEAK's full item database (minus a small blacklist of cheat / quest / cosmetic-only items). Bushes, vines, ground spawners and other scenery are not affected. |
[LootScaling] |
Multiply chest loot quantity by a flat integer. 1 = vanilla, 2 = double, 3 = triple, etc. |
[Tornado] |
Periodically spawns tornadoes targeting a random player on any biome (vanilla PEAK only spawns them on Mesa). Disabled at the Kiln by default. |
[BananaPeel] |
Banana rain: drops 2–5 banana peels (random color) from above each player every wave. Configurable drop height. |
[Tumbleweed] |
Tumbleweed rain: same pattern as the banana rain but with PEAK's native tumbleweed prefab. |
[Dynamite] |
Drops a stick of lit dynamite somewhere near a random player every wave. Configurable distance and an option to drop unlit (for harvesting). |
[MarkerSpawn] |
Press middle-click to drop a ping → spawns a pickaxe at the marker location, attached to the nearest surface when possible. One per player at a time — re-pinging moves it. |
[Eruption] |
Triggers PEAK's native "floor erupts in flames" effect near a random player. Requires the game's EruptionSpawner to exist in the current scene. |
[ChestTraps] |
Each chest opening rolls a small chance to spawn a Mushroom Zombie (default 10%) or teleport the Scoutmaster to hunt the opener (default 5%). |
Nothing fires while you're at the airport / lobby — events only run inside an actual mountain run.
Install
Install via Thunderstore Mod Manager or r2modman, or drop HappyPeak.dll into <PEAK install>/BepInEx/plugins/ manually.
Requires the BepInExPack for PEAK.
Configuration
After running the game once with the mod installed, BepInEx generates BepInEx/config/HappyPeak.cfg. Edit it with any text editor — every entry has a bilingual description (English + Chinese) right above it.
Full config reference
[Randomizer]
| Key | Default | Description |
|---|---|---|
EnableItemRandomization |
true |
Master switch for chest randomization. |
AdditionalBlacklist |
"" |
Comma-separated extra item names to exclude (e.g. Dynamite, Scorpion, CactusBall). |
[LootScaling]
| Key | Default | Description |
|---|---|---|
EnableLootScaling |
true |
Toggle for the chest loot multiplier. |
LootMultiplier |
2.0 |
Flat multiplier. 1 = vanilla, 2 = double, 3 = triple. Rounded to integer internally. |
[Tornado]
| Key | Default | Description |
|---|---|---|
EnableRandomTornadoes |
true |
Toggle. |
TornadoIntervalMin |
10 |
Min seconds between waves. |
TornadoIntervalMax |
30 |
Max seconds between waves. |
TornadoesPerWave |
1 |
How many tornadoes per wave. |
TornadoLifetime |
60 |
Seconds before each tornado is removed. |
EnableTornadoAtKiln |
false |
Allow tornadoes at the Kiln (off because they tend to wreck endgame). |
[BananaPeel]
| Key | Default | Description |
|---|---|---|
EnableRandomBananaPeels |
true |
Toggle. |
BananaPeelIntervalMin |
10 |
Min seconds between waves. |
BananaPeelIntervalMax |
30 |
Max seconds. |
BananaPeelsPerPlayerMin |
2 |
Min peels rained per player. |
BananaPeelsPerPlayerMax |
5 |
Max peels rained per player. |
BananaPeelLifetime |
30 |
Seconds before each peel is removed. |
BananaPeelDropHeight |
15 |
Meters above each player to spawn peels (gravity drops them). |
[Tumbleweed]
| Key | Default | Description |
|---|---|---|
EnableRandomTumbleweeds |
true |
Toggle. |
TumbleweedIntervalMin |
10 |
Min seconds between waves. |
TumbleweedIntervalMax |
30 |
Max seconds. |
TumbleweedsPerPlayerMin |
2 |
Min tumbleweeds rained per player. |
TumbleweedsPerPlayerMax |
5 |
Max per player. |
TumbleweedLifetime |
15 |
Seconds before each tumbleweed is removed. |
TumbleweedDropHeight |
15 |
Meters above each player to spawn from. |
[Dynamite]
| Key | Default | Description |
|---|---|---|
EnableRandomDynamite |
true |
Toggle. |
DynamiteIntervalMin |
15 |
Min seconds between drops. |
DynamiteIntervalMax |
30 |
Max seconds. |
DynamiteCountPerWave |
1 |
Sticks per wave. |
DynamiteOffsetMin |
20 |
Min meters from chosen player. Below ~5 = nuke them. |
DynamiteOffsetMax |
100 |
Max meters. |
DynamiteLifetime |
30 |
Hard cleanup if the fuse fizzles. |
LightDynamiteOnSpawn |
true |
If false, drops as an unlit stick the player can pick up. |
[MarkerSpawn]
| Key | Default | Description |
|---|---|---|
EnableMarkerSpawn |
true |
Toggle. |
MarkerSpawnLifetime |
0 |
Seconds before the spawned pickaxe is removed. 0 = persist forever. |
[Eruption]
| Key | Default | Description |
|---|---|---|
EnableRandomEruptions |
true |
Toggle. Silently skipped on biomes without an EruptionSpawner. |
EruptionIntervalMin |
15 |
Min seconds between eruptions. |
EruptionIntervalMax |
30 |
Max seconds. |
EruptionOffsetMin |
0 |
Min meters from chosen player (0 = directly under their feet). |
EruptionOffsetMax |
5 |
Max meters. |
[ChestTraps]
| Key | Default | Description |
|---|---|---|
EnableScoutmasterTrap |
true |
Toggle for the "open chest → Scoutmaster teleports in" trap. |
ScoutmasterTrapChance |
5 |
Percent chance per chest opened. Keep it low — the Scoutmaster is brutal. |
ScoutmasterChaseTime |
60 |
Seconds the Scoutmaster is forced to hunt the opener. |
EnableZombieTrap |
true |
Toggle for the "open chest → mushroom zombies appear" trap. |
ZombieTrapChance |
10 |
Percent chance per chest opened. |
ZombieCountMin |
1 |
Min zombies per trigger. |
ZombieCountMax |
2 |
Max zombies per trigger. |
ZombieLifetime |
60 |
Seconds before each spawned zombie is removed. |
Tuning recipes
- Chill mode: bump every
IntervalMin/IntervalMaxto 60–180s, setLootMultiplier = 1, keep traps at default. - Party chaos: leave defaults (10–30s intervals).
- Pure loot mode: set every
EnableXxx(exceptEnableItemRandomizationandEnableLootScaling) tofalse. - All-traps, no events: disable Tornado/BananaPeel/Tumbleweed/Dynamite/Eruption, leave ChestTraps + Randomizer + LootScaling on.
Switching languages
Each config description is written on two ## lines: English on the first, Chinese on the second. No language toggle needed — read whichever you understand.
Compatibility
- Targets BepInExPack PEAK 5.4.2403.
- Should coexist with most cosmetic / QoL mods.
- Likely conflicts with mods that also patch
Spawner.SpawnItems(e.g.ItemMultiplier) — Harmony will let one of them win on each call. DisableLootScalingif you wantItemMultiplierto be authoritative. - Coexists fine with
PeakRandomizedChaosif you turn off the overlapping events on either side.
Build from source
Requires:
- .NET SDK 8 or newer (
brew install dotneton macOS,winget install Microsoft.DotNet.SDK.8on Windows). - A local PEAK install — the build pulls game DLLs from
<PeakGameRootDir>/PEAK_Data/Managed/. If your install isn't at the default Steam path, you can either copy theManaged/folder into the project root (auto-detected) or set<PeakGameRootDir>inConfig.Build.user.props.
dotnet restore
dotnet build -c Release
DLL ends up at artifacts/bin/HappyPeak/release/HappyPeak.dll.
To produce a Thunderstore package:
dotnet tool restore
dotnet build -c Release -target:PackTS
Credits
Implementation patterns adapted from:
PeakRandomizedChaosby DoggyDentures — Tornado, BananaPeel, Eruption event templates.ItemMultiplierby IceMods —Spawner.SpawnItemspatching shape.HazardChaosby Bananegame —Dynamite.LightFlareinsight.TrappedLuggageby tony4twenty — chest trap pattern (Scoutmaster + Zombie spawning, RPC names).RayMarkerModby NanJu —PointPingpolling for the marker spawn event.PeakStrandingby lnkr — verified0_Items/ClimbingSpikeHammeredprefab name for embedded pitons.BetterPreplacedPitonsby Gabriel — confirmedShittyPitonis PEAK's internal name for the wooden Mesa pickaxe.ItemBrowserby cherrycove — project structure / build setup template.
CHANGELOG
Changelog
[Unreleased]
- Default tuning pass for the public release. Events fire much less often than the previous test-mode defaults, loot is tripled instead of doubled, and small counts trimmed for balance.
LootMultiplier: 2 → 3 (triple loot)- Tornado interval: 10–30s → 90–120s; lifetime 60s → 30s
- BananaPeel interval: 10–30s → 60–90s; min per player 2 → 1
- Tumbleweed interval: 10–30s → 60–90s; per-player range 2–5 → 1–3
- Dynamite interval: 15–30s → 60–90s
- Eruption interval: 15–30s → 60–90s
- Scoutmaster chase time: 60s → 30s
- Fixed
EnableRandomDynamitedescription that still said "lit on spawn by default" — it's actuallyfalse(unlit) since 0.12.0. - README config tables + tuning recipes updated to reflect the new defaults.
[0.12.0]
Big quality-of-life release. Major redesigns to MarkerSpawn, Dynamite, BananaPeel; new Tumbleweed, ChestTraps, and SafeZones sections; lots of bug fixes.
MarkerSpawn (middle-click pickaxe drop)
- Now drops a real Mesa pickaxe (鹤嘴锄) instead of a piton. Photon prefab name (
0_Items/PickAxeHammered_Shitty) verified againstWesmania/RandomEventsPingGrabber. - Reads
PointPing.hitNormaldirectly for accurate surface attachment on walls / overhangs / slopes. Old approach raycast in 5 world directions and often picked up the floor beneath a wall. - Caught instantly via a Harmony Postfix on
PointPing.Start(no more 200 ms polling that missed rapid pings). - Spawned pickaxes don't crack/break. Mesa's preplaced pickaxes still behave normally — we tag our spawns via
InstantiationDatasoPickaxePermanencePatchonly affects ours. - Up to 2 unclaimed pickaxes per player (hardcoded). New ping past the cap removes the one farthest from the player so the freshly-spawned and held ones are always preserved.
- Auto-cleanup at 60s hardcoded — no more
MarkerSpawnLifetimeconfig. - Spawn position offset 0.3 m out from the surface along the normal so the model doesn't z-fight inside the wall.
- Used
Quaternion.LookRotation(-normal, Vector3.up)(matching the game's ownHammerClimbingSpike) so the spike pokes properly into the wall.
Dynamite (face-drop)
- Redesigned from "drop near random player on the ground" → "drop right in front of the player's face from head height."
- Default
LightDynamiteOnSpawn = false— drops an unlit stick the player can pick up and use, instead of bombing them. - New configs:
DynamiteForwardDistance(default 1 m in front of head),DynamiteDropHeight(default 0 m above head),DynamiteSidewaysJitter(default ±0.5 m). - Old
DynamiteOffsetMin/Maxrepurposed as horizontal scatter — defaults changed from 20/100 → 0/5. Item.SetState(ItemState.Ground)called on spawn so the rigidbody actually falls under gravity (PEAK items default to kinematic until the game's own drop logic activates them).- Respects campfire safe zone.
Tumbleweed (new section)
- Tumbleweeds rain from above each player (same pattern as banana rain) using PEAK's native
TumbleWeedprefab. - Default 15 s lifetime per tumbleweed.
- Respects campfire safe zone.
BananaPeel (rain)
- Peels spawn high above each player and fall via gravity instead of materializing at foot level.
- Each peel is independent (random rotation, no more cumulative trail offset).
- Respects campfire safe zone.
SafeZones (new section)
CampfireSafeRadius(default 30 m) — bubble around every campfire (biome rest + player-lit) where Tornado / Eruption / BananaPeel / Tumbleweed / Dynamite events skip the player.EnableCampfireInvincibility(default on) — patchesCharacterAfflictions.AddStatusso any positive status (injury, cold, hot, hunger, poison, …) is blocked while a player stands inside the safe radius. Healing still works.
ChestTraps (new section)
- Each chest opening rolls per-trap chances:
- Scoutmaster trap (default 5% chance) — teleports the existing Scoutmaster to the chest and forces him to hunt the opener for
ScoutmasterChaseTimeseconds. Uses the networkedRPCA_SetCurrentTargetRPC so the AI on every client receives the assignment. - Mushroom Zombie trap (default 10%) — spawns 1–2 zombies at the chest, sets their wake-up time to 0, locks them onto the opener.
- Scoutmaster trap (default 5% chance) — teleports the existing Scoutmaster to the chest and forces him to hunt the opener for
Other events
- Tornado: Kiln detection now compares against the
Segment.TheKilnenum (was a magic int>= 4that sometimes leaked tornadoes to the summit). - Eruption: respects campfire safe zone.
- All events gated on
Plugin.IsInGameRun()— nothing fires in the airport / lobby.
Bug fixes
- Bushes no longer get randomized items. Removed
LootTablePatch(which patchedLootData.GetRandomItem(s), hit by every spawner not just chests). Randomization is now handled inSpawnerPatchalong with the multiplier; that patch filters byChestSpawnerTypeNames(Luggage, RespawnChest) so non-chest spawners pass through to vanilla logic. - Marker pickaxe no longer destroys items the player is holding. Eviction checks
Item.holderCharacterAND walks the GameObject's parent chain to detect "in a Character's hand/inventory" — both signals are checked; either one passing skips destroy. As of 0.12.0 the dominant safeguard is the "evict farthest from pinger" rule (anything held is 0–1 m away vs walls being further). - Bombs no longer hover in mid-air. Items spawned via
PhotonNetwork.InstantiateItemRoomdefault to kinematic; we now callItem.SetState(ItemState.Ground)to enable gravity. - All networked spawns now use
PhotonNetwork.Destroyvia the sharedPlugin.DelayedNetworkDestroyhelper instead ofObject.Destroy, so despawns replicate to every client (no more ghost objects on clients). - Marker pitons no longer bury themselves inside walls. Switched the rotation calc from
Quaternion.FromToRotation(Vector3.up, normal)toQuaternion.LookRotation(-normal, Vector3.up)to match the game's own placement.
Configuration
- New configs across sections (see README's full reference):
DynamiteForwardDistance,DynamiteDropHeight,DynamiteSidewaysJitter,TumbleweedIntervalMin/Max/sPerPlayerMin/Max/Lifetime/DropHeight,BananaPeelDropHeight,CampfireSafeRadius,EnableCampfireInvincibility,EnableScoutmasterTrap,ScoutmasterTrapChance,ScoutmasterChaseTime,EnableZombieTrap,ZombieTrapChance,ZombieCountMin/Max,ZombieLifetime. - Removed configs:
MarkerSpawnItemName,MarkerSpawnLifetime,MarkerSpawnMaxActive,DynamiteOffsetMin/Max(the old "distance from player" pair). - All descriptions are bilingual (English line + Chinese line) so the cfg file is readable in either language.
LootMultipliernow rounded to nearest integer at read time (no fractional item counts).
Docs
- README rewritten for the public Thunderstore page.
- Recommends installing PEAKModding/ModConfig for in-game live config editing.
- Adds "Upgrading from an older version" notice — delete
HappyPeak.cfgwhen updating, since BepInEx doesn't backfill new entries into an existing cfg. - "Recent changes" section.
- Renamed mod's tagline + general polish.
[0.11.5]
- Initial public Thunderstore release.
- Chest randomization with custom blacklist + loot multiplier.
- Tornado, BananaPeel (trail), Dynamite (lit), MarkerSpawn (piton), Eruption events.
- Bilingual config descriptions.