Client Difference Log
API Changes
Added Class TextChatCommand : Instance [NotBrowsable]
Added Property bool TextChatCommand.Enabled
Added Property string TextChatCommand.PrimaryAlias
Added Property string TextChatCommand.SecondaryAlias
Added Event TextChatCommand.Triggered(TextSource originTextSource, string unfilteredText)
Added Class TextChatConfigurations : Instance [NotCreatable] [NotReplicated]
Added Class ChatInputBarConfiguration : TextChatConfigurations [NotCreatable] [NotBrowsable]
Added Property bool ChatInputBarConfiguration.Enabled
Added Property TextChannel ChatInputBarConfiguration.TargetTextChannel
Added Class ChatWindowConfiguration : TextChatConfigurations [NotCreatable] [NotBrowsable]
Added Property bool ChatWindowConfiguration.Enabled
Added Class ImporterMaterialSettings : ImporterBaseSettings [NotCreatable] [NotReplicated]
Added Property string ImporterMaterialSettings.DiffuseFilePath [ReadOnly]
Added Property string ImporterMaterialSettings.MetalnessFilePath [ReadOnly]
Added Property string ImporterMaterialSettings.NormalFilePath [ReadOnly]
Added Property string ImporterMaterialSettings.RoughnessFilePath [ReadOnly]
Added Property string TextChatMessage.MessageId
Added Property Enum.ChatVersion TextChatService.ChatVersion {✏️NotAccessibleSecurity}
Added Property bool TextChatService.CreateDefaultCommands [NotScriptable]
Added Property bool TextChatService.CreateDefaultTextChannels [NotScriptable]
Added Function void DebuggerUIService:EditWatch(string expression) {RobloxScriptSecurity}
Added Function bool PublishService:PublishDescendantAssets(Instance instance) {RobloxScriptSecurity}
Added Function void StudioPublishService:SetUploadNames(string placeName, string universeName) {RobloxScriptSecurity}
Added Function TextChatMessage TextChannel:SendAsync(string message, string metadata = "")
Added Function Tuple VoiceChannel:AddUserAsync(int64 userId = -1) {RobloxScriptSecurity} [Yields]
Added Event TextChatService.MessageReceived(TextChatMessage textChatMessage)
Added Event TextChatService.SendingMessage(TextChatMessage textChatMessage)
Added Callback Tuple TextChannel.OnIncomingMessage(TextChatMessage message)
Added Callback Tuple TextChatService.OnIncomingMessage(TextChatMessage message)
Added Callback void ToolboxService.ProcessAssetInsertionDrop() {RobloxScriptSecurity} [NoYield]
Added Enum ChatVersion
Added EnumItem ChatVersion.LegacyChatService : 0
Added EnumItem ChatVersion.TextChatService : 1
Added Enum FontStyle
Added EnumItem FontStyle.Normal : 0
Added EnumItem FontStyle.Italic : 1
Added Enum FontWeight
Added EnumItem FontWeight.Thin : 100
Added EnumItem FontWeight.ExtraLight : 200
Added EnumItem FontWeight.Light : 300
Added EnumItem FontWeight.Regular : 400
Added EnumItem FontWeight.Medium : 500
Added EnumItem FontWeight.SemiBold : 600
Added EnumItem FontWeight.Bold : 700
Added EnumItem FontWeight.ExtraBold : 800
Added EnumItem FontWeight.Heavy : 900
Added EnumItem AnimationPriority.Action2 : 3
Added EnumItem AnimationPriority.Action3 : 4
Added EnumItem AnimationPriority.Action4 : 5
Added Tag [NotBrowsable] to Class TextChannel
Added Tag [NotBrowsable] to Class TextChatService
Added Tag [NotBrowsable] to Class TextSource
Changed the parameters of Event TextChannel.MessageReceived
from: (TextChatMessage textChatMessage)
to: (TextChatMessage incomingMessage)
Removed Property NetworkSettings.TrackDataTypes
Removed Property NetworkSettings.TrackPhysicsDetails
Removed Tag [NotReplicated] from Class TextChatService
(Click here for a syntax highlighted version!)
This is really good - I know there was another thread regarding this but being able to set an animation priority of any value would be great. More is helpful, but it’d be nice just to have wayy more control like with ZIndex/DisplayOrder stuff for GUIs
Don’t worry, these additional values are just a transitional measure that doesn’t preclude us from providing a more flexible long term solution.
Very cool! Any more info on what this method looks like / how it’s used? Would this end up changing behavior of task.spawn/defer
to return something similar to JS’s setInterval/setTimeout
?
Inspecting the release notes HTML reveals that the flag associated with the change is FFlagCancellableTaskMethods
. Overriding it enables task.cancel
, which accepts a thread
as a parameter and cancels that thread. task.spawn/defer/delay
all return the thread
.
Cancellable scheduled threads sounds like a dream come true. I know there’s been a lot of discussion about wanting to be able to somehow either stop something scheduled from running but it could be an engineering headache sometimes especially if the task already executes to figure good interruption points.
Personally for me this would come mostly in the case of delay:
task.delay(5, fadeSomethingOut)
-- Needs a check after 5 seconds that it should fade out
-- Needs a unique id so it doesn't conflict with other fades
I’m happy that at least some teams understand our needs as developers and trust us enough to make these kinds of decisions. I know some features have legitimate engineering blocks or they just don’t trust us for some reason, but when both aren’t a problem, we get such awesome features. Thanks!
As for more animation priorities, I am super happy about this. My current project is very deeply animation heavy and only having access to four priorities in 2022 seemed arcane and weird in terms of design. I also know there was that thread from some time ago where some people had issues with this as well (but… some of them were setting all their animation priorities to Action… so of course that’d be problematic). Paving the pathway to arbitrary animation priorities will greatly improve the animating experience and allow for real flexibility when deciding how to prioritise things.
Both great updates and bravo to the teams owning these features. <3
Is it possible to cancel a wait? or do we use task.delay for that?
Assuming that there’s going to be a thread for this when it’s released, I hope to see a use case and explanation for this new change
Yes… ish.
- You can always adjust your code splitting it into two different blocks:
foo(...)
wait(N)
bar(...)
foo(...)
local ident = task.delay(N, bar, ...)
-- To cancel:
task.cancel(ident)
- Technically you can cancel a waiting thread, but it won’t cancel the wait so to speak, it will cancel the wait and everything that comes afterwards. E.g.:
local mostRecentThing
local function doTheThing()
mostRecentThing = coroutine.running()
wait(N)
doStuff()
end
-- To cancel (though ill-advised since you may also be cancelling important stuff
-- that caller of doTheThing was going to do after that call)
task.cancel(mostRecentThing)
Any word on when Highlights might go live? I noticed it was bumped into 514 after it sat pending in 511. Now it’s been almost 2 weeks since 514 was published and there’s still no change.
I’m already trying to integrate Highlights into my games since the Instance exists, but it’s difficult to test.
Interesting.
Here’s some use-cases:
For every 5 minutes of playtime a player is rewarded. Every player has their own timer. If a player leaves it’d like to cancel that wait. However if the player is a Premium user then lower the timer in half. So if the player buys premium in-game I’d have to cancel the current timer and make a new one while also adjusting for the time already waited.
Another one:
Upon player join I run code, however if the player leaves while that code is still running I’d like to cancel the code.
Last one:
After a player uses a skill it goes on cooldown however if the player collects a token for refreshing all cooldowns I’d like to cancel the wait only.
Are these scenarios possible?
in case 1 and 2 I don’t want the code to run anymore.
(I understand that I should use Promise library for this, however I’m mainly curious of what task.cancel will do and what is possible for pure vanilla luau functions)
The simplest way I can think of to write that doesn’t involve task cancellation at all actually:
local NORMAL_DELAY = ...
local PREMIUM_DELAY = ...
local playerData = {...}
local function queueAward()
task.delay(NORMAL_DELAY, function()
if not playerData:hasPremium() then
playerData:awardNonpremiumStuff()
queueAward()
end
end)
task.delay(PREMIUM_DELAY, function()
if playerData:hasPremium() then
playerData:awardPremiumStuff()
queueAward()
end
end
end
queueAward() --> Initial call
Anything that involves “adjusting” / compensating timing will not be possible simply through cancellation. Either you’ll have to do checks against time every frame, or use multiply delays (like above) to make sure that there’s a piece of code ready to unsuspend at every potential point in time where you need to do something.
@RuizuKun_Dev
Personally this is what I would consider ““proper””, since it doesn’t involve any extra threads and doesn’t use cancelling. It’s less intuitive than cancelling though, I would almost prefer the ability to cancel a delay over this (even if it means some wacky behaviour).
There is, for example, coroutine.resume()
ing a waiting thread but that’s kind of hacky, not really best practice I would think, and, comes with that wacky behaviour I mentioned (e.g. thread scheduler wanting to resume the thread after its dead)
local PREMIUM_DELAY: number = ... -- Time for premium players
local NORMAL_DELAY: number = PREMIUM_DELAY * 2 -- Time for regular players
local function queueAward(player)
if player.MembershipType ~= Enum.MembershipType.Premium then -- Not premium, longer delay
task.wait(NORMAL_DELAY - PREMIUM_DELAY) -- Wait additional time
end
awardPlayer(player)
task.delay(PREMIUM_DELAY, queueAward, player)
end
task.delay(PREMIUM_DELAY, queueAward, player)
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.