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.
Njord
A mythic overhaul of Valheim’s ship handling, steering and sea‑faring — now with a Harbourmaster who gives every new Viking their first hull and refits the rest. HUD and OdinShipPlus support.
| Date uploaded | 3 weeks ago |
| Version | 2.0.7 |
| Download link | Wubarrk-Njord-2.0.7.zip |
| Downloads | 520 |
| Dependency string | Wubarrk-Njord-2.0.7 |
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
⚓ NJORD: Master of the Sea 🌊
A mythic overhaul of Valheim’s ship handling, steering, acceleration, and sea-faring experience.
Njord makes boats feel powerful, responsive, and alive — without breaking Valheim’s soul. It introduces modernized helm control, configurable sail and acceleration forces, dynamic wind blending mechanics, a custom HUD, and an optional multiplayer-safe runic wake VFX.
🆕 New in v2.0.0 — The Shipwright Update
| What's new | |
|---|---|
| ⚓ The Harbourmaster | A shipwright takes her post on the shoreline nearest your world spawn. Buy a hull, claim your first one, or have the vessel you're stood on refitted. |
| 🎁 Your First Hull, Free | Every player is given one boat, once, for as long as that world exists — named <your name>'s Pride before she touches the water. |
| 🪵 Paid For In Timber | Hull prices are lists of materials, per hull, set by the server. No coins involved, and no other trader on your server is touched. |
| ⭐ Refits | Stand aboard a hull at the harbour and pay 2×, 3×, then 4× her price to raise her. What a star is worth is entirely the server's business. |
| 🪟 The VikingOS Frame | The Harbourmaster's shop wears the same gilt window chrome as the rest of the suite, shared rather than reproduced. |
| ⚠️ Everyone Updates Together | 2.0.0 raises the ServerSync floor to 2.0.0, so a 1.x client cannot join a 2.0.0 server. The shipyard's RPCs are new. |
✨ Core Features
⚡ Responsive Steering
- Modernized helm control: Smooth, intuitive turning.
- Adjustable steering multiplier: Your longship finally answers the helm.
- Steering gate: Prevents jitter upon helm acquisition.
💨 Acceleration, Sail Forces & Max Speeds
- Overhauled default physics: Provides a smoother, more realistic sailing curve.
- Configurable forces: Adjust forward/reverse and Base/Half/Full sail behavior to your liking.
- Reverse-kick: Optional quick burst of reverse speed for tight maneuvering out of rocky harbors.
- Custom Max Speeds: Per-boat max speed configuration (Njord vs Vanilla).
🌬️ Dynamic Wind Systems
- Instant Snap HUD: When grabbing the rudder, the Njord HUD instantly displays the true natural wind angle.
- Toggleable Full Wind: Enable "Full Wind Always" if you want to skip the sailing struggle.
- [EXPERIMENTAL] Wind Assists: Advanced opt-in mechanics like
Wind_NoDeadZone(nudge out of dead zones) andWind_BlendToFull(blend toward tailwinds) give you a mythic edge against the sea. - Grace Period Mechanics: Natural winds are punishing. When the wind shifts against you, Njord enforces a realistic grace period (default 2.5s). You will feel the dead zone before any magical assists kick in to save you.
🪶 Named Vessels
- Alt + Use at the helm opens the christening dialog.
- Stored on the ship's own record — persists across sessions and syncs to every player.
- Appears in the helm hover panel, the crosshair hover label, and the Njord HUD.
- Up to 24 characters.
🧭 Njord HUD
- Clean, minimal, and mythic.
- Displays your vessel's given name alongside her hull type.
- Fully multiplayer-safe.
- Shows steering, speed, waterline, hull integrity, wind blend, and readiness.
- Drag to reposition freely on your screen.
- Toggle visibility instantly with F7.
⭐ Runic Wake VFX
- Optional glowing wake effect behind ships.
- Color-tinted based on your configuration.
- Scales with speed and sail state.
- Fully multiplayer-safe: Zero performance impact on servers and properly displays across all connected clients.
⚓ The Harbourmaster
A shipwright is placed automatically on the shoreline nearest your world spawn, the first time anyone loads that zone. She keeps her post across restarts, and admins can move her.
[!IMPORTANT] On an established world she may never appear on her own. A dedicated server loads a zone only while somebody is standing in it, and on a world where everyone spawns straight into their own base, nobody has any reason to go back to the world spawn — so the placement never triggers. This is not a failure and the log will say so plainly rather than going quiet. Put her where your players actually are with
njord.harbour.placeat <x> <y> <z>, or have someone walk to spawn once. New worlds place her by themselves, because the first thing anyone does is stand at the spawn.
Use on her opens Njord's own shipyard panel — not Valheim's trader shop. Vanilla's shop can only count coins, and Njord's prices are lists of materials, so Njord draws its own. The consequence worth knowing is the good one: no other trader mod on your server is patched or touched.
| Command | Effect |
|---|---|
njord.harbour.place |
Post or move her where you stand; the slipway is re-derived from the water in front of you |
njord.harbour.placeat <x> <y> <z> |
The same, at explicit world coordinates |
njord.harbour.find |
Print her position and slipway — or, if she has none, why she has none |
njord.harbour.remove |
Destroy the Harbourmaster loaded near you and forget the site |
njord.harbour.forget |
Forget the recorded site without destroying her |
njord.firstboat.revoke <playerID> |
Give one player their free hull back |
Type them in your own game, not at the server console. Placing her is a physical act — the
shoreline is found by raycast and she is seated on a settled heightmap — and a dedicated server
has no colliders or heightmaps outside the world origin. It decides; it cannot measure. So your
machine does the placing, and the server is asked only to authorise it and to record where she
went. It checks you against its adminlist.txt before recording anything.
The consequence worth knowing: the ledger half of an answer prints in the server's log. What your own machine can see prints in your console.
njord.harbour.placeat needs the target zone loaded on your machine — a coordinate in a zone
you are nowhere near measures nothing. If in doubt, stand there and use njord.harbour.place.
njord.harbour.find is also the diagnostic when she never appeared. It reports the world
spawn, whether that zone is loaded at all, and whether the shoreline search finds an acceptable
site — which separates "the search never ran" from "the search ran and rejected everything".
Those two look identical in a log and have completely different fixes.
[!IMPORTANT] The Harbourmaster is written into your world save. Her ZDO names a prefab that only Njord registers, so a world that outlives the mod keeps an object nothing can build. It is harmless — she simply fails to appear — but run
njord.harbour.removebefore uninstalling if you want the world left clean.
🎁 Your First Hull
Every player is given one boat, free, once, for as long as that world exists. She arrives
already christened <your name>'s Pride.
This is the one transaction Njord does not trust the client with. Buying a hull follows vanilla's own trust model — the buyer checks and pays out of their own inventory, exactly as the vanilla shop does with coins — but a grant that can be repeated is not a grant. So eligibility is decided on the server, against a ledger keyed by your persistent player ID, and the row is written before the boat is handed over: a crash mid-grant costs you a boat rather than handing out a second one. Rerolling a character does not get you another.
A gift is not a christening, either — the free hull arrives named, and that does not count
toward your boats_christened stat. You did not name her.
⭐ Refits
Stand aboard a hull at the harbour — or moor her alongside — and pay a multiple of her price to raise her a star. Anyone aboard may pay for a refit; Njord has no concept of hull ownership, and inventing one for this would be a bigger change than the feature deserves.
What a star is worth is entirely the server's business. Upgrade_Tier2/3/4 are lines of
speed, accel, health and cargo values applied against the hull's base figures,
never compounding — so a ⭐4 hull is exactly base × her own tier's number, however she got
there, and lowering a lower tier later cannot leave her carrying a bonus nobody can account
for.
[!NOTE]
speedraises the cap;accelraises the boat. If yourMaxSpeed_*values are set above what a hull can physically reach — the usual way of turning the limiter off — then the cap is not what is holding her back and thespeedkey does nothing at all. On such a serveraccelis the only key that changes how fast a boat actually goes. That is why the shipyard panel quotes the refit's top speed in m/s, before and after, rather than as a multiplier: two numbers you can check against your own HUD cannot mislead you the way a multiplier can.
accel's effect is also sub-linear — drag rises with velocity — so a large number there buys a smaller gain than it looks. The defaults are a starting point to measure, not a promise.
A refit never heals or hurts a hull: raising her maximum health scales what she currently has by the same factor, so a battered boat leaves the yard exactly as battered as she arrived, with a bigger hull around it.
[!WARNING]
cargois the one refit that can destroy items. An item sitting in a slot that stops existing is gone. It is0in every tier out of the box, and Njord never shrinks a hold within a session — but lowering it later, or removing Njord, takes those rows away with whatever is in them.
🤝 Mod Compatibility
Njord is built to play nicely with the most popular Valheim sailing and ship mods:
- OdinShip: Full native support. Njord automatically discovers OdinShip prefabs, applies advanced physics, and generates custom speed limit configurations for each ship.
- OdinShipPlus: Full native support. New prefabs are mapped seamlessly into Njord's speed limits logic.
- Sailing (Smoothbrain): Fully compatible. Njord respects the Sailing mod's skill progression and works alongside it without conflict.
🛠️ Configuration & ServerSync
[!IMPORTANT] Njord uses ServerSync. Server administrators can lock all configurations so they remain authoritative across all clients.
All major systems are configurable via BepInEx (wubarrk.njord.cfg):
SteeringMultiplier&AccelerationMultiplierBaseForwardForce/BaseReverseForceSailForwardForce/HalfSailForce/FullSailForceReverseKick- Wind System Toggles, Blend Rates, and Grace Periods
MaxSpeed_<ShipType>per ship (e.g.MaxSpeed_Raft,MaxSpeed_Karve,MaxSpeed_Longship,MaxSpeed_Drakkar, plus OdinShip/OdinShipPlus ships when detected)VFX_Enable&VFX_Color- HUD position & toggle
Barrkbot_Enable& the export intervals (see below)12 - Shipwright—Vendor_Enable,Vendor_AutoPlace,Vendor_Name,Vendor_HullList,Vendor_FirstBoat_Enable/_Hull, and aVendor_Cost_<Hull>per vanilla hull plusVendor_Cost_Defaultfor everything else
Costs are written as PREFAB:AMOUNT, comma separated — FineWood:60,DeerHide:20,BronzeNail:120.
Prefab names, never display names, because a prefab name is the same string in every
language. A cost naming an item this world does not have takes that hull out of the shop
with a logged reason rather than quietly selling it for whatever was left of its price.
📊 BarrkBOT Data Export
Njord can publish what it measures so an outside tool — a Discord bot, a dashboard, a status page — can answer questions about the fleet. Off by default.
Enable Barrkbot_Enable and the server writes
BepInEx/config/Njord/barrkbot_boats.json:
world_boats— how many hulls exist in the world, broken down by prefab. Counted by sweeping ship ZDOs, which only the server can do.speed_records— the fastest each hull type has ever gone, with the cap that was in force at the time, when it was set, and who was at the helm.
Clients sample speed for the ship they are steering and report their bests to the server;
the server is the only peer that can write the file. Records survive restarts in a sidecar
njord_speed_records.tsv next to the export.
The file is written atomically, so a reader never catches it half-written, and it is
deliberately strict about absence — a hull missing from by_prefab means none exist, a
hull missing from speed_records means nobody has ever sailed one, and cap_in_effect is
null when no cap applied. None of those are ever reported as a zero. world_boats is
null until the first census completes, because "not counted yet" is not "none".
Each record carries two sample counters rather than one: samples_observed is every tick a
hull was watched under way, and samples_recorded is the subset that cleared
Barrkbot_MinSpeed and was eligible to set the record. They differ by exactly what the
speed floor discarded, so samples_recorded is the sample size behind top_speed.
Not included: per-player records. Each hull has one record with a helmsman
attribution, so "who holds the Longship record" is answerable and "who is the fastest
sailor on the server" is not — there is no per-player table and no leaderboard.
[!NOTE] Where a speed cap is in force,
top_speedconverges oncap_in_effectand stays there — it measures the cap, not the hull. Njord caps every hull it recognises, so near-exact ties with the cap are the normal reading, not a suspicious one. The durable content of a record is thehelmsmanandrecorded_at; the number is close to a config lookup.cap_in_effectisnullonly where no cap was in force when the record was set. On a normal setup that means a hull Njord has no cap for — a boat from another mod, or vanilla's unusedTrailership, which carries aShipcomponent but no recipe — which is worth reading as an admin signal, not a missing value: it is an uncapped hull on a server that has decided hulls should be capped, and nothing else on the server will say so. A reader validatingtop_speed <= cap_in_effectmust skip nulls rather than fail them; an unhandled hull has no bound to violate.
| Setting | Default | What it does |
|---|---|---|
Barrkbot_Enable |
false |
Master switch for the export. |
Barrkbot_WriteInterval |
60 s |
How often the export file is rewritten (only when something changed). |
Barrkbot_CensusInterval |
900 s |
How often boats are counted. This sweeps every ship ZDO — the expensive half — so it runs far less often than the speed table. |
Barrkbot_MinSpeed |
1 m/s |
Speeds below this are ignored, keeping drifting hulls out of the table. |
Barrkbot_Sailors_Enable |
true |
Also write the per-player file below. Requires Barrkbot_Enable. |
Per-sailor stats
With Barrkbot_Sailors_Enable on, the server also writes three per-sailor collections,
split by subject rather than by rows:
| File | Collection | Carries |
|---|---|---|
barrkbot_sailors.json |
sailors |
distance_sailed_meters, helm_seconds, distinct_hulls_helmed, last_seen |
barrkbot_wrecks.json |
wrecks |
boats_wrecked, boats_christened, and the world totals block |
barrkbot_hull_bests.json |
hull_bests |
One row per sailor × hull: personal_best_speed, cap_in_effect, recorded_at, distance_sailed_meters, helm_seconds |
Rows are keyed by the persistent player id, with the display name beside it in every file. Both are emitted on purpose: the id is the join key that survives a rename, and the name is the bridge to every other tool that only knows people by name.
Splitting is by subject, never by rows. Every file holds every sailor, so any ranking a reader computes sits on a complete base. A row-split — sailors 1–4 in one file, 5–7 in another — produces a file that confidently reports the wrong leader, which is worse than reporting none.
hull_bests is flat, one row per pairing. Nested objects get stripped from multi-row
listings, so a by_hull map hanging off each sailor rendered as a roster of names carrying
nothing rankable. Flattened, "who is fastest on a Karve" and "who has sailed furthest in a
longship" become answerable.
[!NOTE] The per-sailor figure is called
personal_best_speed, nottop_speed.top_speedmeans one thing only in Njord's exports:speed_records[hull].top_speedinbarrkbot_boats.json, the world record for that hull across everyone. The two are different bases, and giving them one name in two files would be a collision no reader could see. A name that cannot be confused beats a warning that says not to confuse them.
Rollover
When a collection outgrows Barrkbot_RowBudget of rendered row characters, it continues
into barrkbot_sailors_2.json, _3, and so on. Every part carries part and part_of.
Njord used to pin ServerSync's minimum version to its own, so every release disconnected every player until they updated. Rollover exists because of that — a growing roster is handled by the writer rather than by shipping a new build, and the cost of "the file got big" should never land on everyone playing.
The pin itself is now separate: Njord carries a sync floor that only moves when a synced setting or an RPC genuinely changes shape, so ordinary builds no longer lock anyone out. The reasoning behind rollover stands regardless — it was never only about the pin.
Each part also carries a <collection>_leaders block — the top three per rankable field,
computed across the whole collection before it is split, and identical in every part. A
part holding one row of thirteen still reports the true overall leader. Without this, a part
would rank over its own fragment and report a wrong winner with total confidence.
🧩 Dependencies
Njord needs just one thing at runtime:
| Dependency | Why |
|---|---|
| BepInExPack Valheim | The mod loader (also provides HarmonyX). |
(ServerSync is compiled into Njord and needs no separate download.)
📥 Installation
- Install BepInExPack for Valheim.
- Drop the Njord folder into your
BepInEx/plugins/directory. - Launch the game.
- Edit the generated
BepInEx/config/wubarrk.njord.cfgas desired.
🧪 Known Limitations
- Works flawlessly in singleplayer and multiplayer.
- Fully server-authoritative config sync architecture.
- Safe to install mid-playthrough.
- Removing Njord is no longer entirely world-neutral. The Harbourmaster is a real object in your save; without Njord her prefab does not exist, so she silently fails to appear and her ZDO lingers. Nothing breaks.
njord.harbour.removeclears her properly if you want it tidy. Everything else Njord stores — ship names, refit tiers — lives on the boats' own ZDOs and is simply ignored when the mod is gone. - Note: VFX appearance may vary heavily when using modded water shaders. VFX emitters may appear at slightly inaccurate offsets on certain OdinShip prefabs.
Njord — God of the Sea, who tolerates your steering
Support Wubarrk on Patreon
License: MIT — use, modify, and redistribute freely, including commercially; just keep the copyright notice. See LICENSE.md for the full text.
CHANGELOG
📜 Njord — Changelog
⚓ v2.0.7 — The Dockside Update
[!NOTE] The Harbourmaster will now stand on a dock you built instead of falling through it onto the seabed. Client-side placement only - the ServerSync floor stays at
2.0.5, nothing on the wire changed, and no config entry changed.
- She Stands On What You Built: post her on a pier, a jetty, a raised deck, anything with a floor, and she stays on it. Until now she was cloned from Haldor and inherited his
SnapToGround, which finds the ground by raycasting the terrain layer and only the terrain layer - a dock is simply not there as far as it is concerned. So she was dropped straight through it to whatever the natural ground was underneath, which over water means the seabed, with the Harbourmaster standing on it. Worse, that height was then written into her saved position, so everyone on the server loaded her down there too. - Njord Seats Her Itself Now: vanilla's snap is off her prefab entirely, because she was getting it twice and both were terrain-only - once the frame after she spawns, and again on the next global snap pass anywhere in the world, which would have undone any correction. She is now seated once, at the moment she is posted, against every solid surface at that spot: terrain, player pieces, and the world's own structures. Boats are deliberately excluded - a karve moored under her is not a floor - and so is anything directly over her head, so posting her inside a boathouse puts her on its deck rather than in its roof.
- The Watchdog Measures Her Post, Not Her Feet: for half a minute after she is placed Njord checks she has not sunk into the ground, which covers a zone that finishes settling around her. That check now asks what the floor is where she was posted; asking what is under her feet was useless in exactly the case that mattered, because once she is under a dock the honest answer is "the seabed". It also only ever lifts her, never lowers her, so a dock collider that is slow to stream in can no longer be read as an excuse to drop her off it.
[!TIP] On a world where she is already under the dock, her bad position is saved in the world file and this build will not move her on its own. Stand where you want her and run
njord.harbour.placeonce; she will stay put from then on.
⚓ v2.0.6 — Valheim 1.0.16 compatibility
[!NOTE] Rebuilt against Valheim 1.0.16 and re-verified. No floor change - the ServerSync floor stays at
2.0.5: nothing on the wire and nothing written to the world changed.
Rebuilt against the Valheim 1.0.16 release assemblies (client build 25527674 / dedicated server build 25527701, network version 40) and BepInEx 5.4.2350, and re-verified: a static reference check against both the client and dedicated-server assemblies, and a headless boot of the 1.0.16 dedicated server. Njord touches none of the members 1.0.16 changed (it removed only ObjectDB.GetAllFoodItems() and ButtonSfx.Start(), neither of which Njord reads), so every patch binds exactly as it did before.
⚓ v2.0.5 — The Handover Update
[!IMPORTANT] This is the fix for boats that jitter, refuse to take forward or back, snap around under the crew, or throw people overboard after two players trade the helm — the bug that previously only cleared when the original helmsman dove off. Everyone updates together: the server and every client. The ServerSync floor is raised to
2.0.5because the hand-off is cooperative — one machine aboard on an older build is enough to bring the fight back for everyone on that hull. No config entry changed.
Traced from two rounds of live logs (two clients plus a dedicated server, with a transition-only ownership trace). There were two causes stacked, and fixing only the first was not enough.
- The Server Was Never Listening: Njord's helm authority is meant to be arbitrated by the server — a client asks for the helm, the server records who has it and tells every other client. That arbiter was being switched on from a hook that only fires when a player spawns, and a dedicated server has no player. So on a dedicated server it never switched on at all: every helm request was silently dropped and no one was ever told to stand down. The arbiter now comes up the moment the network layer exists, on every peer, headless server included — and re-registers itself cleanly if you log out and join another world in the same session.
- The Hull Was Being Grabbed, Not Handed Over: with the arbiter alive, every handover still fought for one to six seconds. The incoming helmsman's machine took the hull's physics the instant it took the wheel, while the outgoing helmsman's machine was still simulating the hull and still believed it owned it. Valheim settles two machines' claims by whichever wrote data most recently, and the machine simulating a hull writes every tick — so the grab was undone by its next packet, the helmsman's machine grabbed again, and the two traded the hull back and forth until, by luck of timing, the outgoing side heard the news first. Every swap hard-snaps the hull to the other machine's position under everyone's feet: that is the jerking, the boat that "re-dropped like it was just built" (a snap large enough to teleport rather than glide), the deck throw, and the helm that steered but would not take forward or back (each press landed on a copy that was overwritten a few ticks later).
- The Fix: vanilla never takes a hull from a machine that is still simulating it —
Ship.UpdateOwnerhas the owner pass it on, and that is the one kind of transfer the game settles in a single exchange. Njord now does the same. When the server announces a new helmsman, the machine simulating the hull hands it to them on the spot; its own simulation stops there and then, and its next packet carries the new owner with the freshest data, which every copy accepts at once. The incoming helmsman no longer claims from a live owner at all; the only hull it takes outright is one nobody holds. Thrust is applied only once the hull has actually arrived, as vanilla gates every force it applies. A helmsman whose hull never arrives — its previous simulator gone or unloaded — still claims it outright, but only after a full second, well past any hand-off that is ever going to come, when nobody else is writing to it. - Nobody Left Holding A Dead Rope: if a helmsman's connection drops — logout, timeout, or crash — the server releases their helm and tells everyone, so a hull is never bound to someone who can no longer let go of it. A machine that finds itself simulating a hull with people aboard and no record of who steers it (a late joiner, typically) now asks the server before it could contest the real helmsman without knowing.
- Your Debug Flags Were Working All Along: Njord's
Debug_Enableoutput was written at a log level BepInEx's default disk logger discards, so turning the flag on appeared to do nothing. Debug output now goes out at Info level; the flag is still the gate.Debug_AuthControladditionally traces every helm request, arbitration reply, and ownership transition — logged on change, never per tick, so it is safe to leave on. A clean swap readsRPC_AuthorityUpdate applied→handed ZDO ownership to peer …on the outgoing machine and a singleIsOwner False -> Trueon the incoming one; noclaimed … outrightline and no repeatingIsOwnerflips.
⚓ v2.0.2 — The True Muster Update
[!NOTE] A correctness fix to how a ship knows who is aboard her. No config, RPC, or synced setting changed — the ServerSync floor stays at
2.0.0.
- The Boarding Roll No Longer Drifts: vanilla adds a player to a ship's boarding list on every single trigger-volume touch, with no check for whether they're already listed. A hull whose deck spans more than one trigger volume — or a standing player jostled by waves at the seam between two — could rack up duplicate entries that never fully cleared, so a solo sailor's own "onboard" count could climb into double digits over a long session on a longship instead of resting at one. Njord now tracks how many of a ship's volumes each player actually overlaps and only touches the real boarding list on a genuine arrival or departure. Every hull behaves exactly as it always has for the ordinary case; the drift is gone for the complex one.
- Why It Matters Beyond The Log: a stale duplicate entry could leave a ship's own "is anyone still aboard" check stuck on
truelong after the honest answer wasfalse— the kind of desync that can leave a hull unresponsive at the helm. This closes that specific failure mode. It does not touch helm-claim or ZDO-ownership logic, which are unchanged from 2.0.1.
⚓ v2.0.1 — Valheim 1.0.7 compatibility
Rebuilt against the Valheim 1.0.7 release assemblies (client build 25185596 / dedicated server build 25185644, network version 39) and BepInEx 5.4.2350, and loaded on the 1.0.7 Linux dedicated server with every rune bound and no Harmony errors. Njord touches none of the members 1.0 changed (the sector API, VisEquipment hashes, ItemStand, ZDOExtraData, Inventory.Load, save paths, Version), so every patch binds exactly as it did before.
- The ship destroy hook is real now.
Njord_Ship_Destroy_PatchtargetedShip.OnDestroy, a method that has never existed on any build (Ship's only destruction method is the privateOnDestroyed()that WearNTear calls when a hull is broken, which never fires on zone unload or logout). The class was never handed to the rune binder either, so it was dead code rather than a crash — the rune-trail emitter's bookkeeping was simply never cleared when a ship left the world. The cleanup now rides on aNjordShipEmitterCleanupcomponent attached to the ship's GameObject the first time a trail is built for it; its UnityOnDestroyfires on every teardown path — wreck, dismantle, zone unload, logout — and the dead Harmony target is gone. - ServerSync floor stays at
2.0.0: no synced entry or RPC changed, so 2.0.0 clients can still join a 2.0.1 server.
⚓ v2.0.0 — The Shipwright Update
[!IMPORTANT] Everyone updates together. 2.0.0 raises ServerSync's floor to
2.0.0, so a 1.x client cannot join a 2.0.0 server. This is a release rather than a test build, and the RPCs behind the shipyard are new.
[!IMPORTANT] Njord now adds an NPC who is written into your world save: the Harbourmaster's ZDO names a prefab only Njord registers, so if you later remove the mod she becomes an object nothing can build. Nothing breaks — she simply fails to appear — but
njord.harbour.removetakes her out cleanly if you want the world left tidy.
The Harbour
- The Harbourmaster: a shipwright takes her post on the shoreline nearest your world spawn, the first time anyone loads that zone. Talk to her to buy a hull, claim your first one, or have the vessel you are stood on refitted. She keeps her post across restarts. On an established world she may never place herself — a dedicated server loads a zone only while somebody is standing in it, and nobody revisits spawn — so put her where your players actually are with
njord.harbour.placeat <x> <y> <z>. - She Will Not Be Buried: traders are one of only four things in Valheim that snap themselves to the ground, and they do it one frame after spawning, before the terrain has necessarily finished. Njord finishes the ground under anything about to snap, places her only once the ground has settled, and watches her for thirty seconds afterwards — digging her out and persisting the fix if she has sunk.
- Placing Her Is Done From Your Own Game: the shoreline is found by raycast and she is seated on a settled heightmap, and a dedicated server has no colliders or heightmaps outside the world origin. It decides; it cannot measure. So your machine sites her and the server authorises it and records where she went, checking you against its
adminlist.txtfirst. The ledger half of an answer appears in the server log; what your own machine can see prints in your console.
The Shipyard
- Your First Hull, Free: every player is given one boat — a Karve — once, for as long as that world exists, named
<your name>'s Pridebefore she touches the water. Eligibility is decided on the server, against a ledger keyed by your persistent player ID, and the row is written before the boat is handed over: a crash mid-grant costs you a boat rather than handing out a second one. Rerolling a character does not get you another. - A Gift Is Not A Christening: the free hull arrives already named, and that does not count toward your
boats_christenedstat. You didn't name her. - Hulls Are Paid For In Timber: prices are lists of materials, per hull, set by the server. Vanilla's shop can only count coins, so Njord draws its own — which means no other trader mod on your server is patched or touched.
- Hulls Are Called What The Game Calls Them: names come from each hull's own
Piecetoken, so vanilla's Trailership gets its real name, modded hulls get theirs, and every name arrives translated. - The Shop Wears The VikingOS Frame: the same gilt window chrome as the rest of the suite, shared rather than reproduced — so a frame style changed anywhere changes it here too.
Refits
- Refits (⭐1–⭐4): stand aboard a hull at the harbour — or moor her alongside — and pay 2×, 3×, then 4× her price to raise her. Anyone aboard may pay for it. What a star is worth is entirely the server's business:
Upgrade_Tier2/3/4are lines ofspeed,accel,healthandcargovalues against the hull's base figures, never compounding. Stars show on the helm hover panel and in the HUD. speedRaises The Cap;accelRaises The Boat: if yourMaxSpeed_*values are set above what a hull can physically reach — which is how most servers turn the limiter off — then the cap is not what is holding her back, and thespeedkey does nothing. The tier defaults therefore put the refit's real weight intoaccel, the only key that changes speed on such a server, and which still helps on a default one by reaching the cap sooner. They are larger than they look because drag rises with velocity, so the return is sub-linear: measure them rather than trusting them.- The Panel Quotes m/s, Not Multipliers: the refit tab shows a hull's top speed as
16.8 → 18.8 m/srather thanspeed ×1.12. A multiplier is a claim about how fast she will go, and on a server whose caps are unreachable it is a false one. A hull with no cap at all is told so outright. - A Refit Does Not Heal Or Hurt Her: raising a hull's maximum health scales what she currently has by the same factor, so a battered boat comes out of the yard exactly as battered as she went in — with a bigger hull around it.
- Cargo Rows Are Off By Default: they are the one refit that can destroy your belongings, because an item in a slot that stops existing is gone.
cargois0in every tier out of the box, and Njord never shrinks a hold within a session. Turn it on knowing that lowering it later — or removing Njord — takes those rows away with whatever is in them.
Admin & Data
- Admin commands:
njord.harbour.place,njord.harbour.placeat <x> <y> <z>,njord.harbour.find,njord.harbour.remove(andremove force),njord.harbour.forget,njord.firstboat.revoke <playerID>,njord.whoami. All print to your console, andhelplists them with descriptions. njord.harbour.findDiagnoses An Absence: if there is no harbour it reports the world spawn, whether that zone is loaded on your machine, and whether the shoreline search finds an acceptable site — which separates "the search never ran" from "the search ran and rejected everything". Those two look identical in a log and have completely different fixes.njord.harbour.removeWill Not Orphan Her: it can only destroy a Harbourmaster whose zone is loaded, so when it cannot reach her it keeps the site and says so rather than forgetting where she is.remove forceoverrides that, and tells you what it cost.- Export Schema 5:
speed_recordsandhull_bestsnow carrytier. A refitted hull sails to a raised cap, so a speed and the cap beside it are only meaningful together with the refit that was on her — without the field a ⭐4 Karve's record would read as either a cheat or a lie about the published cap.nullmeans no record exists, never tier 1.
📐 v1.3.5 — The Legible Ledger Update
[!NOTE] Export shape only. No physics, handling or speed changes — every hull sails exactly as it did in 1.3.4.
- Sailor Stats Split By Subject:
barrkbot_sailors.jsonnow carries only distance and time; wrecks and christenings moved tobarrkbot_wrecks.json, and per-hull bests tobarrkbot_hull_bests.json. The reason is row width rather than file size — a reader renders one row per sailor into a fixed budget, so a wide row does not just take up space, it pushes whole people out of the visible roster. - Per-Hull Bests Are Now Flat: One row per sailor-and-hull pairing instead of a map nested under each sailor. Nested objects are stripped from multi-row listings, so the old shape rendered as a list of names carrying nothing rankable — every hull best reachable one sailor at a time and no other way. "Who is fastest on a Karve" is now a question with an answer.
- Rollover (
schema_version: 4): A collection that outgrowsBarrkbot_RowBudgetcontinues intobarrkbot_sailors_2.json,_3, and so on, rather than needing a new Njord release. Because Njord pins ServerSync's minimum version to its own, every release disconnects every player until they update — so "the file got big" should never be a reason to make everyone update. - Split Files Still Rank Correctly: Every part carries the top three per field computed across the whole collection before splitting. A part holding one row of thirteen still names the true overall leader. Ranking within a fragment would report a wrong winner with complete confidence, and the reader is told to trust that figure over anything said earlier — so this is the difference between a split file being safe and being actively misleading.
- No Two Fields Share A Name: A sailor's best on a hull is
personal_best_speed.top_speednow means exactly one thing across every Njord export —speed_records[hull].top_speedinbarrkbot_boats.json, the world record for that hull across everyone. The two are different bases, and one name in two files is a collision a reader cannot see; a name that can't be confused beats a warning telling you not to confuse it. - Stale Parts Are Swept: If the roster shrinks, leftover numbered files are deleted rather than left behind for a reader to treat as live data.
🪶 v1.3.4 — The Saga‑Keeper Update
[!IMPORTANT] The Longship and the Drakkar are now speed‑capped for the first time.
MaxSpeed_Longship(26) andMaxSpeed_Drakkar(30) have existed since Njord shipped but never once applied — crews used to these two hulls will feel them slow down. Server admins may want to warn their players, and can raise both values in the config if the vanilla ceiling isn't wanted.
- Speed Limiter Fix: Njord's per‑ship speed cap matched the hulls players call the Longship and the Drakkar, not the prefabs the game actually uses (
VikingShipandVikingShip_Ashlands). Neither ever resolved, so both boats fell through the limiter entirely and sailed uncapped. Every other hull — Raft, Karve, and all OdinShip / OdinShipPlus ships — was unaffected and keeps the exact behaviour it had. - BarrkBOT Data Export: Njord can now publish what it measures, so a Discord bot, dashboard or status page can answer questions about your fleet. Off by default. Enable
Barrkbot_Enableand the server writesBepInEx/config/Njord/barrkbot_boats.jsonwith a per‑prefab boat census and the top speed each hull type has ever reached, including who was at the helm and the cap in force at the time. Records survive server restarts. - Honest Absence: The export never reports a fabricated zero. A hull missing from the census means none exist, a hull missing from the records means nobody has ever sailed one, and a null cap means none applied — three different facts that a
0would flatten into one wrong one. - Census Is Cheap To Tune: Counting boats sweeps every ship ZDO, so it runs on its own long interval (
Barrkbot_CensusInterval, default 15 minutes) rather than sharing the speed table's cadence. Both intervals are written into the export so a reader labels staleness honestly instead of guessing. - Per-Sailor Stats: The export now also writes
barrkbot_sailors.json— distance sailed, time at the helm, boats wrecked, boats christened, and per-hull bests, for each player. Kept in a second file so a growing roster never costs a reader the boat census. Controlled byBarrkbot_Sailors_Enable, which can be turned off to publish fleet data without naming individuals. - Wrecks Counted Honestly: A shipwreck means a hull destroyed by damage — not one you dismantled with a hammer, and not one that rotted at its mooring. Njord tells those apart, and a hull lost with nobody at the helm is recorded as unattributed rather than blamed on the last person who touched it.
- Distance Measured Once: The odometer accumulates only on the peer that owns the hull, so two players sailing near each other can't both bank the same distance. A mileage leaderboard that quietly rewarded playing in groups would be worse than none.
- OdinShip 0.7.8: Verified against the current prefab list — all seven hulls were already supported, and boats are now discovered by inspection rather than a hardcoded list, so future OdinShip additions are picked up with no Njord update.
⚓ v1.3.3 — The Named Vessel Update
[!IMPORTANT] Fixes a single-player regression where boats slowed to a halt the moment you let go of the rudder.
- Helm Release Fix: Njord now holds the helm binding after you step back from the rudder, matching vanilla — your ship keeps her way until you actually leave the boat. Previously she coasted to a stop as soon as you released the helm. All multiplayer authority handling is unchanged: the helm is still a single, server-tracked binding per ship, so two crewmates can never both claim her.
- Name Your Vessel: Alt + Use at the helm christens your ship. The name is stored on the ship itself, so it persists through logouts and shows up for everyone on the server.
- Named Everywhere: Your vessel's name now appears in the helm hover text, on the crosshair hover label, and at the top of the Njord HUD.
- Taller HUD: The readout panel is one centimetre taller, making room for the vessel name without crowding the rest of the gauges.
🌊 v1.3.2 — The ServerSync & OdinShipPlus Update
[!IMPORTANT] This update migrates Njord to ServerSync for highly stable, server-authoritative configuration locking and syncing.
- ServerSync Migration: Completely replaced custom sync RPCs with ServerSync. Server admins can now reliably lock configuration settings across the entire server.
- OdinShipPlus Support: Seamlessly mapped speed limits and physics logic for all new ships provided by OdinShipPlus (CargoCaravel, Skuldelev, GoblinShip, etc.).
- Multiplayer VFX Fix: Resolved a multiplayer bug that was preventing the runic wake VFX from displaying properly on other clients.
- Config Safety Engine: Re-wrote the configuration backend with strict float clamping, protecting your server against physics-breaking NaN/Infinity values.
🌬️ v1.3.0 — The Wind & Configuration Update
- MAJOR CONFIG OVERHAUL: Completely rebalanced default ship handling physics (acceleration, sails, forces) for a smoother, more realistic feel across all ships.
- Wind System Overhaul: Rebuilt the Njord wind physics system to perfectly blend with Valheim's natural winds. Full Wind Always is now togglable!
- UI Snap Fix: The wind HUD icon now instantly snaps to the correct natural wind angle when you grab the rudder, rather than slowly interpolating from 0.
- Mythic Logs: Improved debug and mythic saga logging consistency.
- Experimental Wind Assists: The
Wind_NoDeadZoneandWind_BlendToFullfeatures have been moved to an opt-in[EXPERIMENTAL]status and are disabled by default. - Grace Period Mechanics: Added a configurable grace period delay (default 2.5s) to the wind assists. Ships will now feel the punishing effects of natural dead zones and crosswinds before the Njord assist systems kick in.
🔧 v1.2.2 — The Configuration Polish Update
- Refined default generated configuration values.
⚓ v1.2.1 — The Authority Fix Update
[!WARNING] Fixed a critical network sync bug that caused boats to occasionally refuse to move.
- Boat control authority tweaks and fixes.
- Network sync bug that caused boats to refuse to move is fully resolved!
⛵ v1.2.0 — The OdinShip Update
- Initial OdinShip support.
- OdinShip prefabs now seamlessly benefit from Njord's advanced physics and custom config generation.
✨ v1.1.0 — The Runic Wake Update
[!NOTE] A visual identity update introducing mythic ship‑trail effects and polishing Njord’s presentation on the open sea.
- Runic Wake VFX (New)
- Optional glowing wake effect behind ships.
- Color‑tinted based on config.
- Scales with speed and sail state.
- Fully multiplayer‑safe.
- HUD & Visual Polish
- Improved wake blending with waterline motion.
- Minor HUD clarity adjustments.
- Better visual consistency across ship types.
🛠️ v1.0.8 — The Deterministic Sea Update
[!TIP] A foundational stability update focused on multiplayer correctness, identity tracking, and predictable helm behavior.
- ZDOID-Based Ship Identity (New Architecture)
- Ships now use Valheim’s true network identity system.
- No HUD flicker, no control loss, no prefab collisions.
- Multiplayer-Safe Helm Control
- Each ship tracks its own controller.
- Identical ships no longer overwrite each other.
- Deterministic Startup & Config Sync
- Movement works instantly — no more F8 ritual.
🚀 v1.0.0 — First Public Release
- Complete overhaul of Valheim ship handling and steering.
- Added steering multiplier system.
- Added acceleration and reverse force tuning.
- Added Half/Full sail force configuration.
- Added wind‑blend smoothing system for natural sail transitions.
- Added Njord HUD with configurable X/Y position.
- Added runtime config reload hotkey (F8).
- Added server‑to‑client config sync for multiplayer.
- Added mythic startup logs and diagnostics.