First I would replace
connection = run.RenderStepped:Connect(cameraMovement)
and
connection:Disconnect()
connection = nil
with
run:BindToRenderStep("cameraMovement", Enum.RenderPriority.Camera.Value + 1, cameraMovement)`
and
local s, e = pcall(function() run:UnbindFromRenderStep("cameraMovement") end)
if (s) warn(e) end
respectively. That will ensure your camera movement stuff always happens after roblox does any of theirs. Might not strictly be necessary but it’s good practice.
Then you just need to clamp the location. How exactly you define a boundary is up to you. Let’s say you have a center position and a Vector2 size:
local plotCenter = Vector3.new(100, 0, 100)
local plotSize = Vector2.new(50, 50)
Then where you have cam.CFrame += velocity * dt
, replace that line with something like
local cf = cam.CFrame + velocity * dt
local x, z = plotCenter.X, plotCenter.Z
local w, h = plotSize.X, plotSize.Y
cf.X = math.clamp(cf.X, x - w / 2, x + w / 2)
cf.Z = math.clamp(cf.Z, z - h / 2, z + h / 2)
cam.CFrame = cf
i.e. clamp the X and Z positions of the camera to be in your box.