Fixed repeated Player.UpdatePlacementGhost null-reference errors when AAABuildMenu search or filters produced no results after a piece had already been selected. AAABuildMenu left the old placement ghost alive while its selected prefab became null.
AAABuildMenu filter reconciliation now runs for the local player's real build table whether or not the extended editor is active. It removes stale ghosts when the filtered selection is empty or special, recreates a missing or mismatched ghost when a normal selection returns, and leaves an already matching ghost untouched so its pose is preserved.
The fix remains event-driven on AAABuildMenu's filter application; it adds no polling, per-frame reflection, physics queries or collection allocations.
0.3.13
Shift now moves an X/Y/Z translation arrow in increments equal to the projected span between the piece's outer vanilla snap points. If that axis has fewer than two distinct snap-point positions, it automatically falls back to the projected visual bounds.
The configurable Hotkeys / Bounds step modifier (LeftControl by default) independently forces projected-bounds increments while an X/Y/Z arrow is dragged; Shift is not required. Rotation remains unchanged: Shift still selects 90° increments.
Existing custom values from the 0.3.12 Snap-point step modifier setting are migrated to the renamed bounds modifier and the obsolete key is removed. Both step sizes remain cached once per drag with no per-frame snap-point scans, physics queries or collection allocations.
0.3.12
Added snap-point translation increments. Hold Shift together with the configurable Hotkeys / Snap-point step modifier (LeftControl by default) while dragging an X/Y/Z arrow to move by the projected span between the piece's outer vanilla snap points.
Pieces with no snap points, a single point or only one distinct point position along the selected axis automatically fall back to the existing projected-bounds step. Shift alone remains unchanged, and rotation still uses 90° while Shift is held.
Bounds and snap-point spans are calculated once when an axis drag begins. The implementation reuses the existing snap-point list, performs no physics queries, sorting or per-frame collection work, and reserves a remapped modifier through the editor input firewall.
0.3.11
Holding Shift while rotating temporarily changes the step to 90°. Holding it while dragging X/Y/Z moves the ghost in increments equal to the piece's projected size along the selected world or local axis; geometry size is calculated once when the drag begins.
The centre translation handle is 35×35 pixels by default and configurable through Visuals / Center handle size from 10 to 100 px. Any LMB press over the gizmo reserves placement input before dragging begins, preventing accidental construction from a single centre click.
Translation arrows are 15% longer. Rotation rings show only their camera-facing halves, remain visible through the ghost, use identical geometry for rendering and hit-testing, and draw the active axis last.
Added the configurable Hotkeys / Toggle camera ray follow action (T by default). It continuously places the ghost on the surface or vanilla build point under the camera centre even when regular surface snapping is disabled. Pressing it again freezes the exact pose; Reset to ray disables the mode. Changing G while follow is active immediately recalculates its snapped pivot. Idle updates are gated by actual ray/state changes, and placing a piece no longer pulls the next ghost onto the newly built geometry.
Added optional AAABuildMenu 1.0.1 integration without a hard dependency. It activates only when AAABuildMenu is installed, preserves its search and filters, allows exact sampling of an available piece hidden by the current view—including pieces from another category—and performs a complete selection/list/ghost rollback if reconciliation fails. Empty search results also clear a stale placement ghost.
All new hotkeys participate in the extended-mode input firewall. Per-frame paths add no reflection, LINQ queries or managed arrays; surface following reuses the existing non-allocating physics buffers.
0.3.10
Reduced the center square of the translation gizmo to exactly 25×25 pixels. Its visual size still matches its mouse hit area; axis arrows and rotation rings are unchanged.
0.3.9
Changed the default entry hotkey to B. If a construction hammer is in any inventory slot, Build Ease equips it through Valheim's vanilla flow and enters extended mode; a hammer already held is not toggled again. An unchanged legacy KeypadEnter binding is migrated to B once, while custom bindings are preserved.
Added the persistent Interface / Show toolbar setting. It hides only the top toolbar; the gizmo, camera, building controls and hotkeys remain active, and the hidden toolbar does not block mouse input.
Increased the center square of the translation gizmo and its exact mouse hit area by 50%, from 22×22 to 33×33 pixels. Arrow and ring sizes are unchanged.
Auto-equipping no longer writes directly to Player.m_buildPieces. It uses the vanilla UseItem → ToggleEquipped → EquipItem → SetPlaceMode chain, including queued equipping of custom construction hammers and safe cancellation of pending requests.
0.3.8
Regular interactive structures—chests, beds, workbenches, forges, smelters, ovens, fermenters, portals, furniture and similar objects—are no longer misclassified as special because of support-surface restrictions. They now use the regular Build Ease gizmo and do not follow the camera ray.
The compatibility filter now preserves vanilla placement only for genuine utility actions and objects that require terrain, zone, distance or connection logic: repair, demolition and upgrades; hoes and terrain operations; plants; water; station extensions; pieces with an active blockRadius + blockingPieces pair; and objects with mustConnectTo.
Immediately before construction, the final _desiredPosition and _desiredRotation are injected into the vanilla Player.PlacePiece arguments. The object is still created and synchronized exclusively through the vanilla Instantiate → ZNetView → ZDO chain, without a custom placement RPC or unsafe post-placement ZDO rewrites.
Added protection against an active MoveBuildPieces 1.0.23 operation. Build Ease will not enter over a started or pending network move and exits if such a state appears. While Build Ease is active, the three current MoveBuildPieces activation hotkeys are blocked; its move state is never cancelled or modified through reflection.
Updated the conflicting-editor warning in English and Russian to explicitly include MoveBuildPieces.
0.3.7
Added Visuals / Blue ghost preview, disabled by default. When enabled, any piece selected for construction in extended mode receives a blue emissive ghost appearance similar to the placement ghost in MoveBuildPieces.
Ghost styling modifies only cloned Valheim preview materials, is applied once when a new ghost is created, and is restored when the setting is disabled or extended mode exits. Prefabs and constructed objects are unaffected.
After resources from demolition are successfully auto-collected, their local models are hidden in the same frame. The first search now runs immediately, while existing retries remain for network latency.
Removed the previous forced restriction against placing again at the saved position. Build Ease no longer adds its own overlap restrictions and preserves Valheim's rules for each piece.
0.3.6
Changed the Thunderstore identifier to Build_Ease, displayed in mod managers as Build Ease.
Renamed the assembly from UEPlacementEditor.dll to BuildEase.dll; the technical GUID and existing config path remain unchanged.
Cleaned the installation archive down to four required files: manifest.json, icon.png, README.md and BuildEase.dll.
0.3.5
Added separate English and Russian text tables for the extended-building interface, toolbar, statuses and in-game messages. Language follows Valheim's setting (Russian → RU, all others → EN) and updates through Localization.OnLanguageChange without per-frame polling.
The selected piece name now comes from Piece.m_name and is localized through Valheim instead of displaying the internal prefab name.
The top toolbar can be dragged by its header with LMB while the cursor is free. Dragging is disabled during RMB camera capture, building input is blocked during toolbar interaction, and the window remains within the screen bounds.
Current user settings became the defaults for clean installations: entry on KeypadEnter, light on F, and a 100 m light radius. Following a separate clarification, the default rotation step was changed to 5°.
Completely restructured the README, separating camera controls, gizmo/snapping controls and building actions into sequential English and Russian sections.
Existing configs are not overwritten; new defaults apply only when the corresponding settings are missing.
0.3.4
Renamed the mod to Build Ease with the tagline Easy UE-style building for Valheim. The Thunderstore package identifier is now BuildEase; the technical GUID, DLL name and config path remain unchanged so updates do not reset existing settings.
Added the configurable Hotkeys / Toggle camera light hotkey (L by default) and a toolbar button for temporary work lighting around the camera.
The light follows the free camera, never casts shadows, and is destroyed when disabled or whenever extended build mode exits.
Range (Lighting / Camera light range, 30 m, 1–100) and intensity (Lighting / Camera light intensity, 1.5, 0–10) are configurable and immediately update an active light.
The light hotkey also works while RMB is held; config changes are applied to the Unity Light only on the main game thread.
0.3.3
Added a finished 256×256 Thunderstore icon, a concise English description, a controls table, and an explicit incompatibility warning for other free build-camera or placement-gizmo mods.
After a successful build, the next ghost of the same regular gizmo-compatible piece preserves the exact world position and quaternion of the placed object, including when the ghost is recreated after resources are consumed.
The newly placed pose is temporarily marked as occupied: another LMB click cannot create an overlapping duplicate, while the first real translation or rotation restores normal placement validation.
The vanilla Shift+MMB sample action now copies the source object's exact position and rotation, including pitch and roll, to the selected ghost of a regular gizmo-compatible piece, whether it uses the same or a different prefab. Special pieces retain the vanilla placement path.
Sampling works over the gizmo and synchronises the hidden vanilla/PerfectPlacement rotation state after a complete UpdatePlacement, preventing later mouse-wheel or gamepad processing from resetting the pose.
The camera is captured only while RMB is held. The previous persistent capture mode and its config entry were removed; the nearest vanilla snap point is still selected automatically.
Added Mouse2 to the editor's reserved input, and stale hover state from an old gizmo is cleared when the placement ghost is destroyed or changed.
0.3.2
Rotating the free camera no longer marks its position as changed or invokes the expensive ZoneSystem.GetGroundHeight/terrain raycast on every frame of normal RMB look.
Local/World, surface snap and exit labels are now cached. BepInEx KeyboardShortcut.ToString(), including its internal LINQ and array work, runs only when the state or config actually changes instead of on every IMGUI event.
The hotkey barrier now uses one HashSet + polling array snapshot rebuilt through SettingChanged. This removes four LINQ iterators from every idle InventorySlots frame and eliminates repeated linear hotkey scans.
The surface raycast no longer sorts the entire hit buffer; the nearest valid surface is found in one O(n) pass.
Build snap-point searches use a dedicated reusable collider buffer and process each nearby Piece once. Multiple colliders no longer create duplicate lists or inflate the Cartesian search of snap-point pairs.
A clipping-buffer overflow is retained as the new high-water mark; in very dense bases, Physics.OverlapSphere no longer allocates another large array on every drag frame.
The gizmo caches the current camera directions once per render pass instead of performing hundreds of repeated Camera.current/transform lookups while drawing rings.
0.3.1
Fixed position, rotation and temporary snap-pivot being fully reset when switching between Local and World modes.
Coordinate-system changes now atomically preserve the canonical position, rotation and world-space gizmo point; only the axis orientation changes.
When the placement ghost is internally recreated for the same selected piece, its saved pose and snap-pivot are transferred to the new ghost. Selecting a genuinely different piece or successfully building still starts a new placement.
Added an input-ownership barrier: while the editor viewport is open, standard BepInEx KeyboardShortcut hotkeys from other mods do not receive keys reserved by the editor. Build Ease commands use an internal bypass.
Added dedicated compatibility for InventorySlots, which reads raw Unity Input instead of KeyboardShortcut: its quick-slot handler does not fire while reserved editor input is held. This resolves the Local/World X conflict with Quick Slot 2 Hotkey = X; non-conflicting quick slots remain available.
Changed the default rotation step from 15° to 1°. Existing user-configured values are not overwritten automatically.
0.3.0
The free camera now applies its final transform after the FirstPersonMode postfix; direct fallback WASD input was added alongside ZInput.
Removed the position grid. Snapping now means surface snapping and vanilla Valheim build snap points while dragging the centre square.
Added a central translation handle that remains visible through geometry.
After a surface or build-point snap, the gizmo moves to the snap point and rotation keeps that point fixed in place.
The rotation step is now independent of surface snapping and configurable; a value of 0 enables continuous rotation.
Added configurable hotkeys for surface snapping and Local/World mode. The toolbar displays the actual assigned keys for both actions and for entering or exiting the editor.
Extended mode now removes only the crafting-station requirement for demolition. Repair and all other actions remain vanilla, as do private-area checks, no-build zones and the piece's own restrictions.
Added network-safe pickup of only newly spawned drops after successful demolition through vanilla ownership and Pickup methods. Items that do not fit or are too heavy remain in the world; there is no continuous camera “vacuum.”
Removed the obsolete Position step and Existing piece edit range config entries.
0.2.0
Completely removed the flawed mode for selecting and repositioning already built objects, including its network RPC, creator/host checks, visual proxy and ZDO transform-writing code.
The editor is now limited to the ghost of a new piece; building, repairing and demolishing are handled by vanilla Player.UpdatePlacement.
Reworked the free camera with UE-style controls: a short RMB click toggles the menu, while holding RMB immediately captures the mouse and enables movement and look.
Fixed short RMB click detection after Unity recentres the locked cursor.
Added WASD, Q/E, Space/Ctrl, Shift acceleration and mouse-wheel speed adjustment.
In free-cursor mode, the vanilla repair/demolition ray now points under the cursor; hotbar keys 1–8 and the hide-items command were restored.
Gizmo axes are drawn with depth testing disabled and remain visible through the object.
Added world/local axes, position/angle snapping, and suppression of building actions when clicking the toolbar or gizmo.
Hammer range and crafting-station search range are extended only while the editor is active and safely restored afterwards.
Special terrain, water and connectable pieces automatically use vanilla placement without a gizmo.
Regular gizmo-compatible pieces use separate arbitrary-transform validation without requiring a surface beneath the ray; vanilla support physics remain enabled after construction.
Added protection against PerfectPlacement ABM/AEM and Build Camera modes being active at the same time.
The editor's hard radius is now reapplied after BuildRestrictionTweaks and before placing the piece.
Enabled standard FPR PerfectPlacement no longer accumulates hidden mouse-wheel rotation while the ghost is held by the gizmo.
Removed the per-frame reflection invoke and argument boxing; UpdatePlacement now uses a cached delegate, while the camera and selected-piece compatibility are also cached.
Removed unused and conflicting prototype features; scaling remains intentionally unsupported.
0.1.0
First experimental prototype. Its architecture for editing placed objects was deemed incorrect and completely replaced in 0.2.0.