Linear interpolation!
Torso.CFrame = Torso.CFrame:Lerp(GoalCFrame, LerpAmountHere)
For best results, LerpAmountHere should be tied to dt from heartbeat
Linear interpolation!
Torso.CFrame = Torso.CFrame:Lerp(GoalCFrame, LerpAmountHere)
For best results, LerpAmountHere should be tied to dt from heartbeat
silly me it says it right there!
This is a wonderful guide for server optimization!
May I translate this article and post it in Korean Community?
I would leave the original link!
Yeah, that sounds good to me!
Awesome topic and alot that i can learn of. One question (Im not sure whether this is asked alread). How are the AIâs themselves done? Are they humanoids? I can imagine the server having an easy job by only needing to send position data but the client having a very hard job to move all those units.
Thanks!
No humanoids â that would be far too laggy. The server moves the units and sends position updates to the clients. The clients render units at the given positions. Performance is not too bad having the client move many parts.
Slightly unrelated question, how did you calculate the hash so there werenât any duplicates, and the server and clients always stayed in sync?
We created a module to get unique hashes.
When a new unit is created, we request a new hash from the module. The module checks if there are any inactive hashes and if there are, it reactivates a hash and returns it. If there are no inactive hashes, we increment an internal counter and return this new hash.
When a unit dies, we return the hash to the module and it gets added to the list of inactive hashes.
I think this is an amazing resource, and gives a lot of information.
I also liked pretending to understand what version 3 was about while I was reading.
This post was a life saver for me, I was working on a similar system since Robloxâs physics were too rigid (needed smoother collisions) and expensive for me, but the lag was unreal. I was totally unaware of the bandwidth usage of updating CFrames every frame, everyone should be made aware of this! I was getting like 500+ KB/s updating only 350 objects per frame.
Thank you for sharing this and for making it very easy to understand.
Question that doesnât really pertain to original post: (feel free to not answer if you donât want to give away something or maybe move to PMs)
I was wondering what your custom unit/soldier âcollision functionâ looked like? Mine is linear with distance and is something like: (1 - (distanceBtwEntities/(Entity.Radius + otherEntity.Radius))) * otherEntity.Weight. Iâve experimented with others like inverse-square but this seems to be the smoothest. Perhaps you do something different altogether? Heres a quick implementation example:
Note:
â Each âEntity.BounceVelocityâ is set to 0,0,0 at the end of each frame.
â Iâm using arrays of size 3 for Vector3s for (very slim) performance gains and for a bit more flexibility for other functions I have. (1 == X, 2 == Y, 3 == Z)
local Entity = -- thisEntity
local otherEntity = -- other Entity
local bounceVectorX = Entity.Position[1] - otherEntity.Position[1]
local bounceVectorZ = Entity.Position[3] - otherEntity.Position[3]
local distanceSquared = bounceVectorX^2 + bounceVectorZ^2
local minDistance = Entity.Radius + otherEntity.Radius -- TODO: Better variable name for minDistance
if distanceSquared < (minDistance*minDistance) then
local distance = math.sqrt(distanceSquared)
local bounceAccel = (1 - (distance/minDistance))
local bounceDirectionX = (bounceVectorX/distance)
local bounceDirectionZ = (bounceVectorZ/distance)
local EntityBounceVelocity = Entity.BounceVelocity
local EntityBounceAccel = bounceAccel * otherEntity.Weight
EntityBounceVelocity[1] = EntityBounceVelocity[1] + (bounceDirectionX * EntityBounceAccel)
EntityBounceVelocity[3] = EntityBounceVelocity[3] + (bounceDirectionZ * EntityBounceAccel)
local otherEntityBounceVelocity = otherEntity.BounceVelocity
local otherEntityBounceAccel = bounceAccel * Entity.Weight
otherEntityBounceVelocity[1] = otherEntityBounceVelocity[1] - (bounceDirectionX * otherEntityBounceAccel)
otherEntityBounceVelocity[3] = otherEntityBounceVelocity[3] - (bounceDirectionZ * otherEntityBounceAccel)
end
Hey! Sorry if I havenât understood your post thoroughly, but could you possibly save some memory by using a pairing function, generating a unique number for the two axes (X and Z)? Since pairing functions only work on natural numbers, youâd have to make sure they donât go below 0.
https://cafe.naver.com/korearoblox/183743
https://cafe.naver.com/robloxstudio/2746
I translated this post. Thank you for your permission!
Great post! Though I have some questions left unanswered:
You said in previous replies that you wonât only send through positional data of the goal, so I assume that you tween the positional data on teh server, but how would you re-mark that the position has changed from a specific unit until it has tweened to the goal position?
Kind regards,
I think this would take the same amount of bits to cover all the possible X and Z coordinates.
We donât tween the position on the server, we use a custom movement function (called each game tick if the unit needs to move toward a goal) that takes into account acceleration and current velocity. So whenever this movement function is used, we know the unit has moved and we mark this unit for replication this game tick. Otherwise, the unit didnât move and we donât mark it for replication this game tick.
Hope this helps
Thank you for the elaborate response, though Iâm still a bit confused;
game tick
Do you mean like tick()?
like
while task.wait(tick()) do
movementFunction()
end
?
that takes into account acceleration and current velocity.
How would you involve the physics engine in objects that donât have a physical form?
Lastly
we use a custom movement function
I had first thought this would mean youâre just doing positionData = newPositionData, is it like that?
Thanks in advance for dedicating time to read this and apologies for thanking you at a later notice than expected.
Kind regards,
I think he means something like Heartbeat, although itâs possible heâs running the function less than 60 times a second to minimize performance cost.
For the rest of the questions, I donât really have an answer.
How do you account for varying arrival times causing jumpiness in position if you tie it to dt. If it arrives before the next packet is due does it not stutter with a brief stop?
Can you explain more about the heightmap with the Y position ?
How itâs possible to make heightmaps on Roblox ?
Just out of curiosity, how were you able to tell the client to start and stop rendering objects?
One of my projects uses a similar approach to rendering, and thatâs had me stumped for a while.