-- PAEastSlip turns 216deg vs PAWestSlip's 56.5deg -- nearly 4x. That is the -- "looks terrible" the user means. Find WHERE the turn concentrates: is it a -- smooth long curve, or a few violent kinks? Per-segment heading deltas tell us. local out = {} local function say(s) table.insert(out, s) end local map = workspace:FindFirstChild("Map") if not map then return "Map MISSING" end for _, s in ipairs({ "PAWestSlip", "PAEastSlip" }) do local segs = {} for _, d in ipairs(map:GetDescendants()) do if d:IsA("BasePart") then local k = d.Name:match("^" .. s .. "_Deck_(%d+)$") if k then table.insert(segs, { i = tonumber(k), p = d.Position, cf = d.CFrame, sz = d.Size }) end end end table.sort(segs, function(a, b) return a.i < b.i end) if #segs == 0 then say(s .. ": absent") continue end local deltas = {} for j = 2, #segs do local a = segs[j - 1].cf.LookVector local b = segs[j].cf.LookVector local dth = math.deg(math.acos(math.clamp(a:Dot(b), -1, 1))) table.insert(deltas, { i = segs[j].i, d = dth, p = segs[j].p }) end -- worst kinks local sorted = {} for _, v in ipairs(deltas) do table.insert(sorted, v) end table.sort(sorted, function(x, y) return x.d > y.d end) local sum = 0 for _, v in ipairs(deltas) do sum += v.d end say(("%s: total=%.1fdeg mean=%.2fdeg/seg n=%d"):format(s, sum, sum / #deltas, #deltas)) local worst = {} for j = 1, math.min(8, #sorted) do table.insert(worst, ("seg%d=%.1f"):format(sorted[j].i, sorted[j].d)) end say(" worst kinks: " .. table.concat(worst, " ")) -- how many segments exceed a smooth-curve threshold? local over = 0 for _, v in ipairs(deltas) do if v.d > 5 then over += 1 end end say((" segments turning >5deg: %d"):format(over)) -- segment length consistency (uneven lengths also read as ugly) local lmin, lmax, lsum = math.huge, -math.huge, 0 for j = 2, #segs do local L = (segs[j].p - segs[j - 1].p).Magnitude lmin = math.min(lmin, L); lmax = math.max(lmax, L); lsum += L end say((" seg spacing: min=%.1f max=%.1f mean=%.1f totalRun=%.0f"):format( lmin, lmax, lsum / (#segs - 1), lsum)) -- vertical profile: where does it drop? local topY = segs[1].p.Y local level = 0 for _, sg in ipairs(segs) do if math.abs(sg.p.Y - topY) < 0.5 then level += 1 else break end end local steep = 0 for j = 2, #segs do local dy = math.abs(segs[j].p.Y - segs[j - 1].p.Y) local dxz = (Vector3.new(segs[j].p.X, 0, segs[j].p.Z) - Vector3.new(segs[j - 1].p.X, 0, segs[j - 1].p.Z)).Magnitude if dxz > 0.1 and (dy / dxz) > 0.12 then steep += 1 end end say((" level-run=%d segments steeper than 12%%: %d"):format(level, steep)) end return table.concat(out, "\n")