From 02fbd4372d6b575d9cb5ede0f291a485018757ed Mon Sep 17 00:00:00 2001 From: Jared Brown <206airmail@gmail.com> Date: Sun, 24 May 2026 11:09:24 -0800 Subject: [PATCH] Guard spec.loadVolume access in doUpdate to avoid nil-index crash spec.loadVolume is only created in initialiseTransformGroups, which is called from onLoad only when self.isServer and the vehicle is not in SHOP_CONFIG. On a multiplayer client, or for vehicles UAL detects as autoload-capable but that lack a configured loadArea, spec.loadVolume is therefore nil. The customOffset/customRotation block in doUpdate dereferences spec.loadVolume.length unconditionally, producing repeated "UAL - FATAL ERROR: " log spam via the pcall in onUpdate/onUpdateTick and permanently disabling UAL on the vehicle. Wrap the offset/rotation block with `if spec.loadVolume then ... end`. The action-event update block above is unaffected and continues to run. --- UniversalAutoload.lua | 47 ++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/UniversalAutoload.lua b/UniversalAutoload.lua index a2a40c6..34ed246 100644 --- a/UniversalAutoload.lua +++ b/UniversalAutoload.lua @@ -2585,32 +2585,37 @@ function UniversalAutoload:doUpdate(dt, isActiveForInput, isActiveForInputIgnore spec.customOffset = spec.customOffset or 0 spec.customRotation = spec.customRotation or 0 - local rotationshift = spec.loadVolume.length / 3 - local direction = (spec.currentTipside == "right") and 1 or -1 - local function clampOffset() - local minOffset = (spec.customRotation == 0) and 0 or rotationshift - local maxOffset = spec.loadVolume.length / 2 + minOffset - spec.customOffset = math.clamp(spec.customOffset, minOffset, maxOffset) - end + -- spec.loadVolume is only populated server-side by initialiseTransformGroups, + -- or for vehicles without a valid loadArea config. Skip the shift/rotate logic + -- in those cases to avoid "attempt to index nil with 'length'". + if spec.loadVolume then + local rotationshift = spec.loadVolume.length / 3 + local direction = (spec.currentTipside == "right") and 1 or -1 + local function clampOffset() + local minOffset = (spec.customRotation == 0) and 0 or rotationshift + local maxOffset = spec.loadVolume.length / 2 + minOffset + spec.customOffset = math.clamp(spec.customOffset, minOffset, maxOffset) + end - if spec.leftKeyPressed then - spec.customOffset = spec.customOffset - (UniversalAutoload.SHIFT_DELTA * direction) - clampOffset() - end + if spec.leftKeyPressed then + spec.customOffset = spec.customOffset - (UniversalAutoload.SHIFT_DELTA * direction) + clampOffset() + end - if spec.rightKeyPressed then - spec.customOffset = spec.customOffset + (UniversalAutoload.SHIFT_DELTA * direction) - clampOffset() - end + if spec.rightKeyPressed then + spec.customOffset = spec.customOffset + (UniversalAutoload.SHIFT_DELTA * direction) + clampOffset() + end - if spec.rotateKeyPressed then - local rotated = spec.customRotation ~= 0 + if spec.rotateKeyPressed then + local rotated = spec.customRotation ~= 0 - spec.customRotation = rotated and 0 or -math.pi / 2 - spec.customOffset = spec.customOffset + (rotated and -rotationshift or rotationshift) + spec.customRotation = rotated and 0 or -math.pi / 2 + spec.customOffset = spec.customOffset + (rotated and -rotationshift or rotationshift) - spec.rotateKeyPressed = false - clampOffset() + spec.rotateKeyPressed = false + clampOffset() + end end end