Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Utangard
Biomes nobody in your group has earned starve you: food burns away, buffs are refused, and the land leaves you sapped.
| Date uploaded | 2 weeks ago |
| Version | 1.3.1 |
| Download link | Ezomic-Utangard-1.3.1.zip |
| Downloads | 219 |
| Dependency string | Ezomic-Utangard-1.3.1 |
This mod requires the following mods to function
denikson-BepInExPack_Valheim
BepInEx pack for Valheim. Preconfigured with the correct entry point for mods and preferred defaults for the community.
Preferred version: 5.4.2350README
Utangard
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 byBuffs.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
- Install BepInExPack Valheim 5.4.2350. It is the only required dependency.
- Install Utangard with a mod manager, or drop
Utangard.dllintoBepInEx/plugins/. - 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_Meadows … Key_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
Changelog
Notable changes to Utangard. Format follows Keep a Changelog, and the mod uses semantic versioning.
[1.4.0] - 2026-09-30
Added
- You can earn eating and healing back in a locked biome. Pidgey said it on Longhouse: a locked biome was a wall, not a challenge, and the inability to eat was the problem. Each character now has two bars in every locked biome. Fighting fills from kills of that biome's creatures, and at 50% you can eat there again. Discovery fills from the map you uncover there yourself, and once both bars are full your wounds heal at the normal rate. Meads, powers and Rested are still refused, food and buffs still burn faster and you still leave Sapped. The bars are yours, they only count in their own biome, and they never open it for the group.
- Fighting only counts kills Utangard saw happen. It keeps its own count in your character, one
for each world, so a kill in one world never counts in another, and a singleplayer world is
another world too. Everybody starts at zero with this version, so kills from before it do not
count. Helping with a kill counts. A tame or bred animal counts for nothing. So does a creature
spawned with devcommands or wiped out with
killall, and your own kill while you have devcommands on or are in god mode or ghost mode. A friend who helped somebody in god mode can still be credited when the god-mode player's machine did not have the creature. Each kind of creature is worth 1 to 5 points and the bar is full at 150. No single kind can put in more than half of it. - Discovery only counts fog you lifted yourself, not what a map table shares. It is full at 1 km² in every biome, and a piece of map counts once. The fog lifts in a wide circle around you, so walking a border or sailing a coast fills some of the biome on the other side as well, and nothing stops that filling the whole bar. At 1 km² it takes about ten kilometres of coastline to do it.
- Where two locked biomes meet, an unlock needs both bars. Within 5 m of the second biome its rules reach you, so stepping a metre into a biome you have fought enough in does not let you eat on the edge of one you have not.
- A new Foothold config section:
FootholdEnabled,FightingFullPoints,EatAtFightingPercent,DiscoveryFullKm2,MaxFromOneKindPercent, and aPoints_line per biome saying what each creature is worth there. Eating and the limit per kind are percents of the full bar, so raising the bar keeps them at half. All of it is synced from the host. - Utangard now writes to your character file, which it never did before: one entry per world holding its foothold kill counts.
- A refused meal now says how far your Fighting bar has got. The wording is
Presentation.EatProgressLine. utangard footholdin the console shows both bars for every biome, how many of each creature Utangard has counted for you, what each kind put in, where the cap stopped it, and what is unlocked.utangard creatureschecks every name on the points lines against the game.utangardtest kills <creature> <count>sets your count of one creature in this world, so a test can start a Fighting bar anywhere. It is a cheat command.utangard deaths <creature>says whether a creature dies through its animation, how many your machine has seen die this session and whether it had them, how often it ran the boss credit for one, and whose machine has the nearest live one. It was written for a two-player test of who gets the credit for a kill, and it is not a cheat.utangard deathson its own lists every creature that dies through its animation, andsince <notowner>after a creature adds whether your machine ran a death of one it did not own since that count.- A boss will not come to an altar in a biome the group has not earned. Before, one player
could carry an egg into the locked Mountains, kill Moder there, and start the Plains deadline
for everybody while the rest were still on Bonemass. A refused offering uses nothing up. Each
altar stands in the biome the boss before it opens, so it answers as soon as that biome opens,
by kills or by the deadline.
BlockBossSummonsturns it off. - The Queen's door stays sealed the same way while the Mistlands are locked, since she is not
summoned at an altar. The Sealbreaker is not used up when the door refuses, and a door that is
already open stays open.
BossDoorKeyslists which keys count. utangard biomes, a console command listing each biome's creatures, how many of each Utangard counted for you in this world, and how much of it you have explored. Only creatures a points line pays for are counted, so deer and the rest of the prey always show 0.
Changed
- The Utangard page in the compendium is now a panel. A row across the top has every biome,
green when your group has earned it and red when it has not. It opens on the first locked one,
and you can click any other, or use left and right on the d-pad. Under the row it says who that
biome is waiting on and when it opens anyway. For a locked biome you also see your Fighting and
Discovery bars, what each one unlocks, and the rules of the lock as your server has them set,
so on Longhouse it says food burns 3x faster and wounds heal at a fifth.
Presentation.ShowCompendiumPanelturns it back into the old text page, and the text page is also what you get if the panel fails to draw. - The tooltip on the in-biome icon lists only the rules that apply to you right now, so it says when you may eat or heal there.
Fixed
- The blocked messages and everything under Presentation and Diagnostics are yours on a server now, as the README always said. They were not. Core hands every client the host's whole config apart from keybinds, so the host's wording and its Verbose flag were applied on every client and put back if you changed them. The two boss messages under Gate count as wording too. This needs Core 1.1.0 or later.
- A boss kill is credited by one machine, the one that had the boss. In Valheim 1.0 a creature with a death animation dies on every machine showing it, and in 1.3.1 each of them could write the group's credit. Nobody got it twice, because a credit already written is not written again.
[1.3.1] - 2026-09-12
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.
[1.3.0] - 2026-09-09
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 ofPatchAll, 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 toPlayer.lograther than BepInEx's own log. The tell was the absence of theready.line.
[1.2.1] - 2026-08-25 (second half)
Everything below shipped in 1.2.1 alongside the latch fix above. It sat under Unreleased while the code was already in the release, which is the kind of drift that makes a changelog worth less than no changelog - the README carried it, so the package page was right and only this file was wrong.
Only the people at the frontier hold a gate shut
A character now counts towards a boss's gate only once it has the boss before it in the table.
The case that forced it: a group has cleared Eikthyr, somebody kills The Elder, and the Swamp stays shut - held by a character who has killed nothing at all. That is a person two steps behind the frontier deciding when the people at it may move, and there was nothing they or anyone else could usefully do about it except wait out the catch-up deadline. The gate exists to make fetching your friend worth doing, not to stop a group at the boss its newest member has not reached.
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 the person who is behind - which is the one where helping them is a single evening rather than a campaign. And every biome the group has already earned stays open to them, because the latch is a fact about the group and not about who is standing in it today.
Two decisions inside that are worth naming. It tests the member's own credit rather than whether the previous gate is open: a gate that is open is open for everyone the moment it latches, so testing that would exclude nobody and the rule would do nothing. And it is the immediate predecessor rather than the whole chain, because somebody carrying The Elder without Eikthyr is at the Swamp's frontier by any honest reading.
It lands in Counts, the one seam the gate asks through, so the verdict, what gets latched and
the names in "still owed by" all follow it together rather than two of the three.
Gate.RequirePreviousBoss, default on, host-synced like every other rule.
[1.2.1] - 2026-08-25
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_GlobalKeyshold 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. - 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.
Nothing here changes a rule, a number or a saved value. A gate already latched open stays open - that is what "never regresses" means, and unpicking it after the fact would be a worse promise than the one that was broken.
[1.2.0] - 2026-08-19
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] - 2026-08-17
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] - 2026-08-16
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
0.2.0 shipped the idea; this is the version where it holds up.
- 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.OnDeathlooks like it runs on every client that had the boss loaded, since it pushes vanilla's key above anIsOwnerearly-return. But that guard is unreachable, becauseCheckDeathis its only caller and sits insideif (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. - Credit is per world. A character that cleared a solo world no longer arrives
pre-credited.
BackfillFromCharacterstill allows the migration case, and only for a boss this world has already seen die. - 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.
- 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
RosterDaysfinally drops them. A biome the deadline opens latches too. - Per-boss roster windows via
RosterDaysPerBoss, for when one boss deserves a shorter leash than another. - The blocker line names other people, never you, and shows how long is left.
Fixed
- A refused meal or potion is no longer destroyed.
Player.ConsumeItemremoves the item regardless of whatEatFoodreturns, so the refusal had to move toCanConsumeItem, the gate that path actually respects. - Refusing a guardian power no longer burns its cooldown;
StartGuardianPowersets the cooldown before applying the effect. Restedcan no longer be topped up past the drain.SEManrefreshes a running effect throughInternal_AddStatusEffectwithout ever reaching the public overload.Pukeis 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.
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.
defeated_queenanddefeated_faderare taken from prefab data rather than the game'sGlobalKeysenum. A wrong key fails closed, which is indistinguishable from a working gate.LogGlobalKeysprints what your world actually has.
[0.2.0] - 2026-08-15
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
Three parts rather than one number, because they do different jobs:
- 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.
- 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.
- 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.
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.
- 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.