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.
ValheimAdminForge
Server-authoritative admin GUI: dynamic catalogs (items, effects, creatures, events) for vanilla + modded content, plus player, world and teleport tools.
By Skitale
CHANGELOG
Changelog
0.4.0
- New
Server/TeleportSpreadconfig (default 2m, 0 disables): when several admins "Go to" the same player, each now lands at a different point on a ring around them instead of stacking on top of the target and each other. - New "Map" button next to the X/Y/Z coordinate fields (teleport picker and the Players tab's own coordinate row) — click a spot on the in-game map to fill the fields instead of typing coordinates. Closes the Admin Forge window while the map is up so nothing overlaps, and reopens it after the click.
- "Bring" now goes through the same server-resolved path as "Go to" instead of a separate, client-computed position — it gets the spread-out-admins fix too (no longer stacks the brought player exactly on top of you) and no longer silently no-ops when it can't confirm the target's position.
- Window border/tooltip-strip flicker while dragging: fixed by switching the window to
GUI.Window(notGUILayout.Window) and snapping its remembered position to whole pixels —GUILayout.Windowsilently discards a rounded position every frame. - Window/DimTextColor now also applies to the plain toolbar captions ("Search", "Count", the drag hint, etc.) that previously ignored it. Its default is now black (was grey); default window opacity is now 0.8 (was 1, fully solid).
- Items/Creatures "Mod" filter is a type-to-filter + cycle button now (same UX as World tab's Weather picker), not a row of one button per mod.
- Effects tab: vanilla/modded distinction, plus the same "Mod" filter, for status effects added by mods that ship their own.
- Fixed the Mod filter's cycle button showing the next candidate instead of the one it had just applied — clicking one mod would immediately relabel the button with a different mod's name while still (correctly) filtering to the one you clicked, reading as if the wrong mod's entries had appeared.
- Modded creatures never got a mod name (so the Creatures "Mod" filter row never appeared),
because the attribution diff read
ZNetScene.instance, which is still null for the wholeAwakeprefix chain — exactly where most mods add their prefabs outside the common modding framework's own path. It now uses the instance the Awake was actually called on. Item attribution happened to work around this by accident; status effects and creatures did not. - "Go to" landed every admin at the exact same offset from the target player instead of spreading them out (the spread angle was seeded from a value that's a constant for every admin); "Bring" failed outright ("target player position is not available") when the admin doing it was the listen-server host, and could in rare cases pull the wrong player instead. Both were teleport-resolution bugs on the server side.
- The mod-filter row (Items/Creatures/Effects) could throw an IMGUI "pushing more GUIClips than popping" error the instant you clicked into the Origin toolbar, and the window could overflow past its own bottom edge once the row appeared, especially at the minimum window height.
DimTextColornow falls back to the default like its description already claimed, instead of showing broken markup for an unparsable value.- Mod-name attribution for third-party content no longer goes stale after the catalog it's attached to reloads (world change, late-loading mod), and no longer merges two unrelated mods that both embed the same shared helper library under one fake name.
- The Mod filter's cycle button could still relabel itself away from the active filter by a second path: typing a search that filters the active mod itself out of the match list left the button showing a different candidate while the item/creature/effect list stayed filtered to the old one. Clears the active filter (back to "All") when that happens, instead of leaving the two disagreeing.
- Players/Raise skill failed outright ("Method not found: void .Character.Message(...)")
for every skill, vanilla ones included, on any setup carrying a mod built on a
commonly-embedded skill-management helper library. That library's
Harmony prefix on
Skills.CheatRaiseSkillholds a call to aCharacter.Messageoverload vanilla no longer has, and Mono resolves it while JIT-compiling the prefix — so it throws before the prefix can even decide the skill isn't one of its own. Raise now does the level change itself through public API and never calls CheatRaiseSkill, so it no longer depends on that method being patch-free. - Mod attribution could overwrite an already-known owner with "unattributed" if
ObjectDB.Awakeran a second time in the same session and re-added a prefab/effect of the same name through a patch call that couldn't be attributed — now skipped instead of clobbering a good value with nothing. - Fixed a rare crash ("can only be called from the main thread") when a text-color config value changed off the main thread (e.g. a config-file reload) instead of via the F1 manager — the stale GUI skin it leaves behind is now cleaned up from the next GUI frame instead of destroyed on the spot.
0.3.2
- Player target picker is a click-to-select grid with a filter box now, not a cycle button
0.3.1
- Update readme
0.3.0
- Despawn: a mob spawned moments earlier could be "resurrected" a second later — its
destroy RPC beat its own create RPC to the server, which then ignored the destroy
and synced the mob back ("mobs reappear / press despawn twice"). Fixed by pulling
each ZDO out of the sector index immediately (so
ZNetScenecan't re-instantiate it before the destroy broadcast lands) plus one delayed re-sweep ~1.5 s after each despawn for anything that still slipped through. Runs on the target player's client (a dedicated server doesn't instantiate creatures, so a server-side sweep sees nothing). - Post-review hardening: the world / event commands now
reject NaN / out-of-bounds payloads and unknown environment names, the
envoverride toast only shows to admins, cross-player actions echo a confirmation to the admin, the weather list rebuilds on a world change,PositionPickerno longer flips its control set mid-frame, the client tag table clears on disconnect, and one failed Harmony patch no longer aborts the whole mod. NewServer/PlayerTagstoggle; minimum window size raised to 560×560. - Player name tags: a per-player tag (text + colour) driven by a server-side
BepInEx/config/ValheimAdminForge.tags.json(keyed by SteamID64) — a client can't tag itself. The server broadcasts acharacterZDOID -> tagtable; each client renders it on the head-plate / hover name, in chat, and in the Players tab. Edits to the file apply within ~2 s, and the tag survives death / respawn. - Players tab: Die action (kill the selected target; blocked by god mode, like the console command).
- World tab: time of day, weather (from
EnvMan.m_environments), wind, and the natural-spawn toggle are broadcast to every client (they're process-local overrides that don't sync on their own); time skip (advance shared net time, or jump to next morning), time scale, and a global-key editor run on the server. NewExecutionSite.AllClientsfor the broadcast. - Events tab: the random-event list is built dynamically from
RandEventSystem(mod events included). Start an event at yourself / at a player / at coordinates, Stop, or Random — all run on the server (the vanillaeventcommand isonlyServerand unreachable from a dedicated-server client). Detail card shows biome, duration, range, what it spawns, and required global keys (missing ones flagged). Header shows the active event with a Stop button. - Internal:
IAdminCommand.Site(ExecutionSite.TargetClient/Server) so the dispatcher knows whether to forward a command to a client or run it in the server process. SharedAnchorModeenum for the "at me / at target / coords" picker. - Creatures tab: the creature list is built dynamically from
ZNetScene— vanilla and mod-added creatures appear with no per-mod code, same as the item catalog. Search, vanilla/modded filter, detail panel (faction, base health, boss, tameable). Spawn with count / star level / tamed / health override / spread, at yourself, at another player, or at coordinates — the server resolves the position and caps the count (Server/MaxCreatureSpawn); bosses needServer/AllowBossSpawn. Force-tamed non-tameable creatures go passive instead of spamming a vanilla warning. - Creatures tab Despawn block: remove creatures / ground items / fish / birds
around a player without killing them — no loot, no death, no progress or event
credit. Filter by enemies / tamed / all, prefab name, minimum star level. Players
and tombstones are never touched; radius capped by
Server/MaxDespawnRadius. Claims ZDO ownership first, so it clears objects owned by other clients (vanillaremovedrops/removefishdon't). - Players tab: the "send to coordinates" row now uses the same target picker as the rest of the mod instead of its own separate one.
- Player admin actions (Players tab): god, ghost, fly, nocost, heal, puke, repair
all, clean inventory, explore / reset map, raise / reset skill, and radius sweeps
(kill all / kill enemies / kill tame / tame / aggravate) — applied to the shared
target (self or any online player). Freefly toggles the local camera only. Each
mirrors the vanilla console command of the same name, most of which a dedicated
server denies to clients. Radius sweeps are capped by
Server/MaxActionRadius. - Listen-server (host + friends) parity. Cross-player give / effect / teleport on a non-dedicated host now applies to the actual target instead of the host, and the post-teleport ghost cleanup broadcasts from the host too. Previously only tested on dedicated, where the host is headless.
- Server drops unidentified and rate-exceeding requests silently (per-peer limit) — a spammy client can no longer flood the server log.
ItemCatalogno longer permanently discards items whose localized name didn't resolve (e.g. a mod that registers its localization late); it falls back to the internal name, matching the status-effect catalog. Catalog version bumps on invalidation, not on lazy rebuild.- Internal: shared
LazyCatalog/CatalogLocskeleton behind both catalogs and aFilteredListhelper behind the Items / Effects tabs, so the upcoming Creatures tab doesn't fork the pattern a third time (~100 fewer lines). - Admin permission is enforced once in the RPC dispatcher instead of being repeated in every command.
- Docs, dead code, and minor allocation/redraw cleanups.
Server/StrictItemChecknow documented as also gating status effects.
0.2.0
- Effects tab: status effects discovered from
ObjectDB, with optional duration/power and a Clear button. - Players tab: teleport to a player, bring a player, send any player to coordinates. Server resolves target positions (works even when map-sharing is off). Instant vs loading-screen teleport with freeze protection; post-teleport ghost cleanup.
- Target picker on the Items and Effects tabs (self / any online player).
- Item catalog now drops unresolved/cut-content entries; localized names and descriptions.
- Client↔server handshake reports the admin verdict and warns on a mod-version mismatch.
- RPC handlers are exception-guarded; diagnostic logging moved to Debug level.
0.1.0
- Item catalog built dynamically from
ObjectDB(vanilla + modded), with search, categories, vanilla/modded filter, sort, detail panel and quantity stepper. - Server-authoritative give: per-connection RPC, admin check against the real socket
identity,
IAdminCommandextension point. - IMGUI window (Insert), input capture while open.