You are viewing a potentially older version of this package. View all versions.
Ninex-HappyPeak-0.11.6 icon

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-5.4.2403 icon
BepInEx-BepInExPack_PEAK

BepInEx pack for PEAK. Preconfigured and ready to use.

Preferred version: 5.4.2403

README

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/IntervalMax to 60–180s, set LootMultiplier = 1, keep traps at default.
  • Party chaos: leave defaults (10–30s intervals).
  • Pure loot mode: set every EnableXxx (except EnableItemRandomization and EnableLootScaling) to false.
  • 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. Disable LootScaling if you want ItemMultiplier to be authoritative.
  • Coexists fine with PeakRandomizedChaos if you turn off the overlapping events on either side.

Build from source

Requires:

  • .NET SDK 8 or newer (brew install dotnet on macOS, winget install Microsoft.DotNet.SDK.8 on 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 the Managed/ folder into the project root (auto-detected) or set <PeakGameRootDir> in Config.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:

  • PeakRandomizedChaos by DoggyDentures — Tornado, BananaPeel, Eruption event templates.
  • ItemMultiplier by IceMods — Spawner.SpawnItems patching shape.
  • HazardChaos by Bananegame — Dynamite.LightFlare insight.
  • TrappedLuggage by tony4twenty — chest trap pattern (Scoutmaster + Zombie spawning, RPC names).
  • RayMarkerMod by NanJu — PointPing polling for the marker spawn event.
  • PeakStranding by lnkr — verified 0_Items/ClimbingSpikeHammered prefab name for embedded pitons.
  • BetterPreplacedPitons by Gabriel — confirmed ShittyPiton is PEAK's internal name for the wooden Mesa pickaxe.
  • ItemBrowser by 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 EnableRandomDynamite description that still said "lit on spawn by default" — it's actually false (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 against Wesmania/RandomEvents PingGrabber.
  • Reads PointPing.hitNormal directly 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 InstantiationData so PickaxePermanencePatch only 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 MarkerSpawnLifetime config.
  • 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 own HammerClimbingSpike) 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/Max repurposed 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 TumbleWeed prefab.
  • 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) — patches CharacterAfflictions.AddStatus so 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 ScoutmasterChaseTime seconds. Uses the networked RPCA_SetCurrentTarget RPC 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.

Other events

  • Tornado: Kiln detection now compares against the Segment.TheKiln enum (was a magic int >= 4 that 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 patched LootData.GetRandomItem(s), hit by every spawner not just chests). Randomization is now handled in SpawnerPatch along with the multiplier; that patch filters by ChestSpawnerTypeNames (Luggage, RespawnChest) so non-chest spawners pass through to vanilla logic.
  • Marker pickaxe no longer destroys items the player is holding. Eviction checks Item.holderCharacter AND 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.InstantiateItemRoom default to kinematic; we now call Item.SetState(ItemState.Ground) to enable gravity.
  • All networked spawns now use PhotonNetwork.Destroy via the shared Plugin.DelayedNetworkDestroy helper instead of Object.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) to Quaternion.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.
  • LootMultiplier now 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.cfg when 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.