Release Notes for 514

Notes for Release 514

36 Likes

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!)

14 Likes


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

17 Likes

Don’t worry, these additional values are just a transitional measure that doesn’t preclude us from providing a more flexible long term solution.

29 Likes

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?

9 Likes

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.

17 Likes

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

11 Likes

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

1 Like

Yes… ish.

  1. 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)
  1. 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)
2 Likes

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.

4 Likes

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.

1 Like

@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.