Release Notes for 456

Notes for Release 456


Client Difference Log

API Changes

Added Property float Sound.RollOffMaxDistance  [NotReplicated]
Added Property float Sound.RollOffMinDistance  [NotReplicated]

Added Function void AssetManagerService:InsertAudio(int64 assetId) {RobloxScriptSecurity}

Added Tag [Deprecated] to Property Sound.EmitterSize
Added Tag [Deprecated] to Property Sound.MaxDistance

Changed the parameters of Function UnvalidatedAssetService:AppendTempAssetId 
	from: (int64 id, Vector3 lookAt, Vector3 camPos, string usage)
	  to: (int64 userId, int64 id, Vector3 lookAt, Vector3 camPos, string usage)

Changed the parameters of Function UnvalidatedAssetService:AppendVantagePoint 
	from: (int64 id, Vector3 lookAt, Vector3 camPos)
	  to: (int64 userId, int64 id, Vector3 lookAt, Vector3 camPos)

Changed the parameters of Function UnvalidatedAssetService:UpgradeTempAssetId 
	from: (int64 tempId, int64 assetId)
	  to: (int64 userId, int64 tempId, int64 assetId)

(Click here for a syntax highlighted version!)


How efficient is table.clear compared to iterating through a table and setting its keys to nil?


How efficient is table.clear compared to iterating through a table and setting its keys to nil ?

Much much faster, like, >100x.

The question you should be asking is: How efficient is table.clear compared to throwing away the table and allocating a new empty one?

The answer to that question is that it will be about 2x faster to re-use the capacity of an existing clear’d set/map compared to allocating a new one, even ignoring the benefit of not throwing away a table which adds GC pressure.



May I ask why the replacement was made and why it would be best suited for Sound.EmitterSize and Sound.MaxDistance to be renamed to something longer when scripting or configuring? It seems like a nice change, but an answer would be nice about this change.

With that, what is the service and function of AppUpdateService / AppUpdateStatus? Will it be able to be configured by developers or only access for engineers to create and enable for development purposes?


Sorry if this is a dumb question but do these performance benefits include tables that don’t have numerical keys?

There are instances where I fill a table every frame with a dictionary to instances i.e [instance] = true , then (set it back to {}) next frame.


Glad to see that a U-turn on the BodyAngularVelocity property happened, AssemblyAngularVelocity is a much more descriptive name.

Does this mean the announcement of the change is now obsolete?


EmitterSize was an extremely misleading property name. It actually referred to the radius of the emitter, despite “size” meaning the diameter of an object in all other places where it’s used in the Roblox API. That’s the primary reason for the change.

Yes, that’s actually the primary case where it has a benefit! Both the array part and hash part will have their capacity saved when using table.clear.

You could already clear arrays somewhat efficiently already by using table.move:

table.move(EmptyTable, 1, #tableToClear, 1, tableToClear)

Though table.clear(tableToClear) will be about 2x faster than the above code even for clearing arrays.

Does this mean the announcement of the change is now obsolete?

Yes, expect a new / updated announcement post once everything is in order.



Is this intended?

It was extremely useful to have MaxDistance replicate when working with Sounds, having this property not replicate this value to the client will undoubtedly make everything sound related a pain to work with. Any chances this can be changed?


This looks epic:

I’ve always wanted to make my game available on console, but coding in the UI elements was always too daunting. Does this mean that the compatibility requirement will be removed for putting your game on the Xbox platform now that native support for non-gamepad elements is available?

1 Like

Have no idea why this was initially locked to Roblox, but appreciate granting developers this function. I recall a couple of feature requests asking for consolidation of purchase prompt APIs or a separate function to prompt for bundles. Forgot that one existed but was, for whatever reason, locked.


Will the new “Virtual Cursor” for gamepad be optional? I’ve optimized my GUI navigation for the existing Xbox selector that is moved around with the DPad, and removing that from the game would make it so much harder to play with a Gamepad.


The NotReplicated tag is misleading and IMO should be removed from the API Dump entirely.

What it’s trying to say is that the property is not DIRECTLY ITSELF replicating across the server/client boundary. However, it COULD still replicate across the server/client boundary if it’s inherited from some internal state which is replicated, or maybe it reflects off of another existing property, such as the ones that were just deprecated.


Seems like a limitation of the API system. Maybe a tag for read the documentation this may have unexpected behaviour should be added for edge cases like this.


Looks like it’s only purpose is to invoke updates, Engineers might have to be me up here

Its only two methods, CheckForUpdate and PerformManagedUpdate are both locked behind RobloxScriptSecurity


Clearly 100x is an exaggeration :wink:

the code local empty = {} local N = 10000

while true do
local tna = table.create(N, 42)
local tnb = table.create(N, 42)
local tnc = table.create(N, 42)

local tn0 = os.clock()

for i=1,#tna do
	tna[i] = nil

local tn1 = os.clock()


local tn2 = os.clock()

table.move(empty, 1, #tnc, 1, tnc)

local tn3 = os.clock()

local tha = {}
local thb = {}

for i=1,N do
	tha[tostring(i)] = i
	thb[tostring(i)] = i

local th0 = os.clock()

for k,v in pairs(tha) do
	tha[k] = nil

local th1 = os.clock()


local th2 = os.clock()

print(("array: loop %d ns, clear %d ns, move %d ns"):format((tn1 - tn0) * 1e9, (tn2 - tn1) * 1e9, (tn3 - tn2) * 1e9))
print(("hash: loop %d ns, clear %d ns"):format((th1 - th0) * 1e9, (th2 - th1) * 1e9))
print("sanity check: ", next(tna), next(tnb), next(tnc), next(tha), next(thb))


Example output from a Windows build (I was too lazy to use a rigorous benchmarking solution; I hear @boatbomber’s plugin is pretty awesome):

array: loop 57800 ns, clear 4499 ns, move 87799 ns
hash: loop 182899 ns, clear 11900 ns
sanity check: nil nil nil nil nil

So table.clear should be 13-15x faster than a loop on large arrays. And table.move doesn’t actually work very well here right now…

[fun fact: if you want the array clear loop to go faster, try declaring local xnil xnil = nil (no typos here) outside of the loops and using xnil instead of nil; this makes the array loop go ~10% faster, which is an optimization opportunity and we will likely improve this in the future]



Just my luck, literally LAST NIGHT I finished writing my own module for this and I added it to my game. Thank for you making this an official feature, its something that will really help a lot of developers.


Although this question is not specifically related to this version, it has to do with all new version releases.
Every time a new version is released, the installation folder in Windows 10 changes:

This current version was inserted on this folder:

C:\Program Files (x86)\Roblox\Versions\version-aa7766fcc7cb4906\RobloxPlayerBeta.exe

The part with aa7766fcc7cb4906 will be different each time a new version is released.

This makes it very difficult to manage program rules on windows.
For example, I want to force Roblox Player to use a specific graphic card on my PC:

There, I have to specify a full path to Roblox Player (also Studio).

However, for each Roblox update, I have to redo this rule in my windows, since the Roblox folder will be changed.

How to force Roblox Player and Studio to be installed on the same folder every time?