⚓ 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
join the Mists of Avalor Open BETA find it only on Hexium
License: MIT — use, modify, and redistribute freely, including commercially; just keep the copyright notice. See LICENSE.md for the full text.