Release Notes for 478

Notes for Release 478

40 Likes

Client Difference Log

API Changes

Added Property Enum<NewAnimationRuntimeSetting> Workspace.AnimationWeightedBlendFix [NotScriptable]

Added Function void StudioService:ShowSaveOrPublishPlaceToRoblox(bool showGameSelect, bool isPublish, bool closeAfterSave) {RobloxScriptSecurity}

Added Event StudioService.SaveLocallyAsComplete(bool success) {RobloxScriptSecurity}

Added Enum NewAnimationRuntimeSetting
	Added EnumItem NewAnimationRuntimeSetting.Default : 0
	Added EnumItem NewAnimationRuntimeSetting.Disabled : 1
	Added EnumItem NewAnimationRuntimeSetting.Enabled : 2

Added Tag [Deprecated] to Property Workspace.FilteringEnabled

Added Tags [Hidden] [Deprecated] to Property BasePart.BackParamA
Added Tags [Hidden] [Deprecated] to Property BasePart.BackParamB
Added Tags [Hidden] [Deprecated] to Property BasePart.BackSurfaceInput
Added Tags [Hidden] [Deprecated] to Property BasePart.BottomParamA
Added Tags [Hidden] [Deprecated] to Property BasePart.BottomParamB
Added Tags [Hidden] [Deprecated] to Property BasePart.BottomSurfaceInput
Added Tags [Hidden] [Deprecated] to Property BasePart.FrontParamA
Added Tags [Hidden] [Deprecated] to Property BasePart.FrontParamB
Added Tags [Hidden] [Deprecated] to Property BasePart.FrontSurfaceInput
Added Tags [Hidden] [Deprecated] to Property BasePart.LeftParamA
Added Tags [Hidden] [Deprecated] to Property BasePart.LeftParamB
Added Tags [Hidden] [Deprecated] to Property BasePart.LeftSurfaceInput
Added Tags [Hidden] [Deprecated] to Property BasePart.RightParamA
Added Tags [Hidden] [Deprecated] to Property BasePart.RightParamB
Added Tags [Hidden] [Deprecated] to Property BasePart.RightSurfaceInput
Added Tags [Hidden] [Deprecated] to Property BasePart.TopParamA
Added Tags [Hidden] [Deprecated] to Property BasePart.TopParamB
Added Tags [Hidden] [Deprecated] to Property BasePart.TopSurfaceInput

Removed Function DataStoreService:GetDataFromEmptyScopeDataStoreAsyncTemporary

(Click here for a syntax highlighted version!)

22 Likes

What API is this change talking about? DataStoreService :GetDataFromEmptyScopeDataStoreAsyncTemporary()?

It’s not clear on which API.

9 Likes

They’re talking about the datastore API for consistency checking, it should be worded better IMO as this has confused me and other developers.

See: [Update] DataStores Incident: Data Consistency Checker API - #16

4 Likes

@LuaCow (sorry to shoot the messenger; not sure how to get the right person’s attention here)


I have a big concern about this one

Is UserInputService.KeyboardEnabled still the only reliable way to tell whether a user is on a Desktop or Mobile device? And if so, is this likely to become unreliable in the future?

I can’t use UserInputService.TouchEnabled because of touchscreen laptops. So I’ve been relying on the fact that KeyboardEnabled is always true for desktop devices (whether or not a keyboard is actually plugged in) and always false for mobile.

This is super important for UI development, and I don’t want to have to manage state changes when keyboards/touchscreens get plugged in and out and adjust the entire UI layout to compensate. It’s much simpler to have 1 UI behavior per device.

Unfortunately, the tools for managing this are super limited right now, because AFAIK there’s no API for actually determining a player’s device type.

This is locked to CoreScripts, so this is a major issue:
https://developer.roblox.com/en-us/api-reference/function/UserInputService/GetDeviceType

11 Likes

This has been stated before on many other threads: making your UIs work based on the available inputs is a code smell. Your UI should adapt to whatever a user throws at it, oh say my BlackBerry KEY2 which has a built-in touchscreen, keyboard, trackpad on the keyboard, and maybe a gamepad via USB. I actually had a few games I played on mobile and wasn’t able to continue because they blocked touch inputs and required using my keyboard.


What I am surprised to see is UITheme being removed and not being mentioned anywhere in the release notes or other announcements. The intent was to move to Studio.Theme in settings and not rely on fixed themes in the future, but this broke a lot of plugins by abruptly removing it instead of deprecated it. This change seems bizarre to me.

9 Likes

The UI Theme property was deprecated in version 418, and the UITheme EnumItems were deprecated in version 365. These deprecations were more than a year ago, so it doesn’t seem that abrupt.

5 Likes

We’ve taken action to avoid stuff like that in the future. All future settings fields will be RobloxScript security, and be exposed user scripts through a proper API elsewhere instead if appropriate, an API which is designed so that we can guarantee future compatibility and support for it unlike the settings fields.

5 Likes

When it comes to games meant to scale on the platform, I disagree that this is a code smell. I want to simplify what I show the player, and knowing what the primary method of control/input is on a player’s platform is paramount. It doesn’t make sense to show keybinds or require mouse input on mobile, and it doesn’t make sense to ignore it on desktop.

One critical difference is the amount of space mobile controls takes on the UI HUD. That needs to be different for mobile and desktop devices, and using mobile HUDs on a touchscreen laptop is really bad, as is using a desktop HUD that covers mobile controls.

I’m guessing you’re indirectly answering my question by saying that KeyboardEnabled isn’t reliable though?

6 Likes

You should be dynamically adapting this through UserInputService:GetLastinputType() and UserInputService.LastInputTypeChanged ideally, instead of reading from those {Device}Enabled properties once.

8 Likes

Dunno about LastInputTypeChanged because I would rather not support all and every mode of control (I’m not supporting gyro or gamepad controls, for example)

I made a module for dynamically changing input like you suggested, since it seems that certain race conditions can make it awkward to determine one input mode and be done. Seems like TouchEnabled/KeyboardEnabled is better to use here though. The philosophy behind this is that there should be one “Primary input mode” at a given time, and the player should have to use one primary input mode, whether it’s touch or keyboard and mouse (in the case of my game). I wouldn’t want anyone with a touchscreen laptop swapping over to iPhone/tablet UI just because they tapped the screen; it would make more sense for that to act as a mouse input and keep the keyboard and mouse controls/UI. Perhaps for gamepad and certain other games this method makes sense though. Also, bottom line is, if they don’t have a “touch gui” for movement controls, it’s not worth switching their entire UI to touch since they have no way of moving around otherwise.

EDIT: Don’t use this code. See my reply below

--!strict

local PrimaryInputState = {}

local UserInputService = game:GetService('UserInputService')

local EV_PRIMARY_INPUT_MODE_CHANGED = Instance.new('BindableEvent')
local primaryInputMode = 'Touch' :: string -- :: 'Touch' | 'KeyboardMouse' | 'Gamepad'

local function setPrimaryInputMode()
	local playerGui = game.Players.LocalPlayer:FindFirstChild('PlayerGui')
	if playerGui then
		if playerGui:FindFirstChild('TouchGui') then
			primaryInputMode = 'Touch'
			return
		end
	elseif UserInputService.TouchEnabled and not UserInputService.KeyboardEnabled then
		primaryInputMode = 'Touch'
		return
	end
	
	primaryInputMode = 'KeyboardMouse'
end
function update()
	local savePrimaryInputMode = primaryInputMode
	setPrimaryInputMode()
	if savePrimaryInputMode ~= primaryInputMode then
		EV_PRIMARY_INPUT_MODE_CHANGED:Fire()
	end
end
spawn(function()
	local PlayerGui = game.Players.LocalPlayer:WaitForChild('PlayerGui')
	update()
	PlayerGui.ChildAdded:Connect(function(child: any)
		if child.Name == 'TouchGui' then
			update()
		end
	end)
	PlayerGui.ChildRemoved:Connect(function(child: any)
		if child.Name == 'TouchGui' then
			update()
		end
	end)
	UserInputService:GetPropertyChangedSignal('KeyboardEnabled'):Connect(update)
	UserInputService:GetPropertyChangedSignal('TouchEnabled'):Connect(update)
end)

function PrimaryInputState.GetPrimaryInputMode()
	return primaryInputMode
end

PrimaryInputState.PrimaryInputModeChanged = EV_PRIMARY_INPUT_MODE_CHANGED.Event
update()

return PrimaryInputState
4 Likes

Is there any information that we can be delivered about this now or should we wait for announcements related to this change? Every single game I have ever developed for will be affected by this change because developers, be it me or someone else, have always assumed overriding behaviour. This is also critical as my Summer Accelerator project is animation-heavy so I need to be prepared in advance for this change should it hamper our development process. (Lead informed me we won’t be as affected by this change, just a few fixes to make. That’s good!)

I might need to be prepared to write a feature request about arbitrary animation priority, though even independent of this change I’ve never felt that four priorities was enough. Too hard to slot things correctly and I want to retain this overriding-like behaviour. Not sure how I’d accomplish it with weighting or if it’d have the same effect.

7 Likes

Second to this! Blending is nice, but it’s kind of chaotic to deal with with only four animation priorities. Also would be nice if these custom priorities would replicate.

5 Likes

Yes, there will be detailed announcements about this where you can make your concerns known. I’ll talk to someone about adding a note on scary sounding release notes items like this that a DevForum announcement will be coming with more details.

You can assume that anything that has a three-phase rollout property like this is going to go through a lengthy release process where there’s plenty of time for developer feedback / to adjust your code.

6 Likes

@tnavarts
This change broke at least three plugins I use.

One of them is the Nexus Embedded Editor plugin, that’s now broken and I utilize this plugin in a few places using Rojo projects since its actually pretty useful. I find it quite fun to use. This one isn’t too bad since I don’t use it often and its not necessary but still noteworthy.

Most notably, the Tag Editor plugin by Sweetheartichoke was completely broken and this plugin is necessary to my development, there is no way for me to update my game without using tags and this plugin I use pretty much all of the time. It got immediately updated just after this release so no problems there, but, a lot of my plugins are throwing errors left and right.

Additionally, @Quenty’s Class Converter plugin is broken now too and I use this pretty regularly as well for UI development because it makes going between different button and label types really fast, and, its pretty useful for changing between different part types too.

17 Likes

Hey everyone; sorry for the disruption wrt plugin breakage. We didn’t realize that many existing plugins rely on this - we are going to revert the removal of this property with a Studio patch tomorrow morning. Plugin authors are still encouraged to migrate to the new Theme API but existing plugins should start working again tomorrow.

16 Likes

I still think this API should be removed, just with more forewarning next time.

9 Likes

Okay so… now roblox is dynamically showing and hiding mobile controls now, and this conflicts with the way I’ve been showing/hiding mobile controls when navigating through menus. This seems to use the method Clonetrooper mentioned earlier with UserInputService.LastInputTypeChanged, so I guess because of this change he is right, but only because a flag got flipped.

I’m not sure how to hide mobile controls now though, cause I’ve been manually setting the Visible property of the JumpButton, and now roblox is doing this for me, leading to some really bad state management conflicts.

Side note: I’m completely unable to zoom in/out now on the mobile emulator, because pressing the “I” and “O” keys no longer do a pinch zoom, but instead switch the input method entirely.

Also, moving+rotating the camera at the same time doesn’t work on mobile + keyboard, leading to some very, very clunky controls.

This system needs to be rethought, and there needs to be much more transparency here when releasing a change like this that completely messes with the way I’ve designed my cross-platform compatibility.
@AllYourBlox (Sorry if I’m pinging the wrong person; it’s your name that shows up in the player scripts)

4 Likes

Also, I realized I haven’t really explained well how this recent flag flip messes with the way I handle mobile control UI conflicts.

Deep within the core camera scripts ( the “CameraInput” module, which I have forked+duplicated in my game when I switch between the default camera and certain custom cameras), the camera input itself detects the existence of the thumbstick area (but strangely not the Visible property of DynamicThumbstickFrame even though that’s what’s being changed with this new update???)

The side effect of this is that I cannot just hide the TouchGui when I show HUD elements that conflict with the mobile controls, since this means the bottom-left area will end up both moving the character and panning the camera at the same time.

My solution is to simply hide the jump button, as well as the joystick frames if they have not initially been made invisible or moved around. This allows me to design a HUD area that still lets you move around, but doesn’t show a joystick while that specific menu is open.

Now roblox is managing the visible state of these elements itself (at least when using the mobile emulator). According to the release notes, this only effects the emulator

But it really has me concerned, because I’m kind of left with a mess where now I have to entirely show/hide the mobile controls through TouchGui.Enabled, and as a consequence, entirely fork the camera module itself if I want to have consistent behavior on mobile devices that can connect a keyboard in the future. If the behavior on production mobile devices ever ends up being the same as what’s going on in the emulator, in which certain frames in the TouchGui get shown/hidden dynamically by the core scripts, these bugs with the camera module not being designed for this will still be present. The behavior of the camera module itself is dependent on the structure of this UI tree, which has been changed (seemingly for the emulator only??? but who knows where this is going in the future).

The thing that makes me the most upset about this is that I only knew about this change when I tried to zoom in/out pressing the I/O keys in the emulator, and I knew what the cause was because of this release notes. This seems like a type of change that requires an “ACTION REQUIRED” announcement post.

2 Likes