So, did a thing.
Made a simple proof of concept. Things to note are:
- You have to use physics constraints, I used BodyPosition and BodyGyro. Direct CFrame and Position manipulation wasn’t replicated.
- Network Ownership requires parts be unanchored. If a part is anchored, there is no physics on the object ergo no ownership applicable.
This repro has 9, size(1,1,1) parts used as markers, 8 are bits and the 9th is reserved for signaling that the other client can read the new byte. Info compression and optimization can be added too as mentioned earlier. Since body movers are being used, not sure how much error will be in your positions so the reading process might need to be similar to electrical signals (define a threshold value that defines the 0,1 regions). I suspect depending on size of parts and positions, rounding errors will prevent absolute checks(==).
Server Script
local Players = game:GetService("Players")
local needsowner = true
local bits = workspace.Bits:GetChildren()
Players.PlayerAdded:Connect(function(player)
if needsowner then
for _, part in pairs(bits) do
if part:IsA("Part") then
part:SetNetworkOwner(player)
end
end
needsowner = false
end
end)
Local Script
local bits = workspace.Bits:GetChildren()
local defaultY = workspace.Bits.DefaultY.Value
local startVec = Vector3.new(0,defaultY,0)
local cf = Instance.new("BodyGyro")
cf.CFrame = CFrame.new(0,0,0)
cf.MaxTorque = Vector3.new(math.huge,math.huge,math.huge)
local pos = Instance.new("BodyPosition")
pos.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
local prevVec = startVec
for _, part in pairs(bits) do
if part:IsA("Part") then
local temp = pos:Clone()
temp.Position = prevVec + Vector3.new(2,0,0)
prevVec = temp.Position
temp.Parent = part
local temp2 = cf:Clone()
temp2.Parent = part
end
end
function programBit(bit, on)
if on==1 then
bit.BodyPosition.Position = Vector3.new(bit.Position.X,defaultY+1,bit.Position.Z)
else
bit.BodyPosition.Position = Vector3.new(bit.Position.X,defaultY,bit.Position.Z)
end
end
sampleByte = {0,0,0,1,0,1,1,1}
local function programByte(byte)
for _, bit in pairs(bits) do
local num = tonumber(bit.Name)
if num then
programBit(bit,sampleByte[8-num]) -- because least significant bit is highest array index
end
end
end
local button = workspace.SpawnLocation.SurfaceGui.TextButton
button.MouseButton1Click:Connect(programByte)