Longhouse

Utangard

Biomes nobody in your group has earned starve you: food burns away, buffs are refused, and the land leaves you sapped.

  1. Features
  2. How the group gate works
  3. Biome table
  4. Installation
  5. Multiplayer
  6. Configuration
  7. Troubleshooting
  8. For mod authors
  9. Status
  10. Design notes
  11. Bug reports
  12. Discord
  13. Server
  14. Part of Longhouse

Utangard gates Valheim's biomes on boss progress. Nothing stops you walking into the Swamp on day two, but until your group has earned that biome your food burns away five times faster, you cannot eat or drink, your wounds do not close, and you leave with a stamina penalty that follows you out.

A biome counts as earned when every character on the group's roster was personally present when that boss died, not when the boss has died in the world. Kill Moder yourself and the Plains stays shut until the friend who was offline that night has killed it too. You can switch that off and gate on the world's own defeat keys instead.

Features

Everything here is a default and everything is configurable.

  • Food burns 5x faster in a gated biome. Nothing is deleted, it just runs out fast.
  • Eating and drinking are refused, with a message on screen. The item is never consumed or destroyed. Food is refused by Food.BlockEating; potions and meads are refused by Buffs.BlockNewBuffs, at the moment you drink them rather than after the effect is wasted.
  • Health regeneration is set to zero. Food is Valheim's only passive healing, so damage taken in a gated biome is damage you carry home.
  • Buffs already running burn 5x faster, and new ones are refused. Guardian powers are refused before the cooldown is spent, so yours is still there when you leave.
  • Rested and Resting count as buffs, so a fire and a roof buy you nothing inside. This is the harshest rule in the mod and it has its own switch (Buffs.BlockRested).
  • Harmful effects are never touched. Wet, Cold, Freezing, Burning, Poison and the rest run as normal; speeding those up would be a mercy rather than a penalty.
  • Leaving a gated biome leaves you Sapped: 75% less stamina regeneration. One second inside banks one second of it, up to 30 seconds, and it only spends itself once you are out. It stacks with food and Rested rather than replacing them.
  • The gate reaches 5 m past the edge of a gated biome, so stepping over the line to eat and stepping back does not work.
  • Two HUD icons, a message on entering and leaving that names who the biome is still waiting on, and a message when a biome opens, wherever you are standing.
  • A Utangard page in the compendium (the texts screen, beside Logs and Active Effects) listing every biome, whether it is open, who still owes it, and how long until the deadline opens it anyway.

Dungeons take the biome above them, so a Swamp crypt withers you exactly like the Swamp.

How the group gate works

  • Credit comes from being at the kill. When a boss dies, every player within 100 m of the body is credited. You do not need the killing blow and you do not need to be the host.
  • Only characters at the frontier count. A character counts towards a boss once it has the boss before it in the table. Somebody who has killed nothing does not hold the Swamp shut for a group that cleared Eikthyr and is waiting on The Elder: they count for Eikthyr and nothing beyond it. They still get every biome the group has already earned.
  • Joining late does not undo anything. Once the group clears a boss, that biome is open permanently. A friend arriving with a fresh character gates only what the group has not yet cleared.
  • A deadline opens the biome anyway. Once the first person clears a boss, the rest of the group has a set number of days before it opens regardless: one day for Eikthyr, one more for each boss after. This is what stops one person who stops logging in from holding a biome shut.
  • The roster forgets people who stop playing. A character stops counting for a boss after 14 real days without logging in, so a friend who visited for one evening or an alt made once cannot hold the gate forever. No admin command and no list to maintain.
  • Existing worlds keep their progress. A character is credited for a boss its own save file says it attended, as long as that boss has already died in this world, so installing on a long-running save does not re-lock everything.
  • An empty roster falls back to the world key. Before anyone has published progress, which is the first spawn after installing, the gate answers from the world's own defeat keys.
  • The gate is one answer about the group. If the roster has not all cleared Moder, the Plains withers you too, even if you landed the kill.

Biome table

The defaults are the vanilla progression offset by one: the boss of the previous biome opens the next.

Biome Opened by Global key
Meadows nothing ungated
Black Forest Eikthyr defeated_eikthyr
Swamp The Elder defeated_gdking
Mountain Bonemass defeated_bonemass
Plains Moder defeated_dragon
Mistlands Yagluth defeated_goblinking
Ashlands The Queen defeated_queen
Deep North Fader defeated_fader
Ocean nothing ungated

This is a config table, not a hardcoded progression. Blank a row and that biome is never gated. Point every row at one key and you have a single-boss gate. Point a row at a key some other mod sets and it gates on that instead.

The Black Forest row is the one to look at first: gating it on Eikthyr walls off the copper run most people do before touching him.

defeated_queen and defeated_fader are not in Valheim's GlobalKeys enum, they come from prefab data, so they can only be read off a running game. Both defaults are confirmed correct. A key name nothing sets fails closed and looks exactly like a working gate, so on spawn the mod walks the world's creature prefabs, collects every key any of them sets on death (vanilla's and any other mod's) and warns if a gate row names a key nothing here can set, listing the ones that exist.

Installation

  1. Install BepInExPack Valheim 5.4.2350. It is the only required dependency.
  2. Install Utangard with a mod manager, or drop Utangard.dll into BepInEx/plugins/.
  3. Launch once. The config file is written to BepInEx/config/ezomic.valheim.utangard.cfg.

Install it on every client and on the dedicated server. Each client enforces the gate on itself, so a player without the plugin is not gated by it.

Single DLL, no asset bundle, net462. Built against Valheim 1.0.7, BepInEx 5.4.23.5 and Harmony 2.9. Version 1.3.0 does not run on pre-1.0 Valheim, and the versions before it do not run on 1.0.

Multiplayer

Longhouse Core is an optional soft dependency. With it installed, the server rejects a client whose Utangard version or build id does not match, and the host's rule settings are applied on connected clients in memory without writing their config file. Without it Utangard is fully functional and single player needs nothing else, but a player who simply does not install the mod is not gated at all, so the gate becomes an agreement between players rather than a rule of the server. Utangard logs a warning once if it finds the group gate running in a multiplayer session with no Core.

Settings that decide a rule are synced from the host: all of Gate, including the biome keys and the border margin; the drains and blocks under Food and Buffs, including the healing multiplier; and both Sapped values. Settings that decide wording stay yours: the two blocked messages, all of Presentation, and all of Diagnostics.

Persistence:

  • Progress is stored in the world's global keys and saved with the world, so it survives players logging out.
  • Credit is per world, not per character. A character that cleared a solo world does not arrive on your server pre-credited: imported credit is only honoured for a boss this world has already seen die, so it can never open a biome on its own.
  • Your character file is read, never written.
  • Food timers and status effects belong to the owning client. Nothing here reaches into another player's character.

Configuration

BepInEx/config/ezomic.valheim.utangard.cfg. Every entry has a comment in the file. BepInEx writes the file on first run and the saved value beats any new default in code, so if a change appears to do nothing, check the cfg first.

Gate

Setting Default What it does
Enabled true Master switch. Off leaves the game untouched.
GateOnGroup true Gate on whether every character on the roster has done the boss. Off gates on the world's own key, so one kill opens the biome for everybody.
GateNeverRegresses true Once the group clears a boss, that biome stays open forever. Off makes the gate strictly weakest-link at all times.
RequirePreviousBoss true A character counts towards a boss only once it has the boss before it in the table. Off, every character on the roster counts for every gate.
RosterDays 14 Real days a character keeps counting after it was last seen.
RosterDaysPerBoss (empty) Per-boss overrides, as comma-separated key:days pairs, e.g. defeated_eikthyr:7, defeated_fader:60.
BackfillFromCharacter true Credit a character for a boss its own save file says it attended, for a boss this world has already seen die. The migration path for existing worlds.
CatchUpDays 0 Fallback deadline in days for any boss not named below. 0 means none.
CatchUpDaysPerBoss defeated_eikthyr:1, defeated_gdking:2, defeated_bonemass:3, defeated_dragon:4, defeated_goblinking:5, defeated_queen:6, defeated_fader:7 Days the group has to catch up once the first player clears a boss. The clock starts at the first credit recorded in this world and is never moved.
CreditRadius 100 Metres from a dying boss to be credited.
BorderMargin 5 Metres the gate reaches past the edge of a gated biome. 0 puts it exactly on the border.
ExcludePlayerIds (empty) Comma-separated character IDs that never count towards the gate. IDs, not names; the roster dump on spawn prints both.
Key_MeadowsKey_Ocean see the table above The global key that opens each biome. Blank means never gated.

Food

Setting Default What it does
FoodDrainMultiplier 5 How much faster food burns. 1 disables the drain and leaves only the refusal, which is a much gentler mod.
BlockEating true Refuse to eat food in a gated biome.
EatBlockedMessage The land will not feed you here Shown centre-screen when a bite is refused.
HealthRegenMultiplier 0 Health regeneration in a gated biome, as a fraction of normal. 1 leaves healing alone.

Buffs

Setting Default What it does
BuffDrainMultiplier 5 How much faster an already-running buff burns.
BlockNewBuffs true Refuse to apply any new buff, which also covers potions and meads at the point of drinking, and guardian powers.
BlockRested true Treat Rested and Resting as buffs. Off, a well-built camp becomes a real answer to the biome.
AlsoBlock (empty) Extra status effect names to treat as buffs, comma-separated. The mod finds potions and meads by walking ObjectDB for anything an item applies when consumed, and guardian powers by their GP_ prefix, so this is for the odd one out.
NeverBlock Puke Names to leave alone even if the rules caught them. Wins over AlsoBlock.
BuffBlockedMessage The land turns your power aside Shown when a potion or a guardian power is refused. Effects that arrive without the player asking, such as equipment or weather, are refused silently.

Sapped

Setting Default What it does
StaminaRegenMultiplier 0.25 Stamina regeneration while Sapped, as a fraction of normal.
MaxSeconds 30 Ceiling on how much Sapped you can bank, and so how long you must stand in the biome to reach the full penalty.

Presentation

Setting Default What it does
ShowStatusEffects true Show the two effects on the HUD. The rules still apply when this is off.
MarkIconFrom Poison Vanilla status effect whose icon the in-biome marker borrows.
SappedIconFrom Encumbered Vanilla status effect whose icon Sapped borrows.
EnterMessage Something here refuses you Shown once on entering. Blank to say nothing.
LeaveMessage The land loosens its grip Shown once on leaving. Blank to say nothing.
NameTheBlockers true Name the characters the biome is still waiting on, and how long is left on the deadline.
BlockedByPrefix Still owed by: Prefix for that list.
AnnounceOpenings true Say so, wherever you are, when a biome opens. Covers openings nobody killed anything for, such as a deadline expiring.
OpenedMessage {biome} opens to you That message. {biome} becomes the biome's name, or both names when one boss opens two.
ShowCompendiumPage true Add the Utangard page to the compendium's text list.
CompendiumTopic Utangard What that page is called in the list.

Diagnostics

Setting Default What it does
Verbose false Log every gate transition and blocked effect as it happens.
LogGlobalKeys true Log the world's keys, the roster and the whole gate table on spawn. Worth leaving on: it is how you catch a wrong key name.
LogBlockedEffects false Log the full list of status effects the mod decided are buffs, and the ones it left alone. The list to consult before editing AlsoBlock.
LogDefeatKeys false Log every key a creature in this world sets on death, and what sets it.

Troubleshooting

A biome will not open. Open the compendium page, or read the spawn dump in BepInEx\LogOutput.log. Both name the roster, who still owes each boss, and how long is left on the catch-up deadline. The usual cause is a character on the roster that has not been at that kill; ExcludePlayerIds or RosterDays are the way out if that character is not coming back.

A biome is shut and nobody is named. The log warns when a gate row names a key no creature in this world sets, and lists the keys that do exist. That is either a typo in the table or a key that comes from somewhere else, and it fails closed either way.

A config change did nothing. BepInEx saves the config on first run and the saved value wins. Edit the cfg, not the default.

The log says Utangard is running DEGRADED. A game update has moved one of the methods the mod patches. The line names which feature that cost; everything else is still in force.

The log says Utangard is NOT withering anybody. Neither of the two ways of recording a boss kill survived patching, so a biome that is shut could never open again. The mod stops enforcing anything until it is updated. Setting Gate.GateOnGroup = false gates on the world's own keys instead, which needs none of the mod's patches to open.

Upgrading from Wither. The mod was called Wither before 1.1.0. Keys written under the old name are still read, and are rewritten under the new one as people play, so no progress is lost.

For mod authors

Utangard.UtangardApi.GroupHasKey("defeated_bonemass") answers whether the group has earned a boss, which is not the same question as the world's raw defeated_ key. Take a soft dependency on ezomic.valheim.utangard. Yoke uses it so that stack sizes follow the group's progress rather than a kill nobody else was present for.

Status

Played on a local world and on a dedicated server: refused meals and potions keep their items, both HUD icons render, food and buff timers burn at 5x, Sapped accumulates and follows you out, a guardian power is refused without burning its cooldown, the border margin refuses a player standing three metres outside a gated biome, healing is blocked, gates open and close at borders in both directions, credit is granted at the kill and survives a world reload, a two-character roster names both debtors, the catch-up deadline opens a biome, the compendium page names each boss, the biome-opened announcement fires on the transition, and the defeat-key check verifies all nine rows against the world's own creature prefabs. Running standalone with no Core has been confirmed in game.

One thing is untested: attendee credit with more than one player at a boss kill. Solo you own the boss and credit yourself either way. The loop is identical for one player or five; what is unproven is whether other players' objects are instantiated on the owning client at fight range.

Design notes

The long-form reasoning, and the technical notes on how Valheim records boss attendance, are in DESIGN.md.

Bug reports

The Discord is the fastest route, and the right one if you are not sure whether what you are seeing is a bug. Issues on the repo work too and suit anything long.

Attach BepInEx\LogOutput.log, say whether you were on a server or in single player, and if the gate is doing something you did not expect, turn on Diagnostics.LogGlobalKeys and include the spawn dump: it carries the world's keys, the roster and the verdict on every biome. AppData\LocalLow\IronGate\Valheim\Player.log is worth adding when a vanilla mechanic broke, since exceptions thrown mid-frame land there rather than in the BepInEx log.

Discord

discord.gg/hJzAVaZ5wb is used for mod information, updates, support, bug reports and compatibility questions.

Server

There is also a small EU server running the pack if you want somewhere to play: hard combat difficulty, resources at 1x, everything else vanilla, no application and no activity requirements. Connection details are in the Discord.

Part of Longhouse

Utangard is part of Longhouse, the Ezomic modpack, which pins exact versions of its member mods. You do not need the pack to use Utangard, and it behaves the same on its own.

MIT licensed. By Robbin Thijssen (Thijssen Software).

Changelog

1.3.1 in Longhouse

Changed

  • Rewritten README. Same mod, clearer documentation: what it does and how to install it come first, then configuration, multiplayer behaviour, compatibility and troubleshooting. Every config table was checked against the plugin's own Config.Bind calls, so the settings, sections and defaults listed are the ones actually bound. No code changed in this release.

    discuss
1.3.0

Rebuilt for Valheim 1.0. This version does not run on pre-1.0 Valheim, and the previous one does not run on 1.0.

Fixed

  • The mod works again. Valheim 1.0 added a trailing parameter to SEMan.AddStatusEffect, so the patch no longer named a method - and an unresolved target throws out of PatchAll, which took all twelve patches in the class with it. Utangard did nothing at all while still registering on Core's gate and still refusing mismatched clients on behalf of a mod that was not running. It was nearly invisible: the log carried one warning and no error, because the exception went to Player.log rather than BepInEx's own log. The tell was the absence of the ready. line.

    discuss
1.2.1

A gate could latch open off a half-loaded world. It did, on the live server: the Swamp opened permanently while seven of the nine characters on the roster had never met the Elder.

The bug

ZoneSystem.RPC_GlobalKeys clears every global key and re-adds them one at a time, and it runs on every client every time anybody sets any key, because SetGlobalKey ends in SendGlobalKeys(Everybody). For the length of that loop the dictionary this mod reads its roster and its credits out of is incomplete.

Vanilla never notices - the refill is synchronous, no frame boundary falls inside it. A Harmony postfix on GlobalKeyAdd does notice, and Yoke has one, hooked there deliberately so it catches the bulk list a server sends on connect. So every key in that list made Yoke ask this mod whether the group had cleared a boss, once per key, while the answer was built from whatever fraction had arrived.

With a partial roster the counted members can be exactly the ones who hold the key - the two who had just killed the Elder, whose credits were already in - and LatchIfGroupCleared then finds a group that has cleared it. The !anyCounted guard only ever caught a completely empty roster; a partial one walked straight through it. The open key is permanent by design, RPC_SetGlobalKey has no permission check, and so one client's half-loaded view became everyone's, for good.

The two-second roster cache is what let one frame of that outlive itself.

Fixed

  • The latch refuses to run while the world's keys are settling. A prefix and postfix on RPC_GlobalKeys hold a flag across the rebuild; while it is up, nothing latches. This is the irreversible half of the mod, so it is the half that must decline to answer early rather than answer wrongly.

    discuss
  • The roster is never cached from a half-filled key list, and is invalidated on every key that arrives rather than only on a publish. A cache can no longer outlive the world state it was built from.

    discuss
1.2.0

The border is a band, and wounds do not close

Two rules, both configurable, both on by default.

Gate.BorderMargin, 5 metres. The gate now reaches five metres past the edge of a gated biome. On a line, every penalty in the mod is escapable by taking three steps out of the Swamp, eating, and stepping back in - the drain, the refusal and the grudge all end at a boundary you can see and stand behind. That makes it a rule about where you may chew rather than where you may live, and it is worst exactly where it matters most, at the edge of a fight you are already in. A band has to be genuinely cleared. Set it to 0 to put the gate back on the border.

It samples eight compass points at the margin, so it costs eight biome lookups. Those are cached against the player's position and re-taken every quarter of a metre walked; what is cached is which biomes are within reach and never the verdict on them, so a biome that opens while somebody stands at its border opens for them where they stand.

Food.HealthRegenMultiplier, 0. Health regeneration in a gated biome, as a fraction of normal. It sits in the Food section because food is the only passive healing Valheim has - Player.UpdateFood adds up every meal's m_foodRegen every ten seconds and heals you by it - so this multiplies exactly the healing the food you are not allowed to eat would have given. The land that will not feed you does not mend you either.

It rides StatusEffect.ModifyHealthRegen on the marker effect rather than a patch, because that is the seam vanilla already offers and it composes with every other multiplier instead of overriding them. Which meant the marker had to stop being skipped when ShowStatusEffects was off: it was pure signage then and is carrying a rule now, and turning off the HUD would otherwise have quietly turned off the healing block.

Both are host-synced with Core, like every other setting that decides a rule.

Also: the deadline in the entry message is now read from the biome that is actually withering you rather than the one underfoot. With a margin those part company, and a countdown for the wrong boss is worse than no countdown.

You can see the gate, and you are told when it opens

A Utangard page in the compendium, beside Logs and Active Effects: every biome, whether it is open, who still owes it, and how long until the deadline opens it anyway. Until now that report existed only as log lines on spawn, which is the wrong medium for the person who most needs it - somebody mid-raid wondering why their food vanished is not going to read LogOutput.log.

It is a postfix on TextsDialog.UpdateTextsList, so it is vanilla's list with vanilla's skin, font, scrolling, gamepad handling and close behaviour, none of which this mod then owns. The alternative was an IMGUI window: four patches (both TakeInput overloads, PlayerController.InInventoryEtc, GameCamera.UpdateMouseCapture) and a keybind, to arrive at something that looks like a different game.

The log and the page are one function now. They were about to be two copies of "is this biome open, and if not who owes it", and the interesting part is not the wording but the three-way distinction between open-because-latched, open-because-everyone-has-it and shut-with-an-empty- roster. Two copies of that stay right for about a week.

Presentation.AnnounceOpenings. A message when a biome opens, wherever you are. The mod's whole argument is that fetching the friend who is behind is worth doing, and the payoff for doing it used to land silently - you found out by walking to the Mountain and not being refused. It watches the answer rather than the kill, so a catch-up deadline expiring and a roster member ageing out announce themselves too, and it needs no network code at all: global keys are already broadcast to every client.

The gate keys are checked against the game, not assumed

defeated_queen and defeated_fader are set from prefab data rather than named in the GlobalKeys enum, so they were the two shipped defaults that could not be verified from the game's code - and a wrong key fails closed, which looks exactly like a working gate.

Character.m_defeatSetGlobalKey is a public string on every creature prefab and OnDeath hands it straight to SetGlobalKey, so walking ZNetScene's prefab list gives the complete list of keys any death in this world can set, another mod's creatures included. On spawn Utangard now warns about any gate row naming a key nothing here sets, and prints the ones that exist - which is the answer to the question the warning provokes. Diagnostics.LogDefeatKeys prints the whole map.

It checks and never corrects. A row pointed at another mod's key, or at a key a location sets, is a supported thing to want.

It has now been run, and both names are right. The scan on a live world reported defeated_eikthyr, defeated_gdking, defeated_bonemass, defeated_dragon, defeated_goblinking, defeated_queen, defeated_fader, and also defeated_hive and defeated_serpent for the two creatures that set a key without gating anything here.

Played

All of it, on a live world: the border margin refusing a player standing three metres outside a gated biome, the healing block, the compendium page, the announcement firing on the transition, and the healing block again with ShowStatusEffects = false - where the gate still refused food and held healing at zero with both icons hidden, and regeneration returned on leaving. A presentation toggle does not switch off a rule.

1.1.0

An API for other mods to ask what the group has earned

UtangardApi.GroupHasKey(bossKey) answers the one question this mod knows and nothing else does: whether the group has earned a boss, rather than whether the world has merely seen it die. Those two answers part company the moment somebody is offline for a kill.

It exists because Hoard scales stack sizes by world progression. Reading the raw defeated_ key there would hand out Plains-era stacks for a biome still fenced off here, which is two mods disagreeing out loud about the same word in a way that reads as a bug in whichever one the player happens to be looking at.

A facade rather than making Progression public: the roster, the latch and the deadline are nobody else's business. Read-only by construction, so a consumer cannot open a biome by asking about it.

The README is half the length

The source-code archaeology moved to DESIGN.md - why Character.OnDeath credits one player rather than all of them, what the global keys are called and why, and the handful of things that were nearly bugs. None of it is needed to play, and it was sitting between a new reader and the part that says what the mod does.

Nothing about the gameplay changed in this release.

1.0.0

First release. Played, not merely built.

Core is optional

Utangard installs and runs on its own. Core is a soft dependency: present, it is used exactly as before; absent, the mod is fully functional without it.

Nothing about the gameplay needed Core. The drain, the refusal and Sapped are local patches, and the group gate travels over vanilla global keys, which every client replicates already. Singleplayer is unaffected in every respect.

What Core buys is enforcement, and that is the whole of what standalone gives up. Core is what refuses a client that does not have Utangard; without it, a player who skips the mod is not gated at all and walks into the Ashlands on day one while everyone else waits on the roster. The gate becomes an agreement between players rather than a rule of the server.

That is a real trade and it belongs to whoever runs the server, so the mod logs it rather than refusing to run, and it says so loudly, once, on spawn, when it finds the group gate enabled in a multiplayer session with no Core. That combination is the one that looks like it is working and is not, and failing silently there is the worst of the options.

Mechanically: [BepInDependency] is SoftDependency, every Suite call sits behind a Chainloader.PluginInfos check inside a [MethodImpl(MethodImplOptions.NoInlining)] method, and the project reference to Core is compile-time only. The no-inlining is load-bearing rather than decorative. The JIT resolves the assemblies a method needs when it first compiles that method, so a Suite call sitting directly in Awake would drag Ezomic.Core in before the check could prevent it, and the missing-assembly exception would land during plugin load.

Core is not listed in manifest.json, so installing Utangard does not install Core with it. Confirmed in game: Utangard loads alone, logs that it is running standalone, and the whole gate works without Core present.

The group gate, finished

  • Credit is earned at the kill, by everyone present. The owning client credits every player within CreditRadius (100 m) of the corpse. It had to be done that way: Character.OnDeath looks like it runs on every client that had the boss loaded, since it pushes vanilla's key above an IsOwner early-return. But that guard is unreachable, because CheckDeath is its only caller and sits inside if (zDO.IsOwner()). Crediting "the local player" would have credited exactly one member of a group that killed a boss together, and the gate would then have jammed shut while looking like it worked.

    discuss
  • Credit is per world. A character that cleared a solo world no longer arrives pre-credited. BackfillFromCharacter still allows the migration case, and only for a boss this world has already seen die.

    discuss
  • Progress never regresses. Once the group clears a boss the biome latches open, so a newcomer gates only what has not been cleared rather than revoking what has.

    discuss
  • A catch-up deadline, defaulting to a ladder of one day for Eikthyr and one more per boss after. Without it a single person who stops logging in holds a biome shut for everyone until RosterDays finally drops them. A biome the deadline opens latches too.

    discuss
  • Per-boss roster windows via RosterDaysPerBoss, for when one boss deserves a shorter leash than another.

    discuss
  • The blocker line names other people, never you, and shows how long is left.

    discuss

Fixed

  • A refused meal or potion is no longer destroyed. Player.ConsumeItem removes the item regardless of what EatFood returns, so the refusal had to move to CanConsumeItem, the gate that path actually respects.

    discuss
  • Refusing a guardian power no longer burns its cooldown; StartGuardianPower sets the cooldown before applying the effect.

    discuss
  • Rested can no longer be topped up past the drain. SEMan refreshes a running effect through Internal_AddStatusEffect without ever reaching the public overload.

    discuss
  • Puke is no longer treated as a buff. An item applies it on consume, so the potion rule swept up a debuff, which would have made a gated biome the one place bad food cannot hurt you.

    discuss

Played, not merely built

On a local world and on a real dedicated server: refused meals and potions keep their items, both HUD icons render, food and buff timers burn at 5×, Sapped accumulates and follows you out and cripples stamina regeneration, a guardian power is refused without burning its cooldown, gates open and close at borders, credit is granted at the kill and survives a reload, the latch fires, a two-character roster names both debtors, and the catch-up deadline opens a biome for a group that had not all earned it. No exceptions in a long session.

Known limits

  • Attendee credit has never run with more than one player. Solo, you own the boss and credit yourself either way, and two characters taken in turns only credits whoever is logged in. The loop is the same for one player or five; what is unproven is whether other players' objects are instantiated on the owner's client at fight range.

    discuss
  • defeated_queen and defeated_fader are taken from prefab data rather than the game's GlobalKeys enum. A wrong key fails closed, which is indistinguishable from a working gate. LogGlobalKeys prints what your world actually has.

    discuss
0.2.0

Written and building. Never run in game.

The line this sits on

A biome you have not earned will not feed you. It never stops you walking in.

Valheim gates its biomes with damage, which is a soft gate: out-geared, out-run or out-healed, which is why the Plains stops being frightening ten minutes after it starts. The usual mod answer is a hard boss gate that refuses to let you across the border, which fixes the pacing by deleting the thing worth having: the walk into somewhere you should not be.

Utangard sits between them. You can go anywhere, immediately, and nothing stops you at the edge. The land just will not sustain you while you are there.

The three parts

  • The drain. Food and buffs burn down five times faster in an unearned biome. This sets the clock, and it is the part you feel while things are going well.

    discuss
  • The refusal. You cannot eat or drink anything at all while you are there. Without it the drain is simply beaten by a bigger pack, and the mod becomes an inventory tax rather than a time limit.

    discuss
  • Sapped. Seventy-five percent less stamina regeneration, one second per second spent in the biome up to thirty, and it keeps ticking after you leave. Without it the optimal play is to sprint in, grab and sprint out at no cost, and a penalty you can dodge by being quick is a penalty for slow players only.

    discuss

The gate is on the group, not the world

By default a biome opens when every member of the roster has personally killed the boss, not when the boss has died in this world. Kill Moder yourself and the Plains stays shut until the friend who was offline that night has killed it too.

This rides on Character.OnDeath pushing m_defeatSetGlobalKey into Player.m_addUniqueKeyQueue, which is how the game records a boss kill against a character rather than a world.

Known limits

  • Never played. None of the three parts has been felt in a session, and the numbers are therefore first guesses rather than tuned values.

    discuss
  • The per-character kill record is only refreshed when a player loads in, so a boss killed during the current session is not visible until then unless the kill itself is hooked.

    discuss

Every setting · 48

All of it lives in one file, written on first run with each description beside its default. The file is the source of truth; edit it there.

BepInEx/config/ezomic.valheim.utangard.cfg

server On a server, the host's value applies to everyone while they are connected; your own file is left alone and counts again when you leave. yours Keys and personal settings stay as you set them, on any server.

Buffs 6
SettingWhat it doesDefaultWhose
BuffDrainMultiplier How much faster an already-running buff burns down in a gated biome. Only applies to the effects this mod considers buffs - see the Buffs section below. Harmful effects are never touched, because speeding up Poison or Freezing would be a mercy, not a penalty. 5 server
BlockNewBuffs Refuse to apply any new buff in a gated biome. true server
BlockRested Treat Rested and Resting as buffs, so a fire and a roof buy you nothing inside a gated biome. This is the single harshest switch in the mod: it means a forward base in the Plains gives shelter and warmth but no regeneration. Turn it off and a well-built camp becomes a real answer. true server
AlsoBlock Extra status effect names to treat as buffs, comma-separated. The mod finds potions and meads by walking ObjectDB for anything an item applies when consumed, and guardian powers by their GP_ prefix, so this list is only for the odd one out. Turn on Diagnostics.LogBlockedEffects to see names. (empty) server
NeverBlock Status effect names to leave alone even if the rules above caught them, comma-separated. Wins over AlsoBlock. Puke is here because the first run in a real world found it: something applies it on consume, so the potion rule catches it, and it is a debuff. Blocking it would have handed the player an immunity to bad food in the one biome meant to be punishing them, and the drain would have made it wear off faster there than anywhere else. This is the exact failure the harmful-allowlist design was meant to avoid, arriving from the other direction - worth remembering if a future update adds another debuff that an item hands you. Puke server
BuffBlockedMessage Shown centre-screen when a potion or a guardian power is refused. Effects that arrive without the player asking - equipment, weather, another player's buff - are refused silently, because a message for each of those would be a wall of text nobody reads. The land turns your power aside server
Diagnostics 4
SettingWhat it doesDefaultWhose
Verbose Log every gate transition and every blocked effect as it happens. false server
LogGlobalKeys Log the world's global keys once when a world loads. This is how you check that the key names in the Gate table match what your world actually records - a typo there fails open and gates nothing, silently. true server
LogDefeatKeys Log every global key any creature in this world sets when it dies, and what sets it. This is where the real name of a boss key comes from - the Queen and Fader carry theirs in prefab data rather than in the game's GlobalKeys enum, so it can only be read off a running game. The mismatch warning is printed whether or not this is on; this is the full listing behind it. false server
LogBlockedEffects Log the full list of status effects the mod decided are buffs, once, when ObjectDB is built. The list to consult before editing AlsoBlock. false server
Food 4
SettingWhat it doesDefaultWhose
FoodDrainMultiplier How much faster food burns down in a gated biome. 5 turns a 1600-second meal into a 320-second one. 1 disables the drain and leaves only the refusal to eat, which is a much gentler mod - you keep what you brought. 5 server
BlockEating Refuse to eat anything at all in a gated biome. This is the 'force' half: the drain alone can be beaten by carrying more food, and the block is what makes the timer real. true server
EatBlockedMessage Shown centre-screen when a bite is refused. The land will not feed you here server
HealthRegenMultiplier Health regeneration in a gated biome, as a fraction of normal. 0 is 'wounds do not close here'. It belongs in this section because food is the only passive healing Valheim has - Player.UpdateFood adds up m_foodRegen every ten seconds and heals you by it - so this multiplies exactly the healing the food you are not allowed to eat would have given. Healing that comes from an effect you were carrying is drained by the Buffs section instead. 1 leaves healing alone, which makes a gated biome survivable in a way resting off a bad fight makes it liveable. 0 server
Gate 21
SettingWhat it doesDefaultWhose
Key_Meadows Ungated by default. This is where you start. Global key that must be set before this biome stops withering you. Blank means the biome is never gated. (empty) server
Key_BlackForest Eikthyr. Global key that must be set before this biome stops withering you. Blank means the biome is never gated. defeated_eikthyr server
Key_Swamp The Elder. 'gdking' really is the game's name for him. Global key that must be set before this biome stops withering you. Blank means the biome is never gated. defeated_gdking server
Key_Mountain Bonemass. Global key that must be set before this biome stops withering you. Blank means the biome is never gated. defeated_bonemass server
Key_Plains Moder. Global key that must be set before this biome stops withering you. Blank means the biome is never gated. defeated_dragon server
Key_Mistlands Yagluth. Global key that must be set before this biome stops withering you. Blank means the biome is never gated. defeated_goblinking server
Key_AshLands The Queen. Not in the GlobalKeys enum - verify against LogGlobalKeys. Global key that must be set before this biome stops withering you. Blank means the biome is never gated. defeated_queen server
Key_DeepNorth Fader. Not in the GlobalKeys enum - verify against LogGlobalKeys. Global key that must be set before this biome stops withering you. Blank means the biome is never gated. defeated_fader server
Key_Ocean Ungated by default. Gating the ocean gates every crossing to every biome, including the ones you are allowed into. Global key that must be set before this biome stops withering you. Blank means the biome is never gated. (empty) server
Enabled Master switch. Off leaves the game completely untouched - the patches stay installed but every one of them returns immediately. true server
GateOnGroup Gate on whether everyone in the group has done the boss, rather than on whether the boss is dead in this world. The difference is the whole point. A world key is set once, by whoever landed the kill, and credits everybody - including someone who joined afterwards and has never seen the fight. On, the biome stays shut until every character on the roster was personally present at that boss's death, so carrying a friend through means actually bringing them. The point is to keep a group together. Valheim groups come apart along progression: one person plays more, gets ahead, and the rest arrive to find the interesting content already cleared - so nobody wants to redo it and the person ahead has no reason to go back. This makes helping the people behind you the way you move forward yourself, rather than a favour. If your friend has not killed The Elder, the Swamp is shut for you too, so going back is the next thing on your own list. Off restores the original behaviour: one kill opens the biome for all. true server
GateNeverRegresses Once the whole group has cleared a boss, that biome stays open forever, even if someone new joins later who has not done it. Without this the gate runs backwards: a friend arriving with a fresh character decides nobody has done Eikthyr and shuts the Black Forest for the people who killed him - retroactively, and for as long as that friend keeps logging in. Progress the group paid for should not be revocable by somebody else's arrival. What a newcomer still gates is everything the group has NOT yet cleared, which is where the 'bring your friend' pressure belongs anyway. Off makes the gate strictly weakest-link at all times. true server
RosterDays How many days a character counts for after it was last seen. Real days, not in-game ones. This is the answer to the obvious problem with a group gate: an alt made once, or a friend who visited for one evening, would otherwise hold every biome shut forever. Leaving is automatic and needs no admin command - stop logging in and you stop counting. The cost is that someone on a long holiday silently drops out and the gate may open without them, so set this comfortably longer than your group's normal gap between sessions. 14 server
BackfillFromCharacter Credit a character for a boss its own file says it has attended, as long as that boss has already died in this world. This is the migration path and nothing else: nobody's past kills were recorded before this mod existed, so without it, installing on a long-running world gates every biome until every boss is killed again. It is also the one hole in the 'you had to be there' rule. The record it reads lives on the client and is not world-specific, so a player who was never at the fight is credited the moment somebody else kills that boss here. Requiring the world to have seen the boss die bounds that - imported credit cannot open a biome on its own - but it does not close it. Off makes the rule exact: credit comes only from kills this mod watched happen. Correct for a world that started with the mod installed, and punishing for one that did not. true server
RosterDaysPerBoss Per-boss overrides for RosterDays, as 'key:days' pairs separated by commas. For example: defeated_eikthyr:7, defeated_fader:60 A short window for an early boss says 'keep up or stop counting'; a long one for a late boss keeps somebody on holiday from being written out of a fight the group has been building towards for weeks. Anything not listed uses RosterDays. Written as one line rather than nine config entries because the interesting case is overriding one or two of them, not filling in a table. (empty) server
CatchUpDays Fallback deadline, in days, for any boss not named in CatchUpDaysPerBoss. 0 means no deadline for those. Without a deadline of some kind, one person who stops logging in holds a biome shut for everybody until RosterDays finally drops them, which can be weeks. 0 server
CatchUpDaysPerBoss Days the rest of the group has to catch up once the first player has done a boss, after which the biome opens whether they did or not. The clock starts the first time this mod records anyone as having that boss in this world, and is written once and never moved. The default is a ladder: one day for Eikthyr and one more for each boss after. Early bosses are short trips somebody can be brought along on the same evening, so a day is enough pressure; a late boss is a whole evening's expedition that has to be organised, and holding the group to one day there would just mean the deadline always wins and the gate never does. "defeated_eikthyr:1, defeated_gdking:2, defeated_bonemass:3, " + "defeated_dragon:4, defeated_goblinking:5, defeated_queen:6, defeated_fader:7" server
CreditRadius How close to a dying boss a character has to be to be credited for it, in metres. Deliberately generous. Only one machine sees a boss die - the client that owns it - so it credits everyone standing nearby on the group's behalf, and the two ways of getting that wrong are not symmetric. Too tight and somebody who fought the whole battle is not credited, which holds the gate shut for the entire group with no way to fix it short of killing the boss again. Too loose and a bystander is credited, which costs one person's sense of having earned it. Prefer too loose. 100 server
ExcludePlayerIds Character IDs that never count towards the group gate, comma-separated. The manual override for a character that has to keep playing but should not hold the gate. IDs rather than names, because global keys are lowercased and two characters can share a name. The roster dump on spawn prints both. (empty) server
RequirePreviousBoss A character only counts towards a boss's gate once it has the boss before it in this table. Without it, somebody who has killed nothing at all holds the Swamp shut for a group that has cleared Eikthyr and is waiting on The Elder - a person two steps behind the frontier deciding when the people at it may move. They still count for the boss they are actually next in line for, so the gate that holds a group together is the one nearest them, and biomes the group has already earned stay open regardless. Off restores 'every living character counts for every gate'. true server
BorderMargin How far the gate reaches past the edge of a gated biome, in metres. Without it the border is a line you can stand a step behind: walk out of the Swamp, eat, walk back, and the drain is a mild inconvenience rather than a reason to leave. With it the edge is a band you have to actually clear, and the biome you can see from is still the biome you are in. Costs eight biome lookups a step, cached, so it is not free but it is close. 0 turns it off and puts the gate exactly on the border. 5 server
Presentation 11
SettingWhat it doesDefaultWhose
ShowStatusEffects Show the two effects on the HUD. Off makes the mod invisible, which is atmospheric and also completely baffling to a new player. true server
MarkIconFrom Name of the vanilla status effect whose icon the in-biome marker borrows. Poison server
SappedIconFrom Name of the vanilla status effect whose icon Sapped borrows. Encumbered's weight reads as 'heavy and slow', which is what the effect does. Encumbered server
EnterMessage Shown once on entering a gated biome. Blank to say nothing. Something here refuses you server
LeaveMessage Shown once on leaving a gated biome. Blank to say nothing. The land loosens its grip server
NameTheBlockers Under a group gate, name the characters the biome is still waiting on. Worth leaving on: the honest question a player asks is 'why is this still shut when I killed it myself', and without an answer the only way to find one is to read a log file. Off if you would rather it stayed mysterious. true server
BlockedByPrefix Prefix for that list of names. Still owed by: server
AnnounceOpenings Say so, wherever you are, when a biome opens. Without it the only way to learn that the group has finally cleared Bonemass is to walk to the Mountain and not be refused - which lands the payoff for fetching your friend silently, and usually to the person who was not at the fight. true server
OpenedMessage Shown when a biome opens. {biome} is replaced with the biome's name in your own language, and with both names when one boss opens two. {biome} opens to you server
ShowCompendiumPage Add a Utangard page to the compendium's text list, beside Logs and Active Effects. It is the only place in the game that can answer 'which biomes are shut, who is still owed, and how long until it opens anyway' without walking there or reading a log file. true server
CompendiumTopic What that page is called in the list. Utangard server
Sapped 2
SettingWhat it doesDefaultWhose
StaminaRegenMultiplier Stamina regeneration while Sapped, as a fraction of normal. 0.25 is the 75% penalty. This is a multiplier applied alongside every other one the game has, so it stacks with food and with Rested rather than replacing them. 0.25 server
MaxSeconds Ceiling on how much Sapped you can accumulate. One second in a gated biome buys one second of it, so this is also 'how long you must stand in the biome before the penalty is at full length'. It keeps ticking down after you leave, which is the point - a dash in and out still costs you. 30 server

Discussion

Nothing said yet.

Sign in or make an account to join in.