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.
Sinka
Snap points for chests, fences and anything else that will not line up.
| Date uploaded | 2 weeks ago |
| Version | 1.2.0 |
| Download link | Ezomic-Sinka-1.2.0.zip |
| Downloads | 1362 |
| Dependency string | Ezomic-Sinka-1.2.0 |
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
Sinka
Sinka adds snap points to the vanilla pieces that ship without any, mainly chests, fences and stake walls. Place one and the next snaps flush beside it or squarely on top, the same way walls and floors already do.
Named for the dovetail joint. It started as a chest mod and now covers fences too; the name stayed so existing config files keep working.
Features
- Eight snap points, one on each corner of a piece's own measured footprint.
- Fences and stake walls get a ladder of points up each end instead, so a fence line can follow sloping ground.
- A standing torch placed on a pole snaps down into it, centred, with only its head showing above the top. Which torches and which poles is a config list, and how much of the torch still shows is measured off its own fire when you do not say.
Gapis per prefab where you want it to be, so chests can sit flush in the same world where stakes stand a hand apart.- A chest can be set down on top of another chest, which vanilla refuses outright. Read the server warning under Stacking chests before using it on a server.
- Containers are matched by component, so modded chests are covered without naming them.
- Fences are matched by a config list you can extend.
PointOverridestakes exact coordinates for a named prefab when the derived box is wrong.- Optional: snap every buildable piece the game never gave points to.
- Pieces that already have snap points, vanilla or from another mod, are left alone.
- Nothing is added to prefabs you cannot build, so dungeon loot chests and pots stay unsnappable.
How the snapping works
A snap point in Valheim is a child transform tagged snappoint, and that is all the game
needs. While you hold a placement ghost, FindClosestSnapPoints picks the closest pair of
points within 0.5m, one on the ghost and one on a placed piece nearby, then moves the ghost
so the two points become the same point.
That rule is why Sinka uses corners and nothing else. A ghost's left corner landing on a placed chest's right corner is flush adjacency, and a bottom corner landing on a top corner is a clean stack. Mixing corners with face centres would let a chest snap half its own width out of line.
Gap pushes the corners outward by half its value, since both pieces contribute half the
space between them. Gap = 0.1 leaves 10cm between two chained chests.
Footprints are measured at load from collider data, and only from the geometry that will
actually be standing there. A built piece carries its damage states and destruction chunks
in the same prefab, and measuring all of them at once inflates the box: wood_fence comes
out 2.72 x 2.30 x 0.85 that way against a panel of roughly 2.0 x 1.5, which would leave
chained fences standing 0.72m apart.
The fence ladder
Eight corners give a fence two heights to attach at, its base and a full panel up. Neither
helps you run a fence up a hill, so a fence gets points up both ends instead, at mid-depth,
every FenceLadderStep metres, starting FenceLadderBelow metres under its own base so
the next panel can step down as well as up. The rungs run along whichever horizontal axis
of the piece is longer.
The ladder is capped at 24 rungs per piece. A tall piece with a small step hits that cap and logs a warning saying where the ladder stopped.
Torches on poles
Aim a standing torch at the top of a pole and it snaps down into the pole, centred on it, with only its head standing above the top. Build the pole first; the torch goes on afterwards.
What pairs with what is the Sockets setting, one entry per line of pieces:
piece, piece : target, target : metres showing ; next entry
Semicolons separate entries, colons separate an entry's three fields, commas separate names within a field. Out of the box that is the four standing torches and the mist demister, into the seven poles that exist and can be built: wood, core wood, darkwood and ashwood. The dvergr pole is a prefab you cannot place, so it is not among them.
The torch snaps only while the crosshair is on the top face of a pole it is paired with, and only into that pole. Aimed at anything else, a floor, a wall, the side of a pole, the ground beside one, a torch has no snap point at all and places exactly as it does without Sinka. Nothing ever snaps to a torch. Hold the place-without-snapping key to set a torch on a pole top without sinking it.
The snap has to slide the torch down most of its own length, and the game only looks half a metre around the ghost for something to snap to. So for a torch aimed at a pole top, Sinka widens that search to the distance it measures off the torch at load.
How much shows is optional, and better left out. A burning torch spreads fire into a zone around its flame, and sunk deep enough that zone reaches into its own pole, which in the Ashlands burns the pole out from under it. That gives every torch a floor of its own, measured off its own fire, and an entry with no third field uses exactly that: as deep as this torch can go and no further. The wood torch measures 0.21 that way against the 0.25 chosen by eye for it, which is why the three iron ones are left to measure - they come out at 0.32, enough for the bowl and a little shaft. A typed value below the floor is raised to it with a warning in the log, and one past the torch's own length is capped, since a socket below its tip would leave it floating above the pole.
The mist demister is typed at 0.27 instead, because it carries no fire to measure and its ball wants clearing whole.
A target needs snap points of its own, because the highest of them is what the torch lands on. That is what covers a pole of any length without naming its length, and the startup log names any target that has none, is in no build menu, or matches no prefab at all.
Only the wood torch and the two wood poles have been played. The other names come off the game's asset manifest, which lists what is on disk rather than what the game loads, so one may resolve to nothing - it is named in the log at startup if so, and costs nothing else.
Picking a snap point by hand
Q and E cycle the ghost's snap point while you are holding a piece (TabLeft / TabRight
in the keybinds, so they follow a rebind), and the chosen point's name shows in the middle
of the screen. Sinka names its points by position for that reason:
snap_top-front-left for corners, snap_left-y0.60 for a fence rung, snap_into-pole for a
torch, snap_custom1 for a point you supplied through PointOverrides.
Stacking chests
Vanilla refuses a chest on a chest, and no snap point could ever have changed that. Two rules are in the way, both in the game's own code:
- Placing. The placement ghost is invalid whenever the piece you are aiming at has
WearNTear.m_supportsoff. Every chest ships it off, which is the same reason a torch cannot go on a chest either. - Staying. The wear tick reads
if (m_noSupportWear) { UpdateSupport(); if (!HaveSupport()) num = 100f; }, and that 100 is the whole of the piece's health. A chest that ends up unsupported is destroyed with everything inside it. Chests on the ground are safe because terrain hands out full support.
StackContainers answers both, and each as narrowly as it can be. The support flag is turned
on for one frame on the chest you are aiming at, and only while another chest is in hand; and
a chest standing on a chest is counted as supported so the wear tick leaves it alone. A chest
does not become load-bearing: a wall, a beam or a torch on a chest is still refused.
The build-integrity colours still show a stacked chest as unsupported. That is only the colour - the chest is exempt from the wear it usually warns about.
On a server, read this first
Whether a piece is supported is worked out by whichever player's game owns it, and ownership follows whoever is nearby. A player who does not have Sinka works it out the vanilla way, finds a chest standing on nothing, and destroys it with everything in it.
There is no fix for that from here, because the rule runs on their machine and from their copy
of the prefab. A stack is safe in single player, and on a server where every player has this
mod - through a modpack that carries it, for instance. On a server where some players do not,
set StackContainers = false and you lose nothing but the feature.
What gets snapped
A piece has to be something you can actually build. The buildable set is read off the game's
own piece tables, so the Hammer, Hoe, Cultivator and any modded tool with its own table all
contribute and nothing needs listing. Turning BuildablePiecesOnly off drops that filter
and snaps anything with a Piece component, which includes dungeon loot chests and pots.
Past that filter there are three ways in:
- Containers (
SnapContainers, on): anything with both aPieceand aContainer. Ships are excluded. - Fences (
SnapFences, on): the prefab names inFencePrefabs. Nothing about a fence's components distinguishes it from any other wall, so this one needs names. - Everything else with no points of its own (
SnapUnsnappedPieces, off): mostly chests, fences and loose decoration, since walls, floors and beams ship with their own. It also catches chairs, banners and item stands, where snapping tends to get in the way.
ExcludePrefabs wins over all of it, including PointOverrides. Prefab names are matched
case-insensitively everywhere.
Installation
- Install BepInEx 5.4.2350. BepInEx 5 only, not 6.
- Install Sinka from Thunderstore with
a mod manager, or drop
Sinka.dllintoBepInEx\plugins\Sinka\.
No other dependencies. Sinka does not use Longhouse Core.
Snapping happens on the client while you place a piece, so only the players who want it need it. A dedicated server gains nothing from having it installed, and loses nothing either.
Configuration
BepInEx\config\ezomic.valheim.sinka.cfg, written on first run.
| Key | Default | What it does |
|---|---|---|
SnapContainers |
true |
Snap anything buildable that holds items |
SnapFences |
true |
Snap the pieces named in FencePrefabs |
SnapUnsnappedPieces |
false |
Snap every buildable piece with no snap points of its own |
BuildablePiecesOnly |
true |
Only snap pieces that appear in a build menu |
FencePrefabs |
see below | Comma-separated prefab names treated as fences |
ExcludePrefabs |
empty | Comma-separated prefab names to leave alone, whatever else matches |
PointOverrides |
empty | Exact points for named prefabs, replacing anything derived |
Gap |
0 |
Metres left between two chained pieces. 0 is flush; negative values are ignored |
GapOverrides |
empty | Gap for named prefabs, leaving the rest on Gap |
FenceLadderStep |
0.2 |
Vertical spacing of a fence's rungs, in metres. 0 gives fences plain corners |
FenceLadderBelow |
0.2 |
How far under its own base a fence's lowest rung sits, in metres |
SnapSockets |
true |
Sink a piece listed in Sockets into the top of one of its targets |
Sockets |
see below | What sinks into what, and how much of it shows |
StackContainers |
true |
Let a chest be placed on another chest, and stay there. Read the server warning |
Verbose |
false |
Log the measured footprint of every piece that gets points, and the colliders behind it |
SnapSockets and Sockets are in the [Sockets] section, StackContainers in [Stacking],
Verbose in [Diagnostics], and everything else in [Snapping].
FencePrefabs defaults to wood_fence, piece_sharpstakes, piece_stakewall_blackwood, piece_dvergr_sharpstakes, piece_dvergr_stake_wall. Names that match no prefab are listed in
the log at startup.
BepInEx writes every setting to the .cfg on first run, and the saved value beats a new
default in a later version. If a setting looks like it is being ignored, edit the .cfg.
Upgrading from 1.1.0: Sockets replaces SnapTorchesToPoles, TorchPrefabs,
PolePrefabs and TorchStickOut. Those four are left behind under a [Torches] section in
a config file an older version wrote, where they now do nothing. Deleting that section is
tidiness rather than repair, and a torch depth you had tuned needs writing into the Sockets
entry to keep it.
Sockets
Sockets = piece_groundtorch_wood : wood_pole, wood_pole2 : 0.25 ; piece_groundtorch, piece_groundtorch_blue : wood_pole
Semicolons separate entries, colons separate an entry's three fields, and commas separate names within a field. The third field is metres of the piece left showing above its target, and leaving it out measures the deepest this piece can sink without its own fire reaching the pole. Decimals must use a dot. A malformed entry is reported in the log and dropped, and the rest of the config still loads; a depth that does not parse costs only the depth, and that entry measures instead.
Naming a piece twice is the later entry winning. See Torches on poles for what the pairing actually does and what the defaults are.
GapOverrides
GapOverrides = piece_chest_wood: 0 ; piece_sharpstakes: 0.15
One Gap for everything makes "chests flush" and "stakes a hand apart" the same decision.
Semicolons separate prefabs and a colon follows the name, as in PointOverrides. A prefab
with no entry uses Gap, negative values are ignored, and a name that matches no prefab is
reported in the log at startup.
Because snapping makes two points coincide, each piece contributes half the space between them - so two different pieces chained together meet at the average of their two gaps.
PointOverrides
One axis-aligned box cannot describe an L-shape or a piece whose geometry sits off centre.
piece_dvergr_sharpstakes measures 2.40 x 1.70 x 3.94 centred 0.35 off in x, so the corners
of its box are nowhere near the actual stakes. PointOverrides replaces the derived points
with exact ones:
PointOverrides = piece_dvergr_sharpstakes: -0.5,0,2 | -0.5,0,-2 ; wooden_fence_1_gate: -2.4,0,0 | -2.4,1.17,0
Semicolons separate prefabs, a colon follows the prefab name, pipes separate points, and commas separate the three local coordinates of one point. Decimals must use a dot, because a comma already means something here.
Naming a prefab is enough to get it snapped: it does not also have to be a container or a
listed fence, and it skips the buildable filter. Gap and the fence ladder do not apply,
since a point given by hand is used exactly as written. A malformed entry is reported in the
log and dropped, and the rest of the config still loads.
Multiplayer
Snap points are added to prefabs in your own game, nothing is sent over the network, and world data is unaffected. A player without Sinka sees the pieces exactly where you placed them, they just have more work to do lining up their own.
StackContainers is the exception, and it is not a small one. Support is worked out by
whoever owns a piece, ownership follows whoever is nearby, and a player without Sinka
destroys a stacked chest and its contents. See Stacking chests. Everything
else here stays entirely on your own machine.
Sinka does not register with Longhouse Core's version check, so nothing tells you when two players are running different builds of it. In practice that only shows up as one player finding a piece harder to align than the other did.
Compatibility
Sinka skips any piece that already has snap points, so it will not fight another mod for the same prefab, but whichever one registers first wins and the order is not something you control. Do not run it alongside other mods that add snap points to prefabs:
- FenceSnap by MSchmoecker
- ChestSnap by Frogger
- Extra Snap Points Made Easy by Searica
Extra Snap Points Made Easy is much broader than this mod: manual point cycling with keybinds, grid snapping, and points derived per piece shape across beams, triangles, rectangles and roofs. If you want the whole toolbox rather than chests and fences that line up, use that instead.
These work alongside Sinka, because they do not touch prefabs:
- Snap Points Made Easy by MathiasDecrock cycles the points a piece already has, with separate keys for the ghost's point and the target's. It adds none of its own, so Sinka supplies the points and it picks between them.
- PrecisePlacement, originally by Koosemose and re-uploaded by AcidWerks, now marked deprecated. Free rotation, arrow-key nudging, and copying a targeted piece's rotation and position onto the one you are holding.
Troubleshooting
A piece snaps at the wrong distance. Set Verbose = true and restart. Every piece that
gets points logs its measured footprint followed by the colliders it was measured from, so
you can see which collider is inflating the box. If the box cannot describe the piece, give
it exact points through PointOverrides.
A fence name in the config does nothing. Check the startup log for a
FencePrefabs names that match no prefab warning. The same check runs on PointOverrides,
GapOverrides and both halves of Sockets, and a listed target with no snap points or no
place in a build menu gets a warning of its own.
A torch will not snap into a pole. The pole has to be a target of that torch's own
Sockets entry - a pole paired with a different torch is not enough. The startup log lists
every socket and how far it ends up showing; with Verbose = true it also names each socket's
height and how far it reaches.
A torch sinks too far, or not far enough. Give its entry a third field. With none, the depth is the deepest its own fire allows, which is the safe answer rather than the pretty one.
A piece snaps while I place it, but nothing will snap to it afterwards. The game finds
nearby pieces with a search limited to the piece and piece_nonsolid layers, and a piece
whose colliders sit elsewhere is invisible to it. Sinka lists these in one warning at
startup. Rewriting another mod's or the game's colliders onto a different layer changes what
they collide with, so Sinka reports it rather than fixing it.
"No piece tables found after 900 frames". The buildable filter could not be built, so
Sinka fell back to snapping anything with a Piece component, loot chests and pots
included. Usually means another mod delayed or replaced ObjectDB.
Snap points did not appear at all. They are added to prefabs when the scene loads, so
a config change needs a restart to the main menu at minimum. Check the startup line reading
Added snap points to N piece(s).
Bug reports
Post in the Discord or open an issue at github.com/Ezomic/valheim-sinka. Useful to include:
BepInEx\LogOutput.log, ideally withVerbose = true.- Your
ezomic.valheim.sinka.cfg. - The prefab name of the piece involved. The log lines from
Verbosegive you these. - Whether you were in single player or on a server, and any other snapping or building mods installed.
Discord
The Discord is where mod information, updates, support, bug reports and compatibility questions go.
There's also a small EU server running the Longhouse pack if you want somewhere to play. Details are in the Discord.
Building
dotnet build
Targets net462 and references the game's managed DLLs from the default Steam path. Output
deploys to the repo-local testprofile\; override with -p:ProfileDir=..., or build it into
the shared play profile with own-profile\build-all.ps1.
Design notes
How the corner set is derived, why face centres were left out, what the measured footprint has to exclude, and why the one-way pieces are reported rather than fixed: DESIGN.md.
Credit where it is due: the fence ladder is MSchmoecker's idea, from FenceSnap. Sinka derives
its rungs from the measured footprint instead of hand-placing them, which is how a modded
fence gets the same treatment from one config entry. FenceSnap's hand-tuned numbers are also
what caught a measuring bug here, since it puts wood_fence points at x = 1.0 where Sinka's
inflated box said 1.36.
Author
Sinka is an original mod by Robbin Thijssen (Thijssen Software). Copyright (c) 2026 Robbin
Thijssen. MIT licensed, see LICENSE.
Part of Longhouse
Sinka ships in the Longhouse modpack, which pins the exact versions of the Ezomic mods used on the Ezomic setup. It behaves exactly the same installed on its own.
CHANGELOG
Changelog
Notable changes to Sinka. Format follows Keep a Changelog, and the mod uses semantic versioning.
[1.2.0] - 2026-09-20
Added
-
A chest can be set down on top of another chest (
StackContainers, on). Vanilla refuses this outright and no snap point could ever have changed it, because two separate rules are in the way.Player.UpdatePlacementGhostmarks the ghost invalid whenever the piece you are aiming at hasWearNTear.m_supportsoff, which every chest does - the same reason a torch cannot go on a chest. AndWearNTear.UpdateWearrunsif (m_noSupportWear) { UpdateSupport(); if (!HaveSupport()) num = 100f; }, where 100 is the whole of the piece's health: a chest that ends up unsupported is destroyed with its contents. The field name reads backwards; it means "no support, wear". -
Both are answered as narrowly as they can be. The support flag is lent to the chest you are aiming at for exactly one frame, and only while another chest is in hand, so every other placement test still runs unchanged. And a chest standing on a chest is counted as supported, rather than made to carry real support, so a chest never becomes load-bearing - a wall, a beam or a torch on a chest is still refused, which is vanilla's answer and not a limit of this. The integrity colours still paint a stacked chest as unsupported, which is cosmetic.
-
Tested in game, both halves: a chest places on top of another chest, and it is still there with its contents after leaving the area and coming back. That second half is the one worth proving - placement only needs the ghost to go green, while the wear tick is the path that would have destroyed the chest.
-
On a server this can destroy a chest. Support is worked out by whichever player's game owns the piece, and ownership follows whoever is nearby, so a player without Sinka finds a chest standing on nothing and destroys it with everything in it. Nothing client-side can prevent that. Safe in single player and on a server where everyone has the mod; on a mixed server, turn it off. It ships on, with the warning next to the setting and in the README.
-
Sockets: what sinks into what, and how much of it shows. One entry per line of pieces,piece, piece : target, target : metres showing, and it replacesSnapTorchesToPoles,TorchPrefabs,PolePrefabsandTorchStickOut. Those four could describe exactly one pairing - every listed torch into every listed pole at one shared depth - and depth is the part that cannot be shared, since a torch's length and the height of its own fire are its own. They are left behind under[Torches]in a config file an older version wrote, where they do nothing. -
Every standing torch, into seven poles, out of the box: the wood one, the three iron ones and the mist demister, into wood, core wood, darkwood and ashwood poles. 1.1.0 shipped one torch and two poles. Only the wood torch and the two wood poles have been played; the rest of the names come off the game's asset manifest, which lists what is on disk rather than what the game loads, so one may resolve to nothing and be named in the log at startup.
-
A depth left out of an entry is measured off the piece, not defaulted: as deep as it can sink while the zone its fire spreads into stays clear of its own pole. That floor was already being computed to catch a value set too low; it turns out to be the right number to use when nobody has chosen one. On the wood torch it measures 0.21 against the 0.25 picked by eye, and two independent answers agreeing within a centimetre is why the three iron torches are left to measure - they come out at 0.32, clearing a bowl that sits 0.671 to 0.823 above the pivot. A piece with no
Fireplaceborrows the wood torch's 0.25, which is why the mist demister is typed at 0.27 instead: it has no fire to measure and its ball runs 0.283 to 0.515 under a mesh top of 0.549. -
A pairing is now per entry. A torch aimed at a pole somebody paired with a different torch comes away with nothing, where one shared pole list could not tell the two apart.
-
Tested in game: a standing iron torch sinks into a wood pole at its measured 0.32, bowl clear of the pole, and the pole tiers past wood take a torch the same way. The wood torch is unchanged at the 0.25 it released with.
-
GapOverrides,Gapper prefab. One number for everything made "chests flush" and "stakes a hand apart" the same decision. Same punctuation asPointOverrides, and a prefab with no entry still usesGap. Two pieces of the same kind meet at exactly that gap; two different kinds meet at the average of theirs, because each piece contributes half. Tested in game atpiece_sharpstakes: 0.3: stakes chain a hand apart while chests stay flush. -
Verbosenames the gap each piece got, including when it is the sharedGap. A gap that looks like it did nothing had nothing to check against - the corner positions never appear in the log, and the footprint line reads the same whatever the gap is. -
The startup log now lists every socket and how far it ends up showing, which for a measured depth is written down nowhere else, and
GapOverridesjoins the names-that-match-no-prefab check.
Fixed
- Sharp stakes could not be chained at all, and the reason was a footprint measured from
the wrong thing.
piece_sharpstakeskeeps its colliders as direct children of the root and givesNewnothing but an LODGroup and meshes, so the collider search - which starts atWearNTear.m_newto keep damage states out - came away empty and fell through to mesh bounds. Those include the stakes leaning out in +z, so the piece measured 2.67 deep against 2.40 wide. Deeper than it is wide means the ladder ran along z, which put its rungs on the panel's front and back faces instead of its two ends, and no two panels could ever meet.piece_dvergr_sharpstakesdid the same at 3.81 deep. - The search now widens to the whole prefab before giving up on colliders, cutting out
m_worn,m_brokenandm_fragmentRootsby askingWearNTearfor them rather than by where the search started. What makes that safe is a layer filter: onlypieceandpiece_nonsolid, the layers the game's own snap search looks on, so a hitbox, a pathfinding blocker or an effect area cannot stand in for the piece. This piece'sHIT AREAis an Aoe box a metre and a half behind it and is exactly the collider that would have replaced one wrong answer with another. - A footprint that ends up measured from meshes now says so under
Verbose. It printed nothing at all before, which is what made this take a rip to find: the log showed a wrong box with no collider lines above it and no explanation of where it came from. - Four pieces change how they chain, because they were on that mesh fallback and are now
measured from their colliders, which is what this has always meant to do. Read off the game
at load:
piece_chest_blackmetal2.31 x 1.04 x 1.52 becomes 2.06 x 0.92 x 1.35,piece_chest_grausten1.72 x 1.18 x 1.22 becomes 1.31 x 0.72 x 1.13,piece_chest_warderobe1.68 x 2.68 x 1.11 becomes 1.35 x 2.09 x 0.85, andpiece_sharpstakes2.40 x 1.56 x 2.67 becomes 1.80 x 0.84 x 1.51. Each chains tighter than it did in 1.1.0.piece_chest,piece_chest_wood,piece_chest_privateandpiece_chest_barrelare untouched - they already measured from colliders. Checked in game afterwards: the tighter boxes chain without the meshes running into each other, which was the risk of trusting a collider that sits inside what you can see. - Tested in game:
piece_sharpstakesnow measures 1.80 x 0.84 x 1.51 with a ladder of 6 along x, and two panels chain end to end.piece_dvergr_sharpstakesmoved from mesh guesswork to its real collider box, 2.40 x 1.70 x 3.94 centred 0.35 off in x - the numbers this file has quoted since 1.0.0 - and keeps its ladder along z, which is the axis it genuinely runs on.
Changed
TorchPolesis nowSocketPoints, since the mechanism is "a piece sinks into another piece" and only the config names torches and poles. No behaviour rides on the rename.
[1.1.0] - 2026-09-15
Added
- Torches on poles. A standing wood torch aimed at the top of a wood pole snaps down into
it, centred, with its top
TorchStickOutmetres (0.25) standing above the pole. The torch snaps only while aimed at a pole's top face, and aimed anywhere else it has no snap point, so a torch on a floor is placed exactly as before. Because the snap slides the torch most of its own length, the game's half-metre snap search is widened for that one case to a reach measured off the torch at load.TorchStickOutnever goes below the point where the torch's fire-spread zone would reach its own pole. New[Torches]section:SnapTorchesToPoles,TorchPrefabs,PolePrefabs,TorchStickOut. Tested in game on 1m and 2m poles.
[1.0.1] - 2026-09-12
Changed
- Rewritten README. Same mod, clearer documentation: what it does and how to install it come first, then configuration, multiplayer behaviour, compatibility and troubleshooting. Every config table was checked against the plugin's own Config.Bind calls, so the settings, sections and defaults listed are the ones actually bound. No code changed in this release.
[1.0.0] - 2026-08-27
The 0.9.0 build, proven in play and given its release number - chests snap flush beside and atop each other, fences ladder up hillsides, and world-spawned loot stays unsnappable. Renamed from Dovetail on the way: Sinka is the dovetail joint itself in the Scandinavian tongues, beside the pack's other Old Norse names. Nothing was published under the old name, so nothing breaks.
[Unreleased]
Changed
- Core is gone entirely. Sinka no longer references Core, declares it as a soft dependency, or registers with its version gate. It was already optional; now it is absent. Nothing here has to agree with anything running elsewhere, which is what lets this be played and versioned on its own. The gate is what is given up: nothing reports two ends running different builds of it.
Fixed
- The measured footprint was too big, and fences paid for it. A prefab carries its
damage states and destruction chunks inside itself (
WearNTear.m_new,m_worn,m_broken,m_fragmentRoots), and every collider in all of them was being measured as one box.wood_fencecame out 2.72 × 2.30 × 0.85 against a panel roughly 2.0 × 1.5, so two chained fences would have stood 0.72m apart, the exact thing this mod exists to prevent. The footprint now starts atWearNTear.m_new, skips subtrees switched off viaactiveSelf, and skips colliders on their own rigidbody the wayWearNTear.SetupCollidersdoes. - Credit for catching it goes to MSchmoecker's FenceSnap, whose hand-placed
wood_fencepoints sit at x = ±1.0 against the ±1.36 measured here. Two sources disagreeing is what made it findable without building a fence first.
Added
- Only buildable pieces are snapped (
BuildablePiecesOnly, on). Having aPiececomponent is not the same as being placeable: 35 of the 46 prefabs previously snapped were dungeon loot chests, pots and other things you cannot build. Snap points work both ways, so a chest carried into a crypt snapped to the loot chests standing there. The set is read off the game's own piece tables viaItemDrop.m_itemData.m_shared.m_buildPieces, so every tool including modded ones contributes and nothing needs naming. PointOverrides, exact points for named prefabs. One axis-aligned box cannot describe an L-shape or an off-centre piece, andpiece_dvergr_sharpstakesis the proof at 2.40 × 1.70 × 3.94 centred 0.35 off in x. Both earlier mods needed per-prefab data too: FenceSnap hand-places its gate points and ChestSnap keeps a YAML file of them. Naming a prefab is enough to get it snapped and skips the buildable filter,ExcludePrefabsstill wins, andGapand the ladder do not apply to a point given by hand.- A warning for pieces that can only snap one way.
FindClosestSnapPointstakes the ghost's own points straight off the piece being placed, but finds neighbours throughLayerMask.GetMask("piece", "piece_nonsolid"). A piece whose colliders sit on another layer therefore snaps fine while you place it, and cannot be snapped to once it stands. Six vanilla prefabs are like this, the three gifts and the three pots, so it is one line at startup rather than one per piece. ChestSnap and FenceSnap both rewrite such colliders onto the piece layer; this deliberately does not, because that changes what they collide with and the piece belongs to whoever shipped it. It says so instead. - A ladder of snap points up each end of a fence, so a fence line can follow sloping
ground. Eight corners give a fence two heights to attach at, its base and a full panel up,
and a hill needs the heights in between. Rungs run every
FenceLadderStepmetres (default 0.2) fromFenceLadderBelowunder its base (default 0.2) to its top, at mid-depth on both ends, along whichever horizontal axis is longer. - This is FenceSnap's idea, taken deliberately. The difference is that the rungs come
off the measured footprint rather than being typed in per prefab, so a modded fence is one
config entry rather than a code change.
FenceLadderStep = 0restores plain corners. - It knowingly gives up the uniform point set: a fence rung and a chest corner can now pair and land half a piece out of line. Fences are opt-in by name, which contains it, and FenceSnap made the same call.
Verbosenow names every collider a footprint was measured from, not just the result. Finding which collider inflates a box previously took a rip.- Applying is now tracked per world rather than per process. It keyed off a static bool,
which answers yes for the rest of the session once set, while logging out to the menu and
back in tears down
ZNetSceneand builds a new one. That is the failure CLAUDE.md records as having silently destroyed a built piece elsewhere, and the fix is the same: ask the world, do not answer from a field. If prefab assets do keep their points across a reload the second pass simply finds them under "already had their own", and the log now says which happened.
[0.9.0] - 2026-08-16
Not released yet. Everything below is written, deployed and confirmed loading, but the snapping has only been loaded and not yet played. The version stays under 1.0 until it has, and 1.0.0 will be the release.
Snapping
- Chests and fences line up. Place one and the next snaps flush beside it or squarely on top, with no nudging and no gaps you find after the wall is built.
- Each piece's own footprint is measured at load and given a snap point on all eight corners of it.
- Corners rather than face centres, and the set is deliberately uniform. The game snaps by making the closest pair of points coincide, so a corner meeting a corner is flush adjacency and a corner meeting a face centre would put a piece half its own length out of line.
Gappushes the corners outward by half its value, because each of the two pieces contributes half the space between them. Insetting them, which is the intuitive reading, makes pieces overlap by exactly the same arithmetic.
What gets snapped
- Containers, matched on components rather than names: anything with both a
Pieceand aContainer. Modded chests are covered without a list to maintain. Ships are excluded. - Fences, matched by name, because nothing about a fence's components distinguishes it from any other wall. The list is config rather than code, and any configured name matching no prefab is reported in the log at startup rather than silently doing nothing.
- Everything the developers never gave snap points to, off by default. That set is mostly chests, fences and loose decoration, but it also catches chairs, banners and item stands, where snapping fights you rather than helps.
- Pieces that already have snap points of their own are always left alone.
Correctness
- Footprints are read from collider data rather than from
Collider.bounds. Prefabs sit inactive inZNetScene, where world-space bounds have never been computed and read as zero, exactly when they are wanted. - Loads on dedicated servers.
- Core is optional. Installed, it is used: the mod joins Core's version gate, which compares mod versions and build ids on connect and refuses a client that disagrees. That matters here because this adds child transforms to shared prefabs. Absent, nothing is degraded and the mod runs standalone, so installing Sinka no longer pulls Core in with it. A hard dependency would have been worse than no gate at all, since a missing hard dependency means the plugin never loads.
Naming
Named for chests because that is where it started. It now covers fences and stake walls too, and the name stays so existing configs keep working.