Server Authority Studio Beta - Insights from Engineers!

TLDR:

  • This post will evolve a bit over time
  • This is a minimum set of initial APIs that will be expanded upon.
    • Even smaller than Early Access
    • We will expand the APIs during the lifetime of the Studio beta
    • Always easier to expand APIs (instead of reducing) without negatively impacting Roblox Creators
  • Default Avatars should just work, and easily customizable
  • Functionality is focused around scripts that have control loops that are bound to RunService::BindToSimulation
  • Currently the system works best with simple, one-assembly mechanisms
  • Complex mechanisms (cars with suspensions, ETC) still work with the API but experience quality will most likely be reduced
    • There is quite a bit of work on our part to improve this
  • Some notes on two required features to enable Server Authority
  • Deeper dive on some of the Known Issues

Hi everyone!

Thanks for being interested in the Server Authority beta, this is something that many of us have dreamed of having on the platform for many years, and being so close to a first release has us extremely excited!

We wanted to take a moment to set up some expectations for the initial Server Authority Studio Beta. Some of you may know that once an API is in Roblox, it’s in Roblox forever-ish. Because of this, the current beta is the MINIMUM set of APIs that we feel confident about. This does mean that this is not a complete and final API. We’ve spent a lot of time removing one off hacks that enabled the Early Access Beta APIs, throughout the Roblox engine, allowing us to ship the Server Authority Studio Beta built upon a sustainable core tech stack. This initial API unlocks a lot of Server Authoritative content, so we want to get it in Creators` hands ASAP for further testing and feedback!

We expect that as you start developing some content you will run into pain points and will want to request API extensions. This is part of the process and we want your feedback so that we can methodically extend the capabilities of Server Authority before the fully playable launch in early 2026. We have internally verified the existing API by writing movement abilities for player characters, simple sports games, racing experiences, and shooting games, but these are going to be much simpler experiences than anything you will build, which is why the feedback will be key. The most effective way to request new features is to describe your use-case in detail! Another callout is that we have been mostly focused on feature completeness, so expect performance to significantly improve before the initial launch for Server and Clients.

The current Server Authority technology has been built and optimized primarily for simple mechanisms, like the player characters/avatars. When opted into the Server Authority Studio Beta, if you open a baseplate and change Workspace.AuthorityMode to Server (There may be some pieces of core tech you may need to enable first) and hit play, you will be playing on Server Authoritative default character avatar without writing any code. ā€œIt just works(:trade_mark:)ā€.
todd-howard-it-just-works

Just because we’ve been focusing on simple mechanisms and avatars doesn’t mean that you can’t start experimenting with more complex systems. You can add your own capabilities to default avatars by using module scripts that have a loop bound via RunService:BindToSimulation, and Server and Client bootstrapper scripts that initialize the control loops. Additionally, more complex mechanisms like cars could also be used with the beta today, but we haven’t done the full pass on reducing mispredictions/jitter when working on more complex mechanisms. The Roblox engine was never built with the determinism that makes Server Authority work well, so more complex mechanisms are increasingly more likely to feel ā€œjitteryā€ in this initial Server Authority beta. We are working on this!

Server Authority Requirements

You may have noticed the list of required technologies that have to be enabled before Server Authority is toggle-able, and we want to take some time to highlight a few of these.

Workspace.NextGenerationReplication

This is a brand new replication architecture that we’ve been working on at Roblox for a few years now, and it’s one of the key pillars that make Server Authority on Roblox possible. For Server Authoritative gameplay to be responsive the Server has to send the most relevant updates to each player frequently.

The legacy Roblox replication system was not capable of this:

  • Properties would replicate via a pseudo ā€œFirst In First Outā€ principle, where an update to Color on a tree two miles away would be sent before an update to a Weld CFrame on a mechanism right next to a player just because the Color update happened first during a script call.
  • Additionally, Properties would be sent reliably and could block future updates under certain networking conditions
  • Physics updates on moving objects WOULD actually be prioritized and sent based on relevancy
  • Physics updates were unreliable by default and would never block future updates
  • So imagine a scenario where you have a lot of script-driven property updates, including one that updates a mechanism’s weld CFrame and then simulation that moves the mechanism as a whole. This kind of update almost always arrives desynchronized from Server to Clients due to the wildly different natures of the Physics and Property replication systems.

The new system aims to address these issues and unify the best parts of both replication methods: We get prioritization for the vast majority of networked data, while also making sure that Instance updates are significantly more likely to be synchronized.

With NextGenerationReplication set to Enabled if you are constantly updating the state of the objects in the game world via scripts or simulation, each player will receive the higher priority updates more frequently. You can use the image above to visualize how this would work. If the red dot at the center is a player, then all of the items in the ā€œgreenā€ zone are being updated more frequently and are considered higher priority, while things further out in the orange and red zones will be prioritized less frequently.

This prioritization and synchronized sending is part of what lets us be able to use prediction and validation on the Clients to maintain a responsive gameplay loop even when the true simulation happens on the Server.

Attribute Limits

Part of what makes Server Authority work is making sure payloads for synchronization to the server are quick and timely. This requires us to fit things into a single MTU as much as possible. This is fairly easy to guarantee with Roblox instance Properties since they are normally small and hard capped, however user defined payloads are more complicated.

For now we have strict limits on Attribute Replication to make sure they are small payloads that can be synchronized efficiently. In the future we plan to loosen these, but it requires some feature design and extra architectural expansion.

Important Callouts

  • Larged/Uncapped properties will still use legacy replication, things like Strings, Arrays, ETC.
  • There are no more ordering guarantees for property updates! This breaks the guarantee that when a RemoteEvent arrives that all properties that were updated BEFORE the event was sent would have replicated.
  • Server Performance with 20+ player games needs a lot of work!

Workspace.StreamingEnabled

NextGenerationReplication does a lot of extra CPU work on the Server that didn’t exist before, since we are prioritizing all Instance property updates (something we didn’t have to do with FIFO logic before). Streaming provinces a necessary scalability limit on how much prioritization work needs to happen on the Server. It’s also a key requirement for how we plan to make Server Authority work on low-end devices.

Additionally, RunService::setPredictionMode relies on atomicity/instance grouping that only exists in Streaming. (note: this may not be fully enabled on the first beta version) There are other core functionalities from streaming that we depend on under the hood, and not all of them are currently enabled.

Known Issues

Finally, we want to mention again that since our goal with this Studio Beta is to get the initial API in front of as many developers as possible, we do want to mention that there are still some known issues and initial limitations that will be addressed before the full playable release, including some security issues that will be addressed.

API Behavior that will change before full release:

  • RunService::setPredictionMode currently only applies overrides to the specific instance it is called on. In the future, this will work similar to :SetNetworkOwner where prediction will be applied to the NOU or Atomic Model. (Internally we call this grouping ā€œStreaming Setsā€)
  • RunService::getPredictionStatus will work correctly even with Workspace::AuthorityMode == Automatic so that any vehicles/control scripts you create for Server Authoritative experiences will be compatible in non-server authoritative experiences.
  • We are missing a ā€œRunService::OnRollbackā€ event that lets creators reset custom state when mispredictions must be corrected
  • Properties/Data settable via RunService:BindToSimulation is not finalized

Some Extra Callouts/Workarounds on Specific Known Issues

This is diving a bit deeper into some of the known issues called out in the main announcement thread.

Instance creation and deletion

New instances must be created on the server outside of the Simulation loop. Creators can use a deferred task, BindableEvent, or a BindableFunction to create new instances or destroy existing instances.

Creating a new Part on the Server in a deferred task

RunService:BindToSimulation(function(deltaTime)
	if RunService:IsServer() then
task.defer(function()
local newPart = Instance.new("Part")
			newPart.Parent = game.Workspace
		end)
	end
end)

Deleting a part on the Server in a deferred task

RunService:BindToSimulation(function(deltaTime)
	if RunService:IsServer() then
task.defer(function()
game.Workspace.SomePart:Destroy()
		end)
	end
end)

The server only replicates changes

Clients can diverge from the server and not be resynchronized if a change only takes place on the client and no changes take place on the server; the server only replicates data to the clients when changes are made. If nothing changes on an instance, its data will not be replicated to the clients.

For example, if a client mispredicts that a point was scored by incrementing an attribute, the client might not be corrected until the server changes the instance that holds the attribute. This is the expected behavior for Roblox replication, but might be unexpected in a place designed around server authority. You can force replication on an instance by changing one of its attributes on the server:

Forcing the constant replication of an Instance

RunService:BindToSimulation(function(deltaTime)
if RunService:IsServer() then
	local alwaysReplicated = game.Workspace.Part
alwaysReplicated:SetAttribute("Time", time())
	end
end)

IF YOU HAVE TO USE THE ABOVE TRICK, PLEASE SEND US A REPRO AS THIS IS A FUNCTIONALITY GAP!

Input change signals are inaccurate during rollback

When a client’s simulation is rolled back to an authoritative server state, InputActions’ Change signals can be fired. These signals will happen at different frames than they will on the server, which can result in incorrectly detected inputs on the client.

Instead of using InputAction:Changed, InputAction:Pressed or InputAction:Released, poll InputAction:GetState() in BindToSimulation.

If input changes (like new key presses) are needed, store the InputAction’s last state as an attribute of a predicted instance, and compare the current state to the attribute to detect changes within RunService:BindToSimulation().

Detecting new inputs using Attributes

RunService:BindToSimulation(function(deltaTime)
	for _, player in Players:GetPlayers() do
		local hrp:BasePart = player.Character.HumanoidRootPart
		local inputContext:InputContext = player.PlayerGui.InputContext 
		local shootInput = inputContext.ShootAction:GetState()
		local previousShootInput = hrp:GetAttribute("ShootInput") or false
		hrp:SetAttribute("ShootInput", shootInput)
		if shootInput and not previousShootInput then
			shoot(player)
		end
	end
end)

BasePart’s Touched signal is inaccurate during rollback

When a client’s simulation is rolled back to an authoritative server state, BasePart’s Touched and TouchEnded events can be fired if a BasePart is rolled back to a touching or not touching state. These signals will inaccurately fire on the client when they might not have fired on that frame on the server.

To ensure consistent behavior between client and server, use BasePart:GetTouchingParts() in RunService:BindToSimulation(). If new touches need to be detected, write the relevant information to attributes on a predicted instance to record the necessary information to detect new touches.

Detecting new contacts with the ground

RunService:BindToSimulation(function(deltaTime)
	for _, player in Players:GetPlayers() do
		local hrp:BasePart = player.Character.HumanoidRootPart
		local isOnGround = false
local isTouchingGround = false
		local touchingParts = hrp:GetTouchingParts()
		for _, p in touchingParts do
			if p.Name == "Ground" then
				isTouchingGround = true
				break
			end
		end
		-- Check if we were on the ground last frame
		local wasOnGround = hrp:GetAttribute("OnGround") or false
		-- Update OnGround attribute for next frame
		hrp:SetAttribute("OnGround", isTouchingGround)
		if isTouchingGround and not wasOnGround then
			-- player newly touched the ground
			game.ReplicatedStorage.TouchedGroundEvent:Fire(player)
		end
	end
end)

Seats are client authoritative

Seats and seat welds have client authority in Roblox. Seats can be sat in by any player, at any time, no matter the distance. Players can exploit seats by sitting in them as a way to teleport. Seat welds in Roblox are implicitly owned by the player who sits in the seat and they can be created and destroyed by the client. Using default seat weld systems can create desynchronization where the client thinks they are still in the seat, but the server does not, or vice versa.

Humanoid Enabled States do not Replicate

Setting humanoid states to enabled or disabled does not replicate between client and server. Calling Humanoid:SetStateEnabled() will not replicate any data between client and server meaning deviations between the two will not be rectified. You can fully synchronize enabled states by storing their data in Attributes and setting them every frame.

Synchronizing the ability to Jump with an Attribute.

RunService:BindToSimulation(function(deltaTime)
	local canJump = humanoid:GetAttribute("CanJump")
	humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, canJump)
end)

Setting the PredictionMode on a nil Instance will crash

Calling RunService:SetPredictionMode() with nil will crash. This will be fixed in the next release. Creators should check for nil before calling SetPredictionMode() in their scripts.

-- This will crash!
RunService:SetPredictionMode(nil, Enum.PredictionMode.On)

-- Check for nil in Luaua for safety:
if instance ~= nil then
RunService:SetPredictionMode(instance, Enum.PredictionMode.On)
end
83 Likes

Hi! Thanks for this resource. I had a quick question about cloning instances during simulation. With projectiles, I’m unable to clone parts during the simulation callback or use other RunService events. How might I create projectiles at runtime such that they’re visible for everyone properly to simulate bullets/bullet tracers?

EDIT: Nevermind! I saw that Laser Tag was updated for Server Authority. I’ll be checking that out instead. Sorry!

2 Likes

The PlayerModule doesn’t have any methods to stop the movement code for a specific player however, I think that should be improved upon.

This seems to be referring a C++ method that cannot be accessed from Luau.

I believe we had a .Misprediction event before in RunService? Were they removed due to :BindToSimulation()? It would be really useful if we had events that allowed us to detect when certain things happen under Server Authority.

Attribute limits are understandable, but a solution (such as dividing the data?) must be found because a lot of people use them. And you kind of need attributes to have rollback support for certain values. I’m personally thinking of creating an AttributeManager that automatically creates multiple Instances for a certain Instance’s Attribute so we can achieve more data.

9 Likes

Thank you for the transparency!

Could you expand on the reasons for the reliance on attributes for game state?
Using many attributes will drastically increase the amount of data other users send and receive, which may not be useful. Such as if there’s an ammo count that will need to be predicted and possibly rolled back, but only on one client. Using attributes will still end up replicating that data to users who don’t need that data.
I understand that it’s probably the simplest route to managing state, but I’d appreciate it if we were given more control over attributes themselves or a separate API that allows Luau variables to be rolled back programmatically.

13 Likes

Doesn’t this break like.. everything? What are the boundaries of it? (Is it only affecting things in Workspace etc.)

Are there any plans to add replication fences or something like that which enable replication to be forcibly ordered/grouped?

1 Like

It breaks anything that assumes this kind of Replication Fencing behavior, which is why the architecture is behind a Workspace flag instead of being enabled for all experiences.

Are there any plans to add replication fences or something like that which enable replication to be forcibly ordered/grouped?

Yeah we want to add ā€œLocal Remote Eventsā€ that are synchronous with some instance. But in general, global ā€œreplication fencingā€ is something we internally consider bad because it makes it impossible to make the engine scale better.

8 Likes

Yes, but for example there are various other systems that may be outside of Workspace but which are still replicated which this could impact I believe. For example, replicating instances via PlayerGui, or via ReplicatedStorage. Are those affected by these changes as well? Or is it just for things in Workspace.

Yeah those are also affected by that setting.

1 Like

Cool. Although it sounds like you’re thinking about an API where you have to create a separate remote event for every instance? For what my opinion is worth, that seems bothersome, I would prefer an API like this:

local RemoteEvent = Instance.new("RemoteEvent", game.ReplicatedStorage)
for _, Instance in Instances do
   RemoteEvent:FireClientSynced(Player, Instance, ...)
end

where you just do all the caching/instance setup under the hood, instead of making us do it with:

for _, Instance in Instances do
   local LocalRemoteEvent = Instance.new("LocalRemoteEvent", Instance)
   LocalRemoteEvent:FireClient(Player, ...)
end
2 Likes

Synced remote firing is actually a really good idea, especially with streaming involved. If you could be able to send an instance reference over but have the engine queue it until the client has fully replicated everything by that point, then you wouldn’t have to worry about streamed model references coming back as nil.

1 Like

I appreciate these sorts of posts. Honestly i would really like if we got more in depth explanations of other engine changes and updates like this.

The post below is a rather long read written at 4 am so i apologize. But hopefully it can maybe push some change here.

Look yeah, i get it that you cant really predict over a thousand parts with tons of properties at once. I get that the replication system has been juiced up and needs some optimization on the side to save on performance. But requiring streaming enabled for this is just absurd to me still considering this is mostly used, as youve said here, just as an instance manager to check what to prioritize. Maybe it makes sense to you, your team and whoever else. But it does not make sense to me and plenty other developers who have had to work (and suffer) with streaming enabled. I dont understand this culture at roblox in which GOOD features are being forcefully paired with other features. Sure, i get it to some degree. It’s technically easier to work with X Y and Z if theire being tied to whatever else but this only serves to HURT many other developers looking for higher levels of granularity for their own projects. One big example that really pissed me off is the introduction of the interior environment reflection maps. Amazing feature though and through except oh wait, its entirely automatic, unpredictable and it’s tied to one specific lighting property that just so happens to also change how the entire shading of your experience looks like. Also with the excuse that manual controls wont be provided because:

Personally? I believe this is a full on insult to the developers working on this platform. But whatever, this post isnt about cube map reflections.

You specifically mention the next generation replication performing a lot of extra work on the CPU. I have to ask… how much more exactly? Are there some numbers we can view? Is there some sort of percentage? How much harder is it to replicate one singular instance now? We have no idea because nobody even let’s us now. Instead… the ā€œfixā€ here is to force on us an arguably INSANELY computationally expensive system (on BOTH the server and the client) to presumably ā€œfixā€ said extra work or at least reduce it to some degree. I find it hard to believe that such new replication system is suddenly so demanding that it requires the help of another arguably even more demanding system just to make it ā€œlessā€ demanding, and less demanding by an amount we will never really know. There is absolutely no way you do not know what the costs of streaming enabled are. If you somehow dont then here is a recap:

  • Very computationally expensive on the server, more players = harder to run. (To the degree that it can visibly damage server performance very early on. Anything remotely competitive or anything that requires some level of precision will feel very poor to play with streaming enabled)

  • Very memory intensive on the server. No, we cannot run ā€œlarge worldsā€ with streaming enabled because said large worlds take too much server memory. The 6~ gb of default starting memory are NOT enough for any game with an actual large world running streaming enabled.

  • Very network intensive on the client. Most people dont run amazing internet connections, especially on phones and all streaming enabled helps doing is degrade the experience of anyone that is not running top of the line hardware with powerful wired connections. A constant stream of 500 kb/s back and fourth in even simpler games all because of streaming is horrifyingly bad design. But thats just sadly the nature of constantly throwing instances and whatever else at the client constantly. And i doubt the next gen replication will even ā€œfixā€ this when most games start pushing into the client tens to hundreds of parts at once. With these internet costs forced on most players? Roblox may as well start a torrenting side business.

  • Very performance intensive on the client. Of course, streaming enabled DOES improve initial load times and it DOES reduce initial memory usage. All at the cost of generating constant stuttering (that can be felt and seen on high end hardware mind you) due to instance streaming, massively increased networking costs which of course translate directly to more compute spent on processing packets, gameplay suddenly pausing in the middle of play due to the server not being able to load all instances enough or the client not being able to get them in time (i had this exact issue happening to me way too many times) and inflated memory usage (yes, memory will be lower at first. Only for it to keep going up to a higher threshold than if streaming enabled wasnt used).

  • Insanely degraded visuals. Streaming enabled is VERY generous when it comes to offering the client all the lod blobs it can give. Now… i know SLIM exists and i do believe its an improvement over these… blobs. But i have to then ask about potentially higher network costs considering the higher quality assets along with the fact that streaming… wont be streaming much rendered geometry? The examples shown so far are good in terms of quality, yes. But will this just mean that streaming enabled suddenly no longer does anything to lift some gpu work? Sure, maybe some easier batching or some lower resolution textures. But… the triangle counts remain roughtly the same…

You have to understand, forcing streaming enabled, a massive performance hog just to fix replication being 50% more demanding per-instance or whatever is NOT a good fix and is in no way shape or form good for the longevity of the engine and the platform. Especially not when said streaming can be 5000% more demanding than whatever costs in compute the new replication system brings.

Listen, i dont mind streaming enabled being a thing nor do i mind one click solutions nor do i mind things that ā€œjust workā€ (Dont even get me started on the ā€œjust workingā€ creation engine and starfield man :confused: . Quite ironic.). But what i do mind, along with TONS of other developers, is the fact that we are being forced onto these one click ā€œjust worksā€ solutions while we’re only being told that they somehow make things ā€œbetterā€. No they do not. Let’s not lie to ourselves or to the other thousands of developers that have been fed this streaming enabled lie. In good faith here you cannot tell me that the moment youre being forced to use magic technology that ā€œjust worksā€ into your own work youll just eat it up and be happy. You wont be, i wont be, nobody here will be. Yet… we have to be the victims of this?

I will repeat what i have said previously in another post. Server Authority, a amazing actually game changing feature, is nothing more than dead weight because it is being paired with a piece of technology that is nothing but destructive. I’m sorry if this is rather mean but you sure as hell wont be happy to get a fancy new computer that has all the fancy new and powerful stuff only to also come with a bolted on power supply prone to catching on fire if you dare to push it anywhere past 100 watts. I have a very hard time understanding why roblox is choosing to die on this hill. What’s insane to me is how worthless overall these posts made by engineers asking for feedback seems to be. Outside of bug fixes, VERY little advice actually gets taken into consideration and what we will end up with at best is a couple vague excuses as to why we cant do X thing or why Y is the way it is. And it’s a damn shame. Because its clear how active you all working at roblox are being about all of this. I dont think there has been a single day on this this forum where i have not seen at least a couple engineers actively engaging with people.

8 Likes

The irony was intended, because this is a Beta and my theory on how things will ā€œjust workā€ are surely going to explode in my face once more creators are testing the exsting functionalities and poke holes in what we’ve shipped.

on Streaming + Server Authority.

Look, I get it. Every game developer/creator on Roblox knows what their content needs out of the engine better than any individual Roblox engineer or even Roblox executive does. That`s just the nature of how big the platform is and how many creators there are. Roblox is always stuck with the hard job of figuring out how we can deliver the best tech for the most amount of people. This might mean that sometimes when we ship something, it’s not immediately the best thing for everyone in the ecosystem, but we hope it’s the best for the most amount of people as possible.

Server Authority has been an insanely complex project, considering how long of a legacy Roblox has with Client Authoritative player physics. I’m not gonna pretend that there isn’t a world/alternate reality where we toss even more engineers and QA at the issue and create a Server Authority that works when Next Generation Replication is disabled, or if DeferredSignals are disables, or if Streaming is disabled… but my experience with truly difficult projects like this is that tossing more engineers and more people at the problem rarely creates a good cohesive final product and results in shipping something mediocre with lower quality.

We’re still internally hyper focusing on A LOT of areas that are fundamental requirements to make Server Authority an actually good product for the Platform.

Things like:

  • Resimulation Performance on Low End Devices
  • Server Performance
  • Mispredictions on Simple and Complex Interactions (As you posted in the other thread, with running on a Ball not working by default)
  • Fixing the remaining ā€œClient Authoritative Legacy Logicā€ (don’t get me started on figuring out how to make Tool Welds server Authoritative)

Streaming team has built and optimized a lot of really complex systems that are not apparent to creators/developers under the hood because the only way they experience them is via things like Atomic Streaming. But internally these systems make a ton of internal calculations to group instances into higher level ā€œSetsā€ that make it much easier for us to prioritize and group replicated data. They will also help us identify which instances need to be predicted when a player interacts with something physically. Without these systems Server Authority will just be a big bag of APIs that barely work unless you spend two years reading a manual and understanding Roblox Networking Architecture.

On an orthogonal level, a chief concern of ours is making Server Authority work for low-end devices that can barely simulate their own avatar, much less 200ms of resimulation every time they mispredict. Having Streaming be able to maintain a much lower Client Instance footprint will help with achieving that goal. And as we’ve mentioned previously, Next Gen Replication gets perf benefits from not having to prioritize absolutely everything in the world.

Being able to rely on these systems being there, and not having to pull them out and make them stand-alone, or even duplicating them from scratch, gives us bandwidth to focus on the fundamental issues that we still need to resolve before Server Authority is a viable product to use in live games. We could in theory, drop the requirements and do the extra work I just mentioned, making Roblox a much more complex engine with a much bigger testing surface, where QA will now have to do 2 to 3 times as many tests to make sure every combination of settings still works as expected, but this is going to distract from wrapping up and polishing the fundamentals that we are still in the process of building out and finishing as part of this Beta.

I’m not going to pretend there was some higher-up boogeyman telling us to put Server Authority behind Streaming, I was one of the people that pushed for it due to the above technical reasons. So while I know this answer is still unsatisfying, please understand the choices we have to make. We’re not ruling out a possible future where, once Server Authority is locked down, polished, fully tested, and the most amazing Server Authority implementation on the planet, where we can take the time and maybe decouple, taking on that extra tech complexity, but at this time it would negatively impact Server Authority.

40 Likes

I appreciate the response a lot. Rarely i see responses from engineers past a couple vague words when it comes to things like this honestly.

Yeah but like… instances will have to eventually be streamed in and out. Considering that streaming enabled is rather slow as is, wont this result with such device stuttering like hell either way? The way i see it right now is that youre saving 500 ms of compute on average just to replace it with 2500 ms of compute every couple of seconds. Truthfully? It’s not like i know how streaming enabled truly works under the hood. Not like anyone here, except you probably, has ever really seen how it works. But so far these are the results i am expecting from it sadly.

Still, i really appreciate your response. But now i would like to ask a rather common but also crazy question. And yea i know about the logistical nightmare, the coffee industry booming, the insane movie production level costs and whatever else stuff that entails this question. But really… why isnt roblox investing in a new engine? Theres probably a billion reasons you along with other people have. But right now im starting to see more and more engineers throwing the finger at the engine itself for X Y and Z. And sure, i could be all angry and say that its all excuses so they dont need to do anything ever but… i mean i cant really blame them. I think everyone on the platform will agree when i say this engine is janky as hell. A good chunk of developing something on roblox is pretty much just fighting with the engine to get it to do what it wants. My own latest example is getting the engine to update instances in the same frame i threw them out of parallel back into serial.
You send them into another actor thats supposed to be your half baked serial thread via BindToMessageParallel then run task.synchronize() right after. It works.

So again i have to ask, how come roblox isnt investing in a new engine? I mean a new engine could fix every issue the current engine has and allow for even more technology thats also implemented 100x times better (since yknow, it wont be fighting code from over a decade ago that was designed to run just 3 simple legos on a pentium) and much more performant. I dont think i need to remind you of how many people are asking for X Y and Z only to be told off that it cant be done for whatever reason.

I mean even right here youre basically talking about fighting the engine to support some ancient instances.

And sure yeah, the biggest issues would have to be supporting all games only to end up with the same issues as the current engine because of said required legacy support. But at this point why not also keep the old engine under some LTS branch and start fresh on a new one? Maybe it wont be the most convenient thing for all developers but i feel like this could be a big long term investment for roblox perhaps. Not saying roblox should be Unreal Engine Blox 5 or whatever but at least being able to get close to some of these more modern engines while being 10x more performant and easier to use seems like a pretty big deal to me. Maybe you guys already have some ideas for a new one, who knows?

I mean hey, what do i know? If it was up to me then i would have had some extraterrestrial rendering pipeline that runs on 7 different gpus at once for peak performance. (Trust in rendering the shadow atlas on another gpu dream :folded_hands:)

3 Likes

Thank you for the detailed communication. I think many power developers would still prefer access to more APIs, while also providing the existing ones as-is for most developers. I would not mind having a lot of caveats and less support for say, more precise control out of stream in/out. As it is now we do need to pull and reimplement a lot ourselves anyway- and that means trying to hack the guard rails into moving aside anyway. Which does itself often create spurious bugs.

1 Like

This is a whole can of worms I’m not really prepared to talk about at length, because the topics you touched on are at the scale of ā€œHow to run Roblox as a businessā€, and I spent my 12 years working here primarily focused on the Game Engine and it’s capabilities. So I can riff on some thoughts that are my own, but don’t take this as me speaking for the company.

Roblox is constantly evolving and improving the engine, this is pretty easy to see if you look at what it looked like 10, 5, 2 years ago. We’re constantly refactoring things under the hood for performance, new features, and a lot work on architectural sustainability.

Any good engineer probably should ask themselves ā€œshould I just re-write this?ā€ as a way to re-validate decisions or simply for self reflection on their prior work. A New Engine has an upside of being able to evaluate legacy architectural decisions more easily, but at the cost a lot of engineering resources and significant potential risks for the thousands of small businesses that already have content on Roblox today (whether this is because LTS support isn’t enough for what they need, or whether they now need to migrate to Roblox 2.0…).

But right now im starting to see more and more engineers throwing the finger at the engine itself for X Y and Z.

I hope you didn’t interpret my explanation of the systems we use for Server Authority from Streaming as me ā€œblaming the engineā€. Every Game Engine, and every complex piece of technology is going to have it’s caveats. Good software engineering systems generally have an architecture that defines some base level rules for how the system should be extended and what capabilities it should be able to add in the future and when developers make changes they have to consider that architecture, which comes with constraints.

You then have two choices, expand the architecture, or just hack some garbage on top of it ignoring the architecture… but you get the feature you want! Most real software that people actually use is a weird mixture of both of these. The more mature software is probably a much larger portion of proper architecture, with some hacks, while the least mature software is mostly hacks and little bit of architecture.

The only Software I can imagine being perfectly architected is software described by Academic Papers, and that’s because it’s easy to make things perfect ā€œin theoryā€. So, in connection to my comment:

Fixing the remaining ā€œClient Authoritative Legacy Logicā€ (don’t get me started on figuring out how to make Tool Welds server Authoritative)

Even if we built a brand new game engine from scratch, it’s not like all of a sudden figuring out how to support Tools and Equipment on Roblox 2.0 would go away, right? All it would mean is that we wouldn’t be able to just use the old client-authoritative logic, we would have to re-implement an equipment system from scratch. And we would still have to spend a lot of time thinking about how that systems interacts with existing Roblox content, or decades of scripting practices.

Generally engineers don’t make posts like this because explaining the logic behind some of our decision making is kind of like leaving yourself vulnerable for attack. By giving you details on how we made these decisions, it’s technically more ammo for you if you wanted to nit-pick those decisions and double down. If you think about it, there really is no benefit to the company/engineer to do it since it’s virtually impossible to truly communicate the lifetime of learnings that led to these decisions in a blog-post style. But my hope is that it at least puts a somewhat human face and explains the rationale, even if you don’t necessarily agree with some of the technical decisions.

Tech is interesting, especially software. There are near infinite ways to accomplish the same things, and because of that nature there are infinite number of ways to critique something.

31 Likes

I heavily agree with this part. This applies to almost every software there is today, you cannot understand the decision making completely without being involved in the creation of the software. Outside criticism is great, and allows you to achieve perhaps a better system and architecture, but it is still outside. You have to look at the system from both in and out in order to make a good decision.

Nice to see its out. Can I ask is server authority the reason why shapecast margins were put on hold for now since the physics team is working on server authroity instead

2 Likes

I can’t speak for the Physics teams except to say that the team is much bigger than just the folks helping with Server Authority.

1 Like

I’ve edited the original post in this thread to include some code samples to help people get around some of the Known Issues we described in the original announcement.

This might be stupid to ask, but can RunService:BindToSimulation also fire more than once on the same frame on the server? I know it runs multiple times on the client when there’s a mispredict, but does it also try to ā€˜catch up’ if the server’s ā€˜framerate’ is too slow?

If this is the case, then doing something like spawning a deferred task to destroy an object would be unsafe, no? If the framerate drops to 30 and your frequency is set to 60, then the callback would run twice, and you would spawn two threads.

Also, I noticed the delta time is always the same no matter what the actual framerate is (Hz60 is always 0.0166). Is this intentional?