Valheim
Install with App

Details

Latest version
0.3.0
Last Updated
First Uploaded
Downloads
127
Likes
0
Size
175KB
Dependants
ADDatHost Valheim hosting
€1

πŸ”­ Dvergr Astrolabe

Valheim Mod Server Side Framework Crossplay Version Valheim 1.0

Daylight and night, in real minutes, set once on the server. No client install, ever.

🏰 Wubarrk lives on Hexium - don't miss out

Dvergr Astrolabe is published here and on valheim.hexium.gg. The rest of the Wubarrk and RavenIron Studios catalogue is Hexium only: that is where the current builds live, every one of them tagged Valheim 1.0. The old copies under the Wubarrk name here on Thunderstore are pre-1.0 lines, most of them deprecated, and they are not kept current. Hexium packages install with one click from the Gale mod manager, or unzip into BepInEx/plugins like any other mod. Here is what you are missing.

Server-side only, nothing on clients - the same family as this mod, so Steam, Xbox, PlayFab and crossplay parties all get it with nothing installed:

  • Wonderland - automation, world governance, status effects and Discord notifications for a server whose players run plain vanilla, with vanilla-client enforcement built in.
  • Get Off My Lawn - active wards keep wild creatures and raids out of your base, and doors inside wards close themselves.
  • TortalPortal LITE - a portal network with progression-gated gates, one-way corpse-run recovery, fast-transit terminals, per-portal ore upgrades and portal caps.

Client and server:

  • Njord - a mythic overhaul of ship handling, steering and seafaring, with a Harbourmaster who gives every new Viking their first hull and refits the rest.
  • Shadows of Midgard - a stealth and perception engine: creatures see, hear, remember and doubt, with vision cones, line of sight, noise, light, weather and camouflage tracked for each player separately.
  • Wings of the Valkyrie - four tiers of upgradable runic dragon wings with real armour and resistances, and a Valkyrie Flight skill that grows with every wingbeat.
  • Fatty - a food overhaul: no stat decay, a bigger food bar with a drink slot, stack the same food for extra stats, and diet-based synergy buffs. Works with any food mod.
  • StackIT - server-synced stack sizes, item weights and carry capacity, plus hold Shift to harvest a whole berry patch.
  • TortalPortal - total portal control: pick destinations from a map UI, with destination photos, PIN locks, tame teleportation, travel filters and a procedural runic gateway.
  • AwayFromHome - build a Keeper Stone and that place keeps living while you are elsewhere: animals fed, smelters reloaded, production that no longer stops on an empty server.
  • Let It Grow - a full farming overhaul: configurable growth speed and conditions, hover grow-timers, and Scarecrow and Farm Silo automation that tends farms nobody is near.
  • RuneboundRest - server-authoritative Rested and Comfort: config-driven comfort, resting conditions and duration, plus a Well Rested buff for a full night in your own claimed bed.
  • Blighted World Heart - a massive raid boss that summons endless waves and unique sub-bosses, dropping dozens of custom weapons and armours with Poison, Spirit and Defense affixes.
  • Dvergr Allies - tame, breed and lead an army of Dvergr: four classes, breeding genetics, star-level weapon scaling and native combat AI.
  • Mists of Avalor - a procedural black-stone crypt-labyrinth in a forsaken sky-realm: true-damage traps, restless dead, keys torn from mutant bosses, and the Avalorian Greatsword off the Warden. Bring a torch.
  • VikingOS (beta) - rebuild the interface: move, resize and rotate any HUD, inventory or chat element in a live edit mode, plus chat that keeps your capitals and drag-and-drop item sharing.

RavenIron Studios:

  • FireFront - fire that actually spreads: structure to structure, into the trees, across open ground. Wind-driven, rain-damped, stopped by water, with burn scars, tree regrowth and fires that remember who lit them.
  • Ragnarok's Wrath - the world reacts and remembers: seasons, devastating storms, spreading plague with visible miasma, fire scars, tiring soil and earned titles.
  • Undertow - the sea gets its own motion: currents in a learnable shape, tides, storm surge and flotsam, carrying whatever floats on them. No HUD.
  • Cairn - stack stones on a headland and they burn: a trail of cairns you build yourself, lit and remembered, for worlds with no map.
  • Valkyries Cargo - a Valkyrie air-drops Ingvar the Far-Travelled, a dwarven merchant, beside your hearth when rested; buy and sell at supply-and-demand prices before he vanishes.
  • The Raven's Call (server-only) - admin and analytics: kills, deaths, bosses, gear and playtime narrated to Discord and Chronicle logs, with a web dashboard. Pairs with WhereTheCrowFlies, the client companion that witnesses and reports the events.
  • RavenEye - for server owners: restores the vanilla map to listed admins only on no-map worlds, with every player pinned. Does nothing for anyone else.

Two are published in both places: Valheim 1.0 Compatibility, the preloader that carries pre-1.0 mods across, and The Eye, the API dump tool for mod developers. Questions, bug reports, the clan: Discord. πŸ—


A vanilla Valheim day is 30 real minutes: 21 of daylight and 9 of night. Dvergr Astrolabe lets the server decide those two numbers - a lazy hour of daylight with a 5-minute night, or a 10-minute day and a 20-minute night for a horror server - and every player sees it with nothing installed on their side. Steam, Xbox, PlayFab and crossplay parties alike, because the server is the only machine that owns the world clock.


βš™οΈ Settings

BepInEx/config/wubarrk.dvergrastrolabe.cfg on the server. Edits are picked up within 5 seconds, no restart. The defaults are vanilla, so installing the mod changes nothing until you set them.

Setting Default What it does
[2 - Day And Night] DayMinutes 21 Real minutes from sunrise to sunset: the whole stretch in which the sun is above the horizon and the game counts as day (the Day N banner fires at its start). 0.5 to 180.
[2 - Day And Night] NightMinutes 9 Real minutes from sunset to sunrise: dusk, the midnight day-counter tick and dawn. 0.5 to 180.
[2 - Day And Night] HoldSchedule true Hold every sunrise and sunset to its scheduled time: after a stretch at vanilla speed (boats), a server hitch or a mid-day config edit, the rest of the segment runs faster or slower to land the boundary on time anyway. Off = each segment runs at its nominal rate and a pause shifts the schedule.
[2 - Day And Night] CatchUpLimit 4 How far from the nominal rate the catch-up may go, as a ratio either side (a 0.525x day may run between 0.131x and 2.1x). Higher absorbs longer pauses at the cost of a visibly faster or slower sun afterwards. 1 = never deviate.
[3 - Client Sync] ClockPushInterval 0.5 Seconds between extra pushes of the clock to clients (vanilla pushes every 2 s). Keeps the sun moving smoothly when the rate is far from 1x. 2 adds no extra traffic.
[4 - Boats] PauseFor Ships Ships = the whole server's clock runs at vanilla speed while any player is near a boat. Water = also while any player is over water. Off = never pause; boats take damage under sail while the schedule is active. Read Boats below before changing it.
[4 - Boats] PauseRadius 64 Metres around each player in which a boat under way pauses the schedule. A sailing player's reported position trails the hull by a couple of seconds, so keep it generous. 8 to 256.
[4 - Boats] MooredRadius 24 The same for a boat at rest. Only someone aboard takes the hits, so this just covers the deck, and a boat docked beside your base does not pause the schedule whenever anyone is home. 4 to 256.
[4 - Boats] UnderWaySpeed 2 Metres per second a boat must be moving, between two checks, to count as under way. A moored hull drifts far slower; a rowed Karve is faster. 0.1 to 20.
[4 - Boats] CheckInterval 0.5 Seconds between boat checks (one cheap sector query per connected player each). The schedule reacts to a boat within this delay. 0.1 to 5.
[5 - Compatibility] BandDetection Auto Where sunrise and sunset fall in the game day. Auto reads them from the running game, so a mod that moves them (Gamma of Night Lights' day/night cycle) is followed and DayMinutes / NightMinutes mean its daylight and night. Vanilla assumes the vanilla knees whatever other mods do. Read Pairing with Gamma of Night Lights below.
[5 - Compatibility] BandProbeSteps 1000 How finely the day is sampled to find that band: sunrise and sunset are located to within 1/steps of a day, and a mod that sets the night in whole percent lands exactly on the grid at 1000. 100 to 10000.
[1 - General] Enabled true Master switch. Off = vanilla 21 + 9.
[1 - General] VerboseLogging false Log every sunrise and sunset with the day number, how long the segment that just ended really ran, and the rate that just took effect; also every pause and resume near boats.

A few starting points:

Feel DayMinutes NightMinutes Full day
Vanilla 21 9 30 min
Long lazy days 45 10 55 min
Builders' server 60 5 65 min
Horror server 10 20 30 min
Quick test 1 1 2 min

πŸ”­ How it works

Every machine in a Valheim game turns one number into the time of day: the world clock, in game-seconds. Only the server advances it, and every 2 seconds it pushes the value to each client, which simply adopts it. Time of day is that clock modulo the day length, 1800 game-seconds: the stretch from 0.15 to 0.85 of each day (1260 seconds) is daylight, the remaining 540 seconds are night. That is where vanilla's 21 + 9 comes from. Astrolabe reads those numbers from the running game rather than assuming them (the day length from EnvMan, the two knees by sampling the function that turns the clock into the sun's position), so a mod that changes them changes what Astrolabe paces; see Pairing with Gamma of Night Lights below.

The server cannot change the 1800 baked into an unmodded client. It can change how fast the clock runs. Astrolabe scales the server's clock tick to 1260 / (DayMinutes x 60) game-seconds per real second while the sun is up and 540 / (NightMinutes x 60) while it is down, switching exactly at sunrise and sunset (a tick that straddles the boundary is split so each side runs at its own rate). A day is still 1800 game-seconds, the clock still only counts up, the world save stores it unchanged. It just takes as long as you said.

Holding the schedule. Those rates are the nominal ones. Each segment also gets a deadline, sunset at sunrise plus DayMinutes and sunrise at sunset plus NightMinutes, and every tick the clock runs at whatever rate still spends the segment's remaining game-seconds inside the remaining time, within CatchUpLimit either side of nominal. While nothing interferes that is exactly the nominal rate. When something does (a stretch at vanilla speed near a boat, a server hitch, a config edit mid-day) the rest of the segment absorbs it and the boundary still lands on time.

Between pushes an unmodded client runs its own copy of the clock at 1x, so each push applies a small correction. The sun and the rendered water smooth it over about 2 seconds; Astrolabe pushes every 0.5 s by default so it stays under a degree of sun movement at any sane setting, at the cost of one tiny packet per client per half second. The water surface that boats are simulated against is not smoothed, whatever the push interval, which is why the schedule pauses near them (see Boats below).


β›΅ Boats: how time works when someone is on the water

The short version. While any player is near a boat, the whole server's clock runs at vanilla speed. The moment nobody is, the schedule takes over again and, by default, makes up the lost ground so sunrise and sunset still land when you scheduled them. Boats never take extra damage. The schedule only slips when boats are in use for more of a segment than it can absorb, and the log tells you when that happens.

Why the pause exists. Between pushes an unmodded client runs its own copy of the clock at vanilla speed and then hard-sets it to the server's value. While the schedule is active every push therefore nudges the client's clock by a fraction of a second. The sun and the rendered water smooth that away, but the water surface that boats are simulated against is computed from the raw clock, so each nudge moves it a few centimetres to a few decimetres in a single physics step. A boat with anyone aboard treats that as a slam and takes vanilla's water-impact damage: 10 per hit, up to thirty hits a minute. That is what 0.1.0 did to a Karve under sail: constant bobbing and 60-150 hull damage a minute. Pushing more often does not help, the check is per physics step. The only clean state while a boat is in use is vanilla speed, where a push carries nothing the client did not already have.

What "near a boat" means. Within PauseRadius (64 m) of a boat that is under way, or MooredRadius (24 m) of one at rest. Every vanilla boat and any modded one counts. A boat is under way when it moved faster than UnderWaySpeed between two checks CheckInterval apart, and positions are checked every half second. A player only takes the hits while aboard, which is why a boat docked beside your base pauses the schedule for someone standing on or right beside it, not for everyone at home.

One clock, one pause. There is one world clock for the whole server, so none of this is per player. The first player near a boat pauses the schedule for everyone, the tenth adds nothing, and it resumes when the last one leaves. A player at a base far from any boat sees the sun move at vanilla speed for as long as somebody else is sailing. Nobody sees a jolt in either direction: changing the rate is continuous.

Catching up. With HoldSchedule on (the default), each segment has a deadline: sunset at sunrise plus DayMinutes, sunrise at sunset plus NightMinutes. After a pause the rest of the segment runs faster or slower, up to CatchUpLimit times the nominal rate either side, so the boundary lands on the deadline anyway. After a ten-minute sail in a 40-minute day the remaining daylight runs at about 0.37x instead of 0.525x, which nobody notices. How much boating a segment can absorb depends on how far it is from vanilla, because boating runs the game clock at vanilla pace and a segment only has so many game-seconds:

Segment Boating it absorbs with the boundary still on time Beyond that
Day 40 min about 18 min sunset comes early by the excess
Day 60 min about 17 min sunset comes early by the excess
Day 120 min about 16 min sunset comes early by the excess
Night 5 min about 4 min sunrise runs late by what the cap cannot close
Night 10 min about 9 min sunrise comes early by the excess
Night 20 min about 8 min sunrise comes early by the excess
Vanilla 21 + 9 everything never: there is nothing to absorb

The rule of thumb: a segment stretched longer than vanilla absorbs a little under its vanilla length of boating (21 minutes for a day, 9 for a night); a segment shortened below vanilla absorbs most of its own length. Raise CatchUpLimit to absorb more at the cost of a stranger-looking sun afterwards. If someone is on a boat for longer than that, the server is simply on vanilla time for the rest of that segment and the next one starts fresh. On a server where a boat is in use around the clock, the schedule never runs. That is the limit of a mod that puts nothing on clients, and you should know it before advertising the lengths.

Reading it in the log. With VerboseLogging on, every pause and resume is logged with who and which boat, and every sunrise and sunset says how long the segment really ran, what was scheduled and how much of it was at vanilla speed:

[Info   :DvergrAstrolabe] schedule paused, clock at vanilla speed: Thorium is 12 m from a Karve under way.
[Info   :DvergrAstrolabe] schedule resumed after 6.5 min at vanilla speed.
[Info   :DvergrAstrolabe] sunset, day 12: daylight ran 40.0 real min (40 scheduled, 6.5 of them at vanilla speed near boats); clock at 0.9x for the next 10 real min.

Other settings. PauseFor = Water also pauses for any player standing or swimming over water (by the world's terrain height, so not raised ground), which spares swimmers, fishing floats and floating items the bobbing at the cost of pausing far more often on a coastal server. PauseFor = Off never pauses; use it only on a world without boats. HoldSchedule = false runs every segment at its nominal rate and lets a pause shift the schedule instead. If the boat lookup ever fails on a future game build the mod logs an error and keeps the clock at vanilla speed until restart rather than risk hulls.


πŸŒ— Pairing with Gamma of Night Lights

Some configurations need two mods, and the pairing is not obvious, so here it is spelled out. The partner is shudnal's Gamma of Night Lights (tested against 1.0.10). Only its [Day night cycle] section matters here: Enabled, Night length (the percentage of the game day that is night, vanilla 30) and Day length in seconds (how long a game day is, vanilla 1800). Its other sections (luminance, fog, sun and moon intensity) are pure lighting and have nothing to do with Astrolabe; the two mods do not conflict anywhere.

The two mods turn different knobs. Astrolabe changes how fast the clock runs and keeps the per-day economy: a crop always takes one day, so a longer day costs more real minutes. Gamma changes how the game day is divided and how big it is, at a flat 1x clock, and keeps the per-real-minute economy: production is vanilla at every instant. The consequence, which is the question that started all of this: with Astrolabe alone you cannot have a flat 1x clock and a night longer than the day. The daylight band is a fixed share of the game day (70% in vanilla), so any unequal real-minute split means an off-1x rate in both segments; the only 30-minute split where both sit at 1x is 21 + 9, which is why vanilla is 21 + 9. A long night with untouched real-time production is Gamma's job, not Astrolabe's.

The formula.

production rate = Day length in seconds (Gamma)  /  ((DayMinutes + NightMinutes) x 60)  (Astrolabe)

Gamma sets the numerator, Astrolabe sets the denominator, and Gamma's Night length sets the split independently of both. For any cycle length you like, Gamma's day length divided by it is your production multiplier. Set Night length to the night's share of your real cycle (NightMinutes / (DayMinutes + NightMinutes), 75 for 45 of 60) and both segments land on that same multiplier, so there is no fast-day, slow-night contrast at all; that is the real point of the pairing. (Any other split still averages to the same multiplier over a full cycle, but day and night then run at different speeds.) All three rows below are a 60-real-minute cycle, 45 of it night:

Production Gamma Day length in seconds Gamma Night length Astrolabe DayMinutes / NightMinutes Detected band (day / night game-s) Both rates
vanilla 1x 3600 75 Astrolabe disabled (or 15 / 45) 900 / 2700 1x
1.5x 5400 75 15 / 45 1350 / 4050 1.5x
2x 7200 75 15 / 45 1800 / 5400 2x

The 1x row needs no Astrolabe at all: Gamma alone already lands a 60-minute cycle at 1x, so do not install it for that. The 1.5x and 2x rows are not expressible by either mod alone.

Order of operations. Set Gamma's Day length in seconds and Night length first, then set Astrolabe's DayMinutes / NightMinutes to the real minutes you want. Astrolabe reads the band Gamma produced; Gamma has no idea Astrolabe exists. It reads it by sampling EnvMan.RescaleDayFraction, which Gamma's EnvMan_RescaleDayFraction_DayNightLength prefix reshapes (its EnvMan_GetMorningStartSec_DayNightLength and EnvMan_SkipToMorning_DayNightLength prefixes move the sleep target the same way, and Astrolabe already follows the sleep skip). This only works with band detection on, [5 - Compatibility] BandDetection = Auto, the default since 0.3.0. On 0.2.1 and earlier Astrolabe assumed the vanilla 0.15 / 0.85 knees, so with Gamma's cycle active every rate was wrong by the band ratio and the segment it treated as the long one was the short one. The one-glance check that the two are cooperating is the day cycle line (and every schedule line) in the log, which prints the detected band: daylight band 900 of 3600 game-s (25%, sunrise and sunset moved by another mod).

The caveat, up front. Astrolabe's whole pitch is that clients install nothing. Gamma's cycle feature does not share that property: it patches EnvMan, which runs on every machine, so it must be installed on the clients too, or the server will think it is night while players still see daylight. The moment you reach for this pairing you have given up the no-client-install property, for Gamma's part of it, not Astrolabe's. Anyone who needs zero client install (Xbox, PlayFab, crossplay parties) is limited to Astrolabe alone and the per-day economy, and that is the recommendation for that case.

Which to use.

  • Clients cannot install anything: Astrolabe alone. Production tracks days, not real minutes.
  • Clients have your pack and you want vanilla real-time production with a different day/night feel: Gamma alone. You do not need Astrolabe.
  • You want a specific total real cycle length and a flat production multiplier: both, per the table.

Any other cycle mod. The detection is not tied to Gamma: whatever patches RescaleDayFraction is followed. The band is re-read every 5 seconds, at every sunrise and sunset and after each config edit, so a change on the other mod's side is picked up within seconds and the rest of the current segment absorbs it the way it absorbs a pause. If detection ever fails on a game build this mod has not seen, it falls back to the vanilla knees and logs an error; BandDetection = Vanilla forces that by hand. A mod that changes the day length alone was always followed.


πŸ“ What changes, and what doesn't

Untouched. Boats: the whole clock runs at vanilla speed while anyone is near one (see Boats), so hulls take no extra damage. The day counter (it ticks at midnight, the Day N banner still appears at sunrise). Sleeping: still allowed from noon, still skips to the next sunrise in 12 real seconds. World saves. The empty-server freeze: with nobody online the clock stops exactly as in vanilla (if you run Let It Grow's time flows while empty, its tick is the scaled one, so the two agree).

Stretch with your day (they run on the game clock). Crops and trees, smelters, kilns and furnaces, cooking stations, fermenters, beehives and sap collectors, fires' fuel, item despawn, berry and pickable respawn, creature spawners, taming hunger, pregnancy and growing up, creature and tame health regeneration, trap and ballista rearm, snow damage. With a 45-minute day these still take exactly as many days as before, which now means more real minutes. With a 1-minute night, monsters regenerate health nine times faster than you are used to while it is dark.

Do not stretch (they run on the wall clock). Raids and random events, Rested, food, comfort. A longer day therefore gets more raids per game day, a shorter one fewer.

Fine print. At very long stretches (a rate under 0.2x: days over 105 minutes or nights over 45) a client-owned fire, beehive or sap collector can occasionally drop a fraction of a second of progress when a clock correction lands mid-tick; lower ClockPushInterval to 0.25 to shrink it further. The log warns you, at startup and after each config edit, when a setting lands at or under that floor, or above the point where one clock push moves the sun more than a degree in a single step (about 11x at the default push interval); the line names the setting and the number to change. The vanilla 10-game-second lockout between two sleep attempts scales with the night rate too.


πŸ“¦ Install

Server side only. Drop DvergrAstrolabe.dll into BepInEx/plugins/ on the dedicated server (for a player-hosted world, on the hosting player's game). Start it once to generate the cfg, set DayMinutes and NightMinutes, done. Nothing goes on clients; if the DLL ends up on a client by accident it does nothing. (A mod that changes the game's own cycle, such as Gamma of Night Lights, is a different matter: see Pairing with Gamma of Night Lights.)

Requires the BepInExPack for Valheim (5.4.2350). Built against the Valheim 1.0 dedicated server.


πŸ§ͺ Checking it works

BepInEx/LogOutput.log on the server, at startup and after every config edit:

[Message:DvergrAstrolabe] schedule (startup): daylight 45 real min at 0.467x, night 10 real min at 0.9x; one full day = 55 real min (30 at vanilla speed); daylight band 1260 of 1800 game-s (70%, vanilla assumed until the world loads); each sunrise and sunset is held to its scheduled time, catching up at up to 4x the nominal rate after a pause; clock pushed to clients every 0.5 s (plus vanilla's 2 s); pauses at vanilla speed while any player is within 64 m of a boat under way or 24 m of one at rest.
[Message:DvergrAstrolabe] day cycle (read from EnvMan): 1800 game-s per day, daylight band 1260 of 1800 game-s (70%, vanilla); daylight runs at 0.467x for 45 real min and night at 0.9x for 10.
[Message:DvergrAstrolabe] clock patch live: EnvMan found, day 12, raw day-fraction 0.412 (daylight), 1 player(s) connected.
[Message:DvergrAstrolabe] boat guard ready: sector query OK (312 objects, 1 boat(s) within a zone of the world origin).

With Gamma of Night Lights at 3600 / 75 and Astrolabe at 15 / 45, the day cycle line shows the band it found and the flat pace that follows from it:

[Message:DvergrAstrolabe] day cycle (read from EnvMan): 3600 game-s per day, daylight band 900 of 3600 game-s (25%, sunrise and sunset moved by another mod); daylight runs at 1x for 15 real min and night at 1x for 45.
[Message:DvergrAstrolabe] note: sunrise and sunset in this world sit at raw day-fraction 0.375 and 0.625 instead of vanilla's 0.15 and 0.85, so another mod shapes the cycle (Gamma of Night Lights' day/night cycle does exactly this) and Astrolabe paces the band it defines. That mod has to be on every client as well, or the night the server paces is not the night players see; Astrolabe itself still needs nothing on clients.

With VerboseLogging on, every transition and every pause as well. The segment lengths are measured, so the log proves the schedule by itself:

[Info   :DvergrAstrolabe] sunset, day 12: daylight ran 45.0 real min (45 scheduled); clock at 0.9x for the next 10 real min.
[Info   :DvergrAstrolabe] schedule paused, clock at vanilla speed: Thorium is 12 m from a Karve under way.
[Info   :DvergrAstrolabe] schedule resumed after 6.5 min at vanilla speed.
[Info   :DvergrAstrolabe] sunrise, day 13: night ran 9.3 real min (10 scheduled, 6.5 of them at vanilla speed near boats); clock at 0.467x for the next 45 real min.

A Valheim mod by Wubarrk.

DatHost β€” Valheim server hosting, first month for one euro
DatHost β€” Valheim server hosting, first month for one euro
DatHost β€” Valheim server hosting, first month for one euro
DatHost β€” Valheim server hosting, first month for one euro
DatHost β€” Valheim server hosting, first month for one euro