Longhouse

Longhouse 2.2.0

22 September 2026. After 2.1.2.

Adds Kvedja and Merki, the fifteenth and sixteenth members, and repins Skaft 1.2.0, Core 1.4.0, Vaettir 1.6.2 and Rist 1.6.0.

A minor because the set grew, same as 2.1.0 when it added Jafna. Two members in one release is still one minor, and the four repins ride along rather than going out as a patch of their own.

Kvedja 1.0.0

A line in your chat window when you log in, read from the Longhouse site. It points at the two boards, one for voting on what a mod should do next and one for bugs.

The text is not in the mod. It lives on the site and is edited there, so it changes without an update to install or a server restart. Enabled false and it never asks.

Merki 1.0.0

Everyone is on everyone's map, and the server is the one that decides. The "share position" box is ticked and greyed out, and unticking it is not something a client can do - the server overwrites the flag on its way in, so the box is no longer where the answer is kept.

Your own answer to it is kept as it was, not written over. A server that turns the rule off, or drops the mod, hands everybody back the choice they had made.

When somebody dies, their gravestone appears on the other players' maps at the spot they fell, with their name under it, for up to half an hour. Yours is already pinned by the game, so you are never sent your own. Only the latest death is shown: dying again moves the gravestone rather than adding a second. The server remembers it until it expires, so somebody who logs in ten minutes later to help still gets it, with the time that is left rather than a fresh half hour.

Two settings are off by default and make the map a local thing instead: a range in metres, and same biome only. Both apply to the gravestones as well, so a death out of sight is a death you are not told about.

Nothing is saved. A restarted server has forgotten every gravestone, and your own map drops them when you log out.

The death half is reported by the client that dies, because a server never runs player death code. That is why everybody needs it rather than just the host: somebody playing without it is still on the map, and their deaths go unannounced.

Skaft 1.2.0

The bench half of what the mod already did at the hammer. One press of Repair at a crafting station repairs as many worn items as your Crafting allows: one at level 0, three around 25, seven around 50, ten from 60. Ten is a full kit, so helmet, chest, legs, cape, weapon, shield, bow and the three tools.

Repairs are free in vanilla, no materials, no durability, no stamina, so the skill only affects how many items go in one press. Which items can be repaired is still the game's call, from the recipe, the station and its level. A bench too low for your armour still refuses it.

Skill is granted per item, so ten items in one press raise Crafting by what ten presses would.

Core 1.4.0

A mod can declare the prefabs it puts into the world, and anything can read them back. ZNetScene holds a name and a GameObject, ObjectDB the same for items, ZoneSystem the same for locations, and none of them records who added what, so a failed registration is indistinguishable from a prefab you have not found yet.

Nothing in the pack behaves differently. The development menu is the first thing using it and can now list what each mod put in the world and whether it is there. Mods on the shared registrar declare their names for free, so no member mod changed.

Vaettir 1.6.2

The creel rail's baskets have an inside. They were built as open shells with no thickness, and the game draws one side of a surface and discards the other, so each basket showed the world behind it where its far wall and its floor should have been. Every coil has a wall now, grown inward so the outside of the basket is the shape it always was. The chute post had the same hole and is mended with it.

Eleven warnings on a healthy launch, gone. The rail, the perch, the jib and the post each warned per ingredient that an item "nothing can find" was named in their cost: Fine wood, Iron nails, Leather scraps. They fired while the mod was still checking the price and all resolved a pass later.

ObjectDB.GetItemPrefab goes through a table that is built once and is not ready the instant the item list has something in it, so an early pass misses Fine wood and finds it on the next. Prices are unchanged. A real misspelling in a config line still warns, once, after five tries against a loaded database, and now names the item that was wrong.

Rist 1.6.0

Armour from a runestone is a percentage now. Thick-hided gives +3% armour a rank instead of a flat +2, and its rank 5 carving is another 5% rather than the stagger it used to grant, so a fully carved stone is +20%. Steady footing's carving is +5% armour for the same reason: it has always granted a dose of whatever Thick-hided gives, and no stone hands out flat armour any more.

The flat number was worth less the further you got, which is not what a stone you carve five times should do. Once your armour is at least half the hit, the game works out what you take as damage x damage / (4 x armour), so what reaches you is inversely proportional to your armour rather than reduced by a fixed amount: the old +10 took about a third off a hit at 20 armour and under a tenth off the same hit at 100. It stopped being felt around the Plains, which is where Rattennest raised it on the ideas board.

Ranks already carved are kept and buy the percentage instead. The flat value was better in exactly one place - a hit more than twice your armour, where the game subtracts rather than divides - and there +2 saves 2 damage against +5% of your armour, so it only won below 40.

There is also a rist console command for singleplayer and whoever is hosting, behind devcommands. It prints a character's level, ranks and the armour the game is really using, and can force a stone to a rank. The game's own cheat gate is "am I the server", so a client cannot point it at Longhouse's records.

What moved · 6

Core 1.2.5 → 1.4.0

1.4.0

Added

  • A mod can declare the prefabs it puts into the world, through Suite.Owns, and anything can read them back with Suite.OwnedPrefabs. This is the one fact about a mod that nothing in the game can answer: ZNetScene holds a name and a GameObject, ObjectDB the same for items and ZoneSystem the same for locations, and not one of them has ever recorded who added it. The consequence is worse than it sounds - a mod that failed to register looks exactly like a mod whose piece you have not found yet, and the two want opposite reactions.

    Nothing has to be written to get this. Prefabs.Keep in the shared registrar declares every name it is handed, so the mods using it carry the list without a line of their own; the call is soft in the usual way and a mod running without Core loses the declaration and nothing else.

    Attribution is by the calling assembly's build fingerprint rather than by a guid argument, which is what lets the shared registrar make the call - it is compiled into each mod, so the caller is the mod and there is no guid in scope to pass. Declarations arriving before the mod registers are held and drained at registration, because whether Keep runs above or below the Suite.Register line is an accident of how each plugin was written, and dropping the early ones would have made this work in four mods and silently not in the fifth.

    discuss
1.3.0

Added

  • A server can pick the voice of a chat line it sends. Normal as before, or shout, which the game draws in yellow and in capitals, or whisper, which it dims. The line still goes to one player down their own connection, so a shout here is about how it reads and not about who is sent it. Dyrr's warning before an idle kick is the first thing to use it: a notice that you have two minutes left should not look like somebody saying hello.

    Sent under a second name alongside the existing one, so a server still using the old one keeps working exactly as it did.

    discuss

Kvedja joins at 1.0.0

1.0.0

First release.

When you appear in the world it reads longhouse.thijssensoftware.nl/api/motd and prints what it says into the chat window, one line per line, under a name in orange. Then it stops. It does not repeat, it does not follow you around, and it says nothing at all if the site has nothing to say. By default it stays quiet when you respawn after dying.

It also shows the server's own notices in the chat window - who joined, who left, who died - when the server asks it to. Those come from Crier, which has always known all three and could only ever put them in the top-left corner: a server cannot write to the chat window at all, because the path that gets there looks the speaker up in the connected-player list and a dedicated server has no entry in it. That is the same wall the message of the day is built around, so the same mod answers both. Verified in game on 2026-09-22, leaves and deaths.

Nothing appears unless a server sends it, and only the server is listened to: the line is checked against the server's own connection before it is shown, or any player could put words in everyone else's chat window under the server's name.

The text is not in the DLL. It lives on the site and is edited there, so it changes without an update to install or a server restart, and the same line reaches you in singleplayer, on Longhouse and on somebody else's server. Point Url somewhere else and it is a message of the day for any server that wants one, as long as the far end answers plain text.

Settled since 0.1.0 by running it:

  • The request works from inside the game. The TLS line came from Crier, which makes the trip from a dedicated server, and a client is a different process, so it was a guess until the scenario watched a real fetch land.
  • The timeout is a CancellationTokenSource, not HttpClient.Timeout. Setting that property per request throws InvalidOperationException the second time, because the first request starts the handler. The first login of a session would have worked and every later one would have failed looking like a network fault.
  • The line arrives under its title. kvedja-greets-you-in-chat reads the scrollback for the speaker as well as the address, which tells "the message arrived" apart from "the message arrived without its name on it".

Two things the scenario cannot cover, since a replay starts after both have happened. Watch them by eye the first time:

  • Whether the chat window opens by itself. Adding a line to the buffer does not do it. Chat.Update draws the window only while its hide timer is under the delay, and the incoming-message path resets that timer, not AddString. Kvedja reaches the timer by reflection and zeroes it. If that binding is ever wrong the message sits in the scrollback, invisible, with everything else reporting success.
  • Whether four seconds is the right wait. The first second or two after spawning is the loading screen fading out, and a line printed under it has been said to nobody. The number is a guess at the length of a fade.

Registers with Core's gate at Requirement.HostOnly and marks every setting as yours. A host imposing Url would point your client at an address of its choosing, and Core writes an imposed value into the guest's own cfg, so it would still be there after they disconnected.

Merki joins at 1.0.0

1.0.0

First release.

Run through before it went out, which is worth stating because for most of its life this entry said the opposite. Four scripted tests pass: the forced checkbox and the player's own saved answer surviving underneath it, a death mark crossing from one machine to another with the server's clock on it and expiring by itself, never being handed your own, and the per-recipient player list keeping its shape with a range set. A listen host with a guest on it is the one path nobody has run.

Everyone connected to the server is on everyone's map, and cannot take themselves off it. The checkbox on the map is greyed out rather than left to tick itself back on a frame after you click it, because a checkbox that undoes your click reads as a bug and a greyed one reads as a rule.

Two optional limits on top of that, both off: a range in metres, and same-biome-only. With either set, the server builds a separate player list per recipient instead of broadcasting one - which is the reason they are off by default rather than merely a taste.

Deaths are pinned on the other players' maps, not just the dead player's own, labelled with their name and expiring after thirty minutes. The server passes each death on under the same rule as the map, so a private position sends no mark and Range and SameBiome decide who gets one.

Each player's own answer to the map checkbox is never saved over. The server applies its rule on top, so turning the rule off, or removing the mod, gives everyone back the choice they had made. A client with Merki on a server without it forces nothing and greys out nothing.

Renamed from Beacon to Merki before it ever ran, with the GUID following to ezomic.valheim.merki. Nothing needs carrying over: no config file with the old name was ever written anywhere.

Builds against Valheim 1.0: the per-recipient player list writes the server-assigned display name and the PlayFab id in the order 1.0 reads them.

Death marks are remembered by the server, one per player, so somebody who joins or reconnects after a death still gets the gravestone, for the time that is left rather than a fresh half hour. A second death moves a player's mark instead of adding another, you are never sent your own, and the dead player's name sits under the gravestone on the large map. DeathMarkMinutes now runs from 1 to 30, and the option to keep a mark for the whole session is gone. A server restart forgets every mark.

A second death now also reaches the players who only had the first: if the new spot is out of their Range or biome, the old gravestone is taken off their map instead of staying for up to half an hour. A brand-new character's scope is measured where the valkyrie sets it down, not where the ride starts. Reports and marks travel over each player's own connection to the server, which takes the name from that player's character, so no client can report a death for somebody else or send a gravestone that did not come from the server. Switching DeathMarks or Enabled off now drops the marks the server was holding and the pins already drawn.

Rist 1.5.1 → 1.6.0

1.6.0

Added

  • A rist console command, for singleplayer and for whoever is hosting. rist show prints this character's level, xp, ranks and the armour the game is actually using; rist rank <card> <n> forces a card to that rank. It needs devcommands, and the game's own cheat gate is ZNet.IsServer(), so a client cannot point it at a dedicated server's records. Ranks were otherwise only reachable by clicking the panel, which put five ranks nine skill levels away from anyone balancing a stone.

    discuss

Changed

  • Thick-hided is a percentage now: +3% armour a rank instead of a flat +2, and another 5% at rank 5 in place of the stagger capstone, so a fully carved stone is +20% armour. The game takes dmg * dmg / (4 * armour) once your armour is at least half the hit, so damage taken is inversely proportional to armour and the old flat +10 cut about a third of a hit at 20 armour and under a tenth of it at 100. It stopped mattering around the Plains, which is where Rattennest raised it on the ideas board. A character with ranks in Thick-hided keeps them and those ranks buy the percentage.

    discuss
  • Steady footing's capstone is +5% armour instead of +2. Its capstone has always been a dose of whatever Thick-hided gives per rank, so it follows the change above, and no card grants flat armour now. The one place a flat number was better is the other branch of the curve, a hit bigger than twice your armour, where the game subtracts rather than divides: +2 saves 2 damage there and +5% saves 5% of your armour, so the old value only won below 40 armour.

    discuss

Skaft 1.1.1 → 1.2.0

1.2.0

The bench half of repair. The hammer sweep is untouched.

Added

  • One press of the Repair button at a crafting station now repairs several worn items, and how many is your Crafting skill. One at level 0, two from about 14, three around 25, seven around 50 and ten from 60 - ten being a full kit, which is helmet, chest, legs, cape, weapon, shield, bow and the three tools. So coming back from the swamp is one press at the top of the curve and ten presses at the bottom of it, which is where the game already had you.

    The count is MinItems + (MaxItems - MinItems) * (level / FullLevel)^ItemCurve, floored, read fresh on every press. FullLevel is the same entry the radius uses: one skill, one level at which it has arrived.

    discuss

Why a count, when the sweep charges a price

Because there is no price here to charge. Vanilla asks for no materials, no durability and no stamina to repair an item at a bench - the presses were the whole cost of it, which is why repairing a kit is tedious rather than expensive. A mod that cut a price here would be cutting nothing. So the constraint is the number itself: it starts at vanilla's one, and the skill is what buys it up.

ItemCurve is its own entry rather than the radius's Curve, and it sits above 1 where that one sits below it. A count is a much coarser dial than metres: one more metre of reach is nothing, one more item is the difference between pressing twice and pressing once. Sharing the radius curve would have handed out three items a press at Crafting 10, at a level where the radius is deliberately still worth nothing.

The skill it pays is vanilla's, unchanged

RepairOneItem raises Crafting by how worn the item was, once per item. This repairs items the same way and grants the same amount for each, so nine items in one press raise Crafting by exactly what nine presses raised it by. That matters because Crafting is what buys the count: if the payout had been per press rather than per item, the mod would have been feeding the skill that grants it. It is not. Only the pressing changes.

What it leaves alone

It does not decide which items may be repaired. InventoryGui.CanRepair does, as it always has, which carries the recipe lookup, the repair-station match, the station level and the world level. A bench too low for your armour still refuses it, and refuses it here for the same reason.

It does not fire the station effect once per item, and does not report one item at a time. One press sounds like one press and says Repaired 9 items in the middle of the screen, on vanilla's own $msg_repaired line with a count where the item name goes. Naming one of nine items and putting x9 after it - the trick the sweep uses for a wall repaired thirteen times - would be a lie about which nine things were fixed.

Changed

  • Enabled now means the whole mod rather than only the sweep. RepairItems is the switch that keeps one half and drops the other.

    discuss
  • FullLevel now drives both halves.

    discuss

What has actually been run

All of it, on 22 September 2026, in a live singleplayer world, driven start to finish by a Devkit scenario so that it can be run again: twelve worn crude bows at a roofed workbench, and one press of the Repair button fixed ten at Crafting 60, one at Crafting 0 and three at Crafting 25.

Those three numbers are the point of running it. Any one of them alone is satisfied by several wrong implementations - ten is also what "repair everything" does, one is also what a mod that never ran does - and only the curve produces all three from the same press.

The skill payout is vanilla's, and it showed itself without being asked: the single repair at Crafting 0 had taken Crafting to 1 by the next step, which is RepairOneItem granting exactly what it always granted, with the mod adding nothing of its own.

Not exercised: a dedicated server, a second player, and a station too low for the item being repaired. That last one is vanilla's CanRepair either way, which is why it was left to it.

Vaettir 1.6.1 → 1.6.2

1.6.2

Fixed

  • You could see straight through the creel rail's baskets. Reported from the game with a screenshot: three baskets hanging off the rail, each showing the world behind it where its far wall and its floor should have been.

    The baskets were built as open shells - a surface with no thickness - because a basket is open-mouthed and the shell was what made the mouth. Valheim draws one side of a surface and throws the other away, so the near wall was there and the far wall, seen from behind, was not. Every coil of every basket now has a wall, grown inward so the coil profile keeps the exact outside line it was designed with, and the mouth is closed off rather than left as a zero-thickness edge.

    The same shape had the same hole in the chute post, one of the four plain posts that ship beside the carved one, and it is fixed with it. Nothing else in the mod has an open surface left anywhere.

    Nothing in Blender could have caught this. It draws both sides of everything, so the piece was correct in every render it was ever picked from, correct in the lineup, and wrong the moment it stood in a world. The check that does catch it is counting edges that belong to only one face, and it now runs over every model.

    discuss
  • Eleven warnings on a healthy launch. The rail, the perch, the jib and the post each warned, per ingredient, that an item "nothing can find" was named in their cost - Fine wood, Iron nails, Leather scraps, Silver - while the mod was in the middle of making sure the price was right. Every one of them resolved a pass later, and the log proved it: eleven warnings and not one of the give-up messages that would follow a real failure.

    The cause is the same one 1.6.1 was about, seen from the other side. Pricing is retried from an Update because ObjectDB.GetItemPrefab answers through m_itemByHash, which is built once and is not ready the instant m_items has something in it - so an early pass fails to find Fine wood, of all things, and finds it on the next. Warning at that point is crying wolf on every start, and the launch where it means something then reads exactly like the ten where it did not.

    The missing names are carried to the give-up branch instead, which already existed and is the honest version: it fires only after five passes against a loaded database, and it now names the items rather than saying "something this game does not have". A cfg typo is still reported, once, with the word that was wrong.

    discuss

Discussion

Nothing said yet.

Sign in or make an account to join in.

2.1.2 →