Mods / Universal Display Lib
- Tags:
- Author:
- Calminaion
- Side:
- Both
- Created:
- Jul 25th at 8:58 AM
- Last modified:
- Sep 12th at 5:50 PM
- Downloads:
- 7949
-
Recommended download (for Vintage Story 1.22.0 - 1.22.7):
universaldisplaylib_1.1.3.zip 1-click install
Universal Display Lib
A complete overhaul of Window Storage Lib
Free item placement, stacking, rotation, lighting, particles, animation and block swapping
For any block, not just windows - modders can add their own storage using this Lib
Mark a surface in your shape file and the rest is done for you
Change every setting in game through Integrated Mod Manager, ConfigKit or ConfigLib - none required. Your own settings apply the moment you save; the four server rules are set by the server and shown read-only to everyone else. See Settings below.
A flame sat beside its lamp if the lamp was displayed turned or scaled. It now goes through the same rotation and scale as the item. Update Window Display - Patches to 1.0.5 with this: its oil lamp offsets are written for the new behaviour.
windowdisplaylib to universaldisplaylib. Delete the old zip rather than adding the new one beside it - two libraries claiming the same block classes means neither loads. Update the content mods with it, since they ask for the new id. Server owners: needed on client and server alike. Your worlds are safe - no block codes changed, and everything comes back exactly as you left it.Required Mods
Required
You will also want
The Patches mod is what switches on particles and makes items work that have no display data of their own.
Comes With An Editor
Type .udedit and point at an item on any surface. Set its box size - the footprint that decides where it fits, what it will not overlap and how high the next one stacks - and its display transform, with every change applied live on the block in front of you. Nothing needs to be in your hand, and the finished entry is written out ready to paste into a patch.
shelf - that is the key vanilla reads, so the same size and transform will be used on its own shelves and cases.
Universal Display Editor - .udedit - for boxes and transforms
Universal Display Editor - display-entries output
Features
Free Placement, Not Fixed Slots
- Built on the psurface system vanilla introduced, taken a good deal further than vanilla takes it.
- A surface is one shape element named
psurface0-w16-h16-d7-windowdisplay. Width, height, depth and category all read straight out of the name, and a shape can hold as many as you like. - Items sit on a HALF-voxel grid, centred on the spot you click - 32 positions across a block rather than 16, which is one pixel of a 32×32 texture and the finest step anyone can actually see. On an ordinary window that is 448 places a single item can go. Whole-voxel spacing is a config option if you would rather.
- Item facing comes from the geometry. A surface on the north face turns its items to face north with no JSON at all. Override per surface with
surfaceFacingDegif you need something unusual.
Seeing Where Things Will Land
- Ghost preview. A see-through copy of whatever you are holding, drawn exactly where it will go and turned the way it will be turned. It goes red when it will not fit. Aim at an item already on the sill and it shows the one you would STACK on top, at the angle the pile gives it, with an outline at that level.
- Both outline boxes can be switched off separately - the one showing where the item will land, and the one around an item you are aiming at.
- Press
Bto bring them back for a moment when you want to line something up precisely. It is not saved, so you go back to your normal setup next time. - With the boxes off there is no visible grid at all. It is still a grid underneath, but it stops feeling like one.
- Transparency is configurable, and the whole thing has an off switch if you would rather not have it.
Rotating Things
- Hold Sprint and scroll the mouse wheel. What it turns depends on what you are pointing at - a bare bit of sill turns the item you are about to place, an item already sitting there turns that one. No wrench needed for either.
- Hold Sneak and scroll the mouse wheel to raise or lower an item, in the same split as above - a bare bit of sill nudges the item you are about to place, an item already sitting there nudges that one. Items land at the right height on their own, so this is for the odd one that wants a touch more. It is saved with the item.
- Any angle, not just quarter turns. You set the step size in the config and it governs both held and placed items.
- Turning a long item across the sill instead of along it is often the difference between fitting and not, and the ghost shows you that happen before you commit to it.
- The turned shape is what actually gets used for fitting, stacking and clicking, not just the model you see.
- If a turn would leave an item overlapping its neighbour or hanging off the edge it refuses and says so, rather than letting it happen.
- Placed items get a slight random resting angle so a shelf looks natural rather than perfectly lined up. Turn it off in the config if you want everything square - and it applies to things already placed, not only new ones.
Stacking
- Items stack where the item itself says they can, and every one in a pile keeps its own angle.
- A new item copies the angle of the one you aimed at, so a pile stays consistent without setting it every time. Aim at a different item in the stack and the new one copies that instead.
- That lets you build a stack a layer at a time and turn each one as you go. Stack an ingot, scroll to turn it, stack the next. Crossed and fanned piles all work.
Fine Positioning
- Stacked items rest on what is under them. Each item sits on the declared height of the one BELOW it rather than its own, so a pile of mixed sizes lines up - a plant meets the rim of a flowerpot whatever height that pot is, vanilla or modded.
- Chiselled blocks work as risers. A chiselled block measures its own height from its voxels, so one placed on a surface lifts whatever you stack on it by exactly as much as you cut. Stepped and tiered displays, built in game, with nothing to configure.
- Nudge an item up or down - Sneak and scroll. For the odd item that wants a touch more than the automatic height gives it. Works on the item you are about to place and on one already down, chosen by what is under your crosshair. Saved with the item.
Items Just Work
- Anything already authored for a vanilla shelf displays at its correct size - bowls, crocks, clay pots, moulds, all of vanilla's clutter. No patch needed.
- Resolution order is
displayable.windowdisplay→displayable.shelf→shelvable→windowdisplayable. You only need a patch for items nobody ever authored, or where the vanilla size is wrong for a sill. - An item may name its own display shape, which is how clothing shows neatly folded rather than laid out flat.
- Contained interaction: crocks, bowls and cooking pots can be used in place without picking them up first.
- The info box tells you how fresh stored food is and its temperature, so you can see at a glance whether that meal is still worth eating.
- Fine-tune any item live with the in-game transform editor, under
onUniversalDisplayTransform. It reads and writes the same entry a patch uses, so you can tune by eye and copy the numbers straight out.
Light, Particles & Weather
- Lighting: a lantern, candle or oil lamp on the sill lights the room at its own colour and level, and relights the moment the contents change.
- Particles: candles, lamps and incense keep their flame or smoke while on display, spawned at the item's own position and turning with it. Vanilla shelves and display cases do not do this at all. Set per item with
particleOffset, so only items somebody has actually tuned will emit. - Rain sound: rain on the glass, scaling with real rainfall and fading naturally. One shared sound across every window, so a whole wall of them costs no more than one.
- Food: stored food follows vanilla's spoil rules and rots in place, and the rate responds to whether the window is open or shut.
- Room sealing: an open window stops sealing the room, so windows have to be shut in winter. Turn it off with
RoomSafeOpeningif you would rather not think about it.
Animation & Opening
- Animations can be called anything. Static geometry, animations and surface markers all live in one shape file, split automatically at tesselation by
animatedElements. - Only the elements you name go to the animator. Everything else stays batched into the chunk mesh, which keeps its per-vertex lighting and ambient occlusion and costs nothing per frame. The old mod ran panes through the animator that never moved, which is exactly the wrong way round.
- Any number of independent panes per block, each with its own open and closed boxes.
canOpenmakes a style that stays shut.sealsRoom: falseanimates a pane without touching the open/closed state, for interior doors and display flaps. (WasisWindow; the old name is still read.)- Toggling is resolved server-side and broadcast, so
linkedOpenmoves a stacked window as one piece instead of each segment starting a moment apart. - A swoosh on every toggle, and breaking an open window still drops the normal closed item.
- Every sound is yours to choose. Opening, closing, swapping and rain are all named in the block's own JSON under
displaySounds, so a cabinet need not swoosh like a window. Leave a key out and the library's default is used - except rain, which is off unless a block asks for it.
Frame & Collision Groups
- frameBoxGroups tie an animation to the boxes you click, with
animOpen/animCloseandopenFrameBox/closedFrameBox, plus arrayedstaticFrameBoxesfor parts that never move. - collisionBoxGroups mirror it exactly, with open, closed and static variants, also arrayed. The two are independent, so a block can declare no frame box at all and still collide properly.
- Selection boxes for the item grid are built from the surface marker, so they always match what is actually there.
- The block-breaking crack overlay rotates to match how the block was placed.
Chaining & Swapping
- Stack a window on another and the buried surfaces hide themselves. Opt individual ones back in with
showSurfacesWhenStacked. placeWithandpairedWith: "below"build multi-block windows from a single item. 2-high and 3-high go down together, break together and drop one item. If the space above is blocked it refuses to place rather than half-building.- Block swapping:
wrenchSwapToconverts a placed window into another style or its edge-mounted version with Sprint and a wrench. It understands{variant}placeholders and works across a whole tall stack at once. - Rings longer than two blocks work fine, so you can build a proper cycle. Window Display uses one to mirror left and right windows: left, left edge, right, right edge, back to left.
- It refuses while anything is stored, so nothing is ever lost to a swap.
Controls
You can do all of this with something in your hand. Placing, taking and opening never fight each other.
Right Clickthe frame or pane to open and close the windowRight Clickanywhere on the sill to place the held item thereRight Clicka placed item to take it backSprint + Mouse Wheelon the sill turns the item you are about to placeSprint + Mouse Wheelon a placed item turns that item, either waySprint + Wrench + Right Clickthe frame swaps the window to its next style or edge versionBshows the outline boxes temporarily, whatever your config says. Rebindable
Rotation steps by whatever you set as Slot Rotation Degrees, starting from the item's own resting angle rather than snapping to zero. A pending turn clears once you place the item, or if you switch to something else in your hotbar.
Settings
Settings live in ModConfig/universaldisplaylibconfig.json, and can be changed in game through Integrated Mod Manager (type .imm in chat), ConfigKit (press P, or Mod settings in the pause menu) or ConfigLib. None of them are required, and only one should be installed at a time. Every change applies the moment you save - no relog, no restart.
Client Settings
Yours alone. They change what you see and how your controls feel, never what the server allows.
- Rain Sound Volume: 0 (off) to 10 (loud) - default 5
- Rain Sound Range: 1 to 64 blocks - default 12
- Animation Speed: 1 (very slow) to 5 (very fast) - default 3
- Rotation Step Degrees: 5 to 90 - default 15. How far one turn of the held or placed item goes
- Height Step Voxels: 0.05 to 4 - default 0.25. How far one notch of Sneak + scroll raises or lowers an item
- Placement Jitter: true by default. The slight random resting angle on placed items. False makes everything sit perfectly square
- Placement Ghost: true by default. The see-through preview of the held item
- Placement Ghost Opacity: 1 (barely there) to 10 (solid) - default 5
- Show Placement Box: false by default. The outline showing where the held item will land - for checking a patch, not for play
- Show Placed Item Box: false by default. The outline around an item you are aiming at
Server Settings
Set by the server and pushed to every player; in the settings screen they show read-only unless you are an admin. In singleplayer, that is you.
- Height Limit Voxels: 1 to 16 - default 8. How far an item may be raised or lowered from where it would naturally sit
- Precise Placement: true by default. Half-voxel spots - 32 across a block instead of 16. Set false for whole-voxel spacing. Items already placed on half-voxel spots keep working whichever way it is set
- Allow Item Overlap: false by default. Lets items overlap each other so they can be packed tight, instead of refusing a placement that touches something already there. Stacking is unaffected and items still have to stay on the surface
- Room Safe Opening: false by default. Set true and rooms stay insulated whether windows are open or shut - close every window before switching it on
Known Issues
- A bright light flickers for an instant when the window changes. Placing, taking or turning an item, or opening a pane, makes a lantern on that sill dim for a fraction of a second. This is the game's own lighting rather than the mod - any block change makes it work the light out again from scratch, and how long that takes depends on how bright the source is. A candle does not show it at all. Turning shadows off does not help and there is nothing this mod can reach. Lumos by tehtelev fixes it - it replaces that lighting system, and with it installed the flicker is gone.
- The ghost shows containers without their liquid. A bucket or bowl with something in it previews as the empty vessel. The game cannot upload a filled liquid container's model on its own - it is built for a different rendering path - so the vessel is all there is to draw. The liquid comes back the moment you place it, and the ghost still shows the right position, size and rotation. Food in a bowl is built differently and does show its contents.
- Turning placement jitter off does not change items already placed until that window redraws. Take or place something on it, toggle a pane, or reload the world to apply it everywhere. The angle is worked out live; it is the model that is cached.
- Rebinding Sprint needs a world reload before it takes effect. Until then the old key still works and the tooltip may name the wrong one. This is vanilla - the game copies the mouse click modifiers from your Sneak and Sprint keys once when settings load and does not redo it on a rebind. Vanilla's own cabinet behaves the same way.
- Large items only fit edge windows. Anything deeper than 6 voxels has nowhere valid to sit on an ordinary sill, since items are centred where you click and have to fit entirely inside. Edge windows are twice as deep and take them fine.
Screenshots & GIFs
The ghost preview - the item shown where it will land, red when it will not fit.
Sprint and scroll to turn an item, before or after placing it.
Free placement with the outline boxes turned off.
Sprint and a wrench cycles a window through its styles and edge versions.
Without Lumos.
With Lumos by tehtelev.
For modders - giving an item a display size and transform
Most items need nothing: anything with a vanilla displayable.shelf entry is inherited as is. Patch only when an item has no display data at all, or is too big for a sill. An override replaces vanilla's entry wholesale, so restate behavior if you want stacking.
"displayable": {
"windowdisplay": {
"size": { "width": 3, "height": 4, "length": 3 },
"behavior": "Stacking",
"randYRotAngle": 0,
"particleOffset": { "x": 0, "y": 0, "z": 0 },
"transform": {
"translation": { "x": 0, "y": 0, "z": 0 },
"rotation": { "x": 0, "y": 0, "z": 0 },
"origin": { "x": 0.5, "y": 0, "z": 0.5 },
"scale": 1
}
}
}
size is the footprint in voxels - bounds, collision, selection box and stack pitch. transform is visuals only, and nothing keeps the two in step. Any key here also takes a ByType suffix for per-variant values.
Width and length, and why 6 is the number to remember. An item is centred on the spot you click, so it reaches half its width to each side and half its length front and back, and it has to fit entirely inside the surface. Positions are whole voxels. A main window sill is 16 wide by 7 deep, so a 7-deep item would need to sit at 3.5 and there is nowhere to put it - keep length at 6 or under. Going over is a perfectly good way to make something edge-window only, if that is what you are after.
Height is the stack pitch, so it decides clipping. It is not just how tall the item is allowed to be - it is how far up the next one sits when you stack them. Declare it shorter than the item really renders and copies sink into each other; declare it taller and they float with a gap. If you scale an item down with transform you have to scale size with it or you get exactly that - a clay bowl at scale 0.85 with its original height left a visible gap under every bowl in the pile.
Height is also checked against the surface: anything over 7 is refused outright on the shallower surfaces like the display unit and the pane shelf. That is occasionally worth taking on purpose - the vanilla hammer is declared at 6 against a taller model, which lets it go on those surfaces at the cost of stacked hammers overlapping slightly.
behavior is what allows stacking at all. Set it to "Stacking" and items of that type can be piled on each other. Leave it out and it defaults to no stacking, which catches people out when they override an item that vanilla had already set - the override replaces the whole entry, so if you do not restate it you have quietly turned stacking off.
randYRotAngle is how crooked an item is allowed to sit. It is the full spread of the random resting angle, so the item lands within half of it either way - the default of 30 means anything up to 15 degrees off square in either direction. Set it to 0 and the item always sits perfectly straight, which is what you want for something that is meant to look deliberately placed. A small value like 7 is useful when an item has a front, or when its particleOffset is measured against a particular side - the vanilla oil lamp uses that, so its flame stays on the wick instead of swinging away from it. This is per item and sits underneath the player's config switch, so somebody who has turned jitter off gets square items regardless.
particleOffset is optional and switches on flame or smoke particles for that item, in voxels from the top of its box.
Easiest way to get the numbers: use the in-game editor, in the section below. It writes the finished entry out for you.
For modders - the in-game editor, and your own display surfaces
Type .udedit and point at an item. The window shows that item's box size and its display transform - width, height, length, translation, rotation, origin, scale and flip - and every change applies live to the block in front of you. Nothing needs to be in your hand. It follows whatever you look at until you touch a control, then locks onto that item so an edit cannot be stolen by a drifting crosshair; hold Alt to look around and move to the next one.
There is now a block to tune on. A Display Editor Surface, in the creative inventory, is a plain gridded slab you can stand items on and edit against without needing a window or a finished block in front of you. It uses its own editorsurface category, so what you tune there is written under that key - change it to the category you are targeting when you paste the entry into a patch.
Everything you tune is written to ModConfig/universaldisplaylib/display-entries.txt as a finished entry, ready to paste into a patch - using sizeByType keyed on the item's own variant, so widening it to a whole family is a one-character edit to *. The file is the output; the tuning itself is not saved and lasts until you reload. Nothing in that file is ever read back by the mod, so edit or delete it freely.
Making your own surface. A surface is one element in the block's shape. Draw a cube where you want items to stand and name it - the name IS the configuration, there is no attribute to set:
{
"name": "psurface0-w16-h4-d16-box",
"from": [ 0.0, 10.0, 0.0 ],
"to": [ 16.0, 14.0, 16.0 ]
}
psurface0 surface number, so one block can carry several
w16 h4 d16 how much room items get, in voxels
box the display category - any name you like
Its from corner is where items are measured from, and the w/h/d in the name should match how big you drew it. Then hide it, or players see a solid cube sitting on your block:
"shape": {
"base": "yourmod:block/yourblock",
"ignoreElements": [ "psurface0-w16-h4-d16-box" ]
}
The category is what keeps your data separate. A surface ending -box reads displayable.box off the item, so the same item can sit one way on your block and another on a window or a vanilla shelf, with none of the three overwriting each other. Leave the last segment off and the surface falls back to shelf. Your patches then look like the ones above, under your own key:
"displayable": {
"box": {
"size": { "width": 4, "height": 5, "length": 4 },
"behavior": "Stacking",
"transform": {
"translation": { "x": 0, "y": 0, "z": 0 },
"rotation": { "x": 0, "y": 0, "z": 0 },
"origin": { "x": 0.5, "y": 0, "z": 0.5 },
"scale": 0.85
}
}
}
Items you never patch still work. With no entry for your category, the lib falls back to the item's vanilla displayable.shelf data, then shelvable, and finally a plant's own potted form. So most of the game is displayable on your block before you write a single patch, and you patch only what looks wrong.
The editor follows the same rule: it reads and writes the category of the surface you are pointing at, and the file names that category per item - so you can tune something on a window and something on your own block in one session and paste each into the right place.
For modders - block attribute reference
canOpen- whether panes can be toggled at allframeBoxGroups[]- one per pane:animOpen,animClose,openFrameBox,closedFrameBox,staticFrameBoxes,sealsRoomcollisionBoxGroups[]- the same, for collision. Independent of the frame boxesanimatedElements[]- shape elements the animator drives; everything else stays chunk-batchedwrenchSwapTo- string or array, with{variant}placeholders. Build cycles across blocks, each pointing at the nextplaceWith/pairedWith- multi-block stackslinkedOpen- stacked windows toggle as oneshowSurfacesWhenStacked[]- surfaces that stay usable when stacked. Absent means all hiddenlockChiselledSurfaces[]- surfaces where a chiselled block, once placed, is permanent: it cannot be taken by hand, turned or nudged. Breaking the block still drops it. Only the FIRST one fitted to that surface is fixed, and only chiselled blocks are affected - anything else on the same surface behaves normally, so nobody can jam junk in that the owner has to break the block to clearsurfaceFacingDeg- override the derived item facing, keyed by surface indexnoPlacementJitter- kills the random resting angle for that block, for surfaces holding something the player lined up by handdisplaySounds- name the sounds this block makes:toggle,toggleSolid,swapandrain. Leave a key out and the library’s own default is used - exceptrain, which is silent unless a block asks for it, so a cabinet or a crate never patters like glass. A path with no domain resolves in your own mod, so writegame:for a vanilla sounddropsAs- name the block this one drops, with{variant}substitution
A block with no frame boxes at all still works. Sprint and a wrench will use any box except a placed item, so something fully chiselled or otherwise frameless can still be swapped.
Recommended Mods
A note on how this was made. AI was used in the creation of this mod - in the code, the JSON, and the text on this page (Images were made by me). The design, the decisions and every test in game are mine, and the only game source it was ever pointed at is Vintage Story's public GitHub repositories. If something is wrong, it is mine to fix - report it and I will.
| Mod Version | Mod Identifier | For Game version | Downloads | Released | Changelog | Download | 1-click mod install* |
|---|---|---|---|---|---|---|---|
| 1.1.3 | universaldisplaylib | 2504 | Sep 12th at 5:50 PM | universaldisplaylib_1.1.3.zip | 1-click install | ||
Version 1.1.3A settings screen in game, and flames that stay on their lamps What To UpdateThis and Window Display Patches 1.0.5, together. Patches needs this version - its oil lamp flame positions are written for the new flame behaviour below, and on 1.1.2 they would be wrong Window Display is unchanged and stays at 1.0.4. Nothing to do in your worlds, and nothing to do with your config. Your existing settings are kept Added
Fixed
For Patch Authors
| |||||||
| 1.1.2 | universaldisplaylib | 2863 | Aug 15th at 9:46 PM | universaldisplaylib_1.1.2.zip | 1-click install | ||
Version 1.1.2Clutter on a display surface could corrupt itself everywhere - that is fixed, and the editor understands clutter now What To UpdateThis and Window Display Patches 1.0.3, together. Patches now needs lib 1.1.2 rather than 1.1.1 - its new clutter entries are what triggered the bug below Window Display is unchanged and stays at 1.0.3. It works against this exactly as it is Nothing to do in your worlds. No block codes changed and nothing you have placed is affected Fixed
Changed - The Editor Understands Clutter
Coming from before 1.1.0? The library was renamed from | |||||||
| 1.1.1 | universaldisplaylib | 911 | Aug 9th at 6:25 AM | universaldisplaylib_1.1.1.zip | 1-click install | ||
| |||||||
| 1.1.0 | universaldisplaylib | 439 | Aug 6th at 5:26 PM | universaldisplaylib_1.1.0.zip | 1-click install | ||
|
RENAMED - PLEASE READ BEFORE UPDATING This was Window Display Lib. The mod id has changed from windowdisplaylib to DELETE THE OLD ZIP. Do not simply add this one beside it - two libraries UPDATE ALL THREE MODS TOGETHER. The content mods now ask for the new id, so Server owners: the library is needed on client and server alike, so everyone YOUR WORLDS ARE SAFE. No block codes changed. Placed windows, their contents, Everything below was also in the prepared 1.0.3, which was never uploaded.
- Potted plants on a sill. A plant sits on a window in its potted form, stacked - Placement is twice as precise. Spots are half a voxel apart - 32 across a - Stacked items rest on what is under them. Each item sits on the height of the - Nudge an item up or down with Sneak + scroll, before or after placing, for the - Stacking shows a preview. Aim at an item with another in hand and you see - Every sound is nameable per block - opening, closing, swapping and rain, all - New setting: Allow Item Overlap, off by default. Lets items overlap so they - For patch authors: an in-game editor, .udedit. Point at an item and tune its
- A stutter when closing a window. The pane snapped shut, jumped back open, then - Rotating a stored item no longer plays a sound. It was inaudible to the person | |||||||
| 1.0.2 | windowdisplaylib | 758 | Aug 1st at 9:53 AM | windowdisplaylib_1.0.2.zip | 1-click install | ||
|
Fixed
not just tall ones, so if you run a server this is the one to update for.
Singleplayer was never affected. Both the server and everyone connecting
need 1.0.2. Thanks to Specker for the report.
(Fix is verified in code but not yet on a live server - shout if it persists)
place and writing to another, so edits appeared to do nothing. | |||||||
| 1.0.1 | windowdisplaylib | 117 | Jul 31st at 7:10 PM | windowdisplaylib_1.0.1.zip | 1-click install | ||
|
Features Added
Fixes
Known Issues
| |||||||
| 1.0.0 | windowdisplaylib | 357 | Jul 26th at 8:15 PM | windowdisplaylib_1.0.0.zip | 1-click install | ||
|
Initial Release | |||||||
