Valheim
You are viewing a potentially older version of this package. View Latest Version
Install with App

Details

Date Uploaded
2 weeks ago
Downloads
434
Size
36KB
ADDatHost Valheim hosting
30% off

BeenThere

BepInEx 5 plugin for the Valheim server and every client on it (#308). Resources drop more in biomes you have been through: a player who has killed a tier's boss gets the tier rate on that tier's items, a player who names a catch-up tier gets the catch-up rate on every tier up to it until they kill its boss, everyone else gets vanilla. Both rates default to 3x. Plugin GUID syxe.BeenThere, assembly BeenThere.dll, version 0.1.0.

Progress is per character, not per world: the group killing the Queen does nothing for a player who was not there. The server decides everything and tells the clients; a client's own cfg only matters in single player.

Tiers

Eight tiers, first to last biome. Each names the boss prefab whose death completes it, the vanilla world key, and the items it governs (verified against the 1.0 client in docs/research/valheim-loot-progression-prefabs.md).

Tier Boss Items
Meadows Eikthyr Wood, FineWood
BlackForest gd_king RoundLog, Stone, CopperOre, TinOre
Swamp Bonemass ElderBark, IronScrap
Mountain Dragon SilverOre
Plains GoblinKing BlackMetalScrap (creature drop; CreatureDrops, default off)
Mistlands SeekerQueen BlackMarble, YggdrasilWood
Ashlands Fader Grausten, FlametalOreNew, Blackwood
DeepNorth FrozenKing_p3 Frostwood, GoldOre

The table is config ([Tiers]): Order lists the tier names and each name has a bosses|world key|items line, so a tier can be added or an item moved without a rebuild. An item may belong to one tier only.

What decides a drop

The player on the damage packet that broke the tree, log, rock, ore deposit or creature, looked up by character name in the server's state:

  1. killed this tier's boss: TierRate;
  2. else catch-up tier at or above this tier: CatchUpRate;
  3. else 1x.

Trees, logs, rocks, ore deposits and loot spawners go through DropTable.GetDropList; pickables (branches, loose stone, shoreline tin, snow branches, ash stone) through Pickable.Drop; creatures through CharacterDrop.GenerateDropList (off unless CreatureDrops). Vanilla's own resourcerate key still applies underneath; run the world at 1x.

Drops nobody hit (a tree felled by a falling tree, ore collapsing when its support goes, fire, timed debris) follow NoAttackerRule: WorldKey (default) gives the tier rate once the world's boss key is set and never the catch-up rate, ZoneOwner uses the record of the player whose client generated the drop, None gives 1x.

State

<BepInEx config dir>/BeenThere/state.txt on the server, so on TOWER /mnt/user/appdata/valheim/BepInEx/config/BeenThere/state.txt. One character per line; edit it while the server runs and it reloads within a second and pushes to every client.

world=equinoxv1
player=Syxe;kills=BlackForest,Meadows,Mountain,Plains,Swamp;catchup=Mistlands
player=Myrrdin;kills=BlackForest,Meadows,Mountain,Plains,Swamp;catchup=none

No catchup field means the server's DefaultTier applies; none means none even if a default is set. A character with no line is a new player: no kills, the default catch-up. A file for another world is parked as state.txt.other and a fresh one started. The directory is excluded from the modpack's config harvest (config_exclude in mods.yml).

Kill credit

When a boss dies, the client that owns it tells the server, and the server credits the tier to every connected character (KillCreditRadius > 0 restricts it to those within that many metres of the death). Any kill counts, not only the world's first; the Frozen King counts at phase three. Everyone sees a top-left message naming who was credited.

Console

On any client, F5:

  • beenthere or beenthere status: your record and the rate you get per tier.
  • beenthere catchup <tier|none>: ask the server for a catch-up tier. The server checks AllowedTiers and MaxTier and answers top-left.

Config

syxe.BeenThere.cfg: [Rates] TierRate, CatchUpRate; [CatchUp] DefaultTier, AllowedTiers, MaxTier; [Rules] NoAttackerRule, CreatureDrops, KillCreditRadius; [Tiers] as above. The server's values travel with the state, so clients need no matching cfg.

Build and ship

./build.sh runs the tests (pure logic, no game dlls) and writes dist/BeenThere.dll beside dist/manifest.json. The csproj references the game and BepInEx dlls from the local Steam install and the seat's r2modman profile. The server gets the dll from dist/ through the source: repo row in mods.yml, as ValheckCountdown does.

Players get mods through the r2modman profile code, which resolves them from Thunderstore, so the client half ships only as a published package:

  • Thunderstore team syxe is the namespace; the package is syxe-BeenThere in the valheim community. A team service account named syxe_fleet_publish owns the upload token (shown once in the team's Service accounts tab).
  • The token lives in the vault at fleet/thunderstore/publish, field token (docs/openbao.md). Nothing in the repo or on TOWER holds it.
  • ./publish.sh reads the token with bao kv get, builds the zip with tcli from thunderstore.toml (icon, README, generated manifest, the dll at the zip root) at the csproj <Version>, and uploads it. Bump the version in BeenThere.csproj, Plugin.cs and dist/manifest.json together; Thunderstore never accepts a version twice. tcli is a dotnet tool (dotnet tool install -g tcli).
  • After publishing, pin the mods.yml row to the same version; the digest posts the new profile code to the players.
Thunderstore development is made possible with ads. Please consider making an exception to your adblock.