Sending a TweenInfo to client over a remote event receives nil

Attempting to send a TweenInfo datatype to a client using a RemoteEvent will result in the client receiving nil but no error or warning being thrown. Any other arguments sent will be received as normal. Possibly intentional, but inconvenient and lack of warning is confusing.
Repro file:
Place1.rbxl (16.0 KB)

23 Likes

I’m really curious, how are you using this?

6 Likes

Yeah, really curious as to why you need to send tween information from the server to the client.

perhaps its not a matter of why, but a matter of why not?

14 Likes

A machine has a lot of read outs on multiple surfaceguis, including a bar graph. It was easier and more organised to have the server script send a tween to a single client side script that handles all the games tweens than try and set up a series of local scripts that run the surface guis.

Of course it’s fairly easy to work around, either setting up enums for different tweets or sending the info as separate arguments, but a warning would be appreciated.

TweenInfo is not the only one that suffers from this, BrickColors and Color3 also are transformed to nil.

EDIT: This first part was incorrect, my bad.

When these are created in the server they don’t replicate into the client so when passing them as arguments the pointer which holds the info will be pointing to nil in the client.

Related
http://devforum.roblox.com/t/replicating-orphaned-instances-via-remoteevents-remotefunctions/15007?source_topic_id=31937

2 Likes

Color3 too? I remember using it over network, but I could be wrong

Yeah, my guess is that roblox objects in general do not pass through remote events unless the location where they are stored is shared by both the client and the server.

I’m pretty sure Vector3s get sent tho

I’m currently networking Color3 values without any issues. This is incorrect.

2 Likes

Would you mind posting an example? I cant seem able to do it

Just put a RemoteEvent in game.ReplicatedStorage and then used these two scripts:

Script in game.ServerScriptService

game.ReplicatedStorage.RemoteEvent.OnServerEvent:connect(function(...)
	for i, v in pairs({...}) do
		print(i, typeof(v), v)
	end
end)

LocalScript in game.StarterPlayer.StarterPlayerScripts

game.ReplicatedStorage.RemoteEvent:FireServer(Color3.new(1, 0.1, 0.5))

Output was

1 Instance Osyris
2 Color3 1, 0.1, 0.5

Color3NetworkTest.rbxl (12.8 KB)

1 Like

It does work, I’ll need to double check my code then.

Thanks!

4 years later and it’s still not fixed, I’m not entitled to knowing how the engine works, but I feel like something this small isn’t hard to fix, I’m assuming it was put off because there aren’t many use cases.

I use TweenService for certain effects in my games and I’d like to have a clientsided setting so some players who don’t want to view the cosmetic effects won’t have to see them.

Not being able to send over a simple argument like TweenInfo makes this difficult for no reason, where as now I have to send over all tween info seperately and create it all over again. Allowing to pass a TweenInfo argument would really benefit me and future developers.

Repro.rbxl (22.4 KB)

15 Likes

Well sending all the information needed for a tween would be so easy and you could use one local script for all tweens who would not want that?

I hope this gets fixed soon.

1 Like

@madattak probably worth moving this over to the feature request category and renaming it.

@ people above: bumping this every few days is pointless because this is not a recent regression.

i had a modulescript to make a custom tween take damage
client fires the server then with “Client” or “Server” as the first arg
if it is Client then the Server will Call FireAllClients then all Clients will retrieve this.
it is a modulescript so that client and server can easily access the updated version of the script and i dont gotta change anything from the client or server.
it would check if the tweeninfo is actually a tweeninfo or it will use a bounce tweeninfo as the default tween.
heres the modulescript

TweenService=game:GetService("TweenService")

return(function(Humanoid, Damage, TInfo, Yield)
	local Tween=TweenService:Create(Humanoid, ((typeof(TInfo)=="TweenInfo" and TInfo) or TweenInfo.new(9, Enum.EasingStyle.Bounce, Enum.EasingDirection.Out)), {Health=Humanoid.Health-tonumber(Damage or "12")})
	Tween:Play()
	if Yield then
		return Tween.Completed:Wait()
	end
end)

oof it was working but some reason it stopped randomly.
i do both client or server so that the tween can be smoother bc it is on client.
server may not be as smooth but replicates better.
but im good at making client replication.

ok, i’m so so so sorry for bumping, but i’d like to share this smart workaround i found for getting around this until they decide to fix this.

So first, create a module script in replicated storage called “TweenInfos” or something like that, and type this:

local tween_infos = {}

return tween_infos

we will store our tween infos inside this module.

Now from here, we need to add the tween infos inside this tween_infos table

storing the infos inside the module:

local tween_infos = {
	["TWEENINFOIDHERE"] = TweenInfo.new(2) -- tweeninfo here
}

return tween_infos

next, we will send the id of the tween info to the client, which will then get the tween info and play the tween!
local script:

local replicated_storage = game:GetService("ReplicatedStorage")
local tween_service = game:GetService("TweenService")
local tween_remote = replicated_storage:WaitForChild("TweenEvent")
local tween_infos = require(replicated_storage:WaitForChild("TweenInfos"))
tween_remote.OnClientEvent:Connect(function(object:Instance, info_id, goals)
	local success, info = pcall(function() -- do this so the script wont break if the info id is invalid
		return tween_infos[info_id]
	end)
	if success and info then
		tween_service:Create(object, info, goals):Play() -- finally, play the tween!
	else
		warn(string.format("could not found tween info with id of %q", info_id)) -- if the info isn't found, we'll add a warning to the output so we can debug
	end
end)

this is our server script

local replicated_storage = game:GetService("ReplicatedStorage")
local infos = require(replicated_storage:WaitForChild("TweenInfos"))
local tween_remote = replicated_storage:WaitForChild("TweenEvent")
local part = workspace.Part
local info_id = "ColorTween"
local goals = {
	Color = Color3.fromRGB(75, 93, 255) --- pastel purple
}
task.wait(2) -- so we can see the tween
tween_remote:FireAllClients(part, info_id, goals)

there we go. hope this helps :slight_smile:

the final result is really nice

To work around this bug I just FireServer/Clients with the TweenInfo elements then create the TweenInfo on the other side manually

TweenEvent:FireClient(Part, {Transparency = 1}, 1, Enum.EasingStyle.Linear)
TweenEvent.OnClientEvent:Connect(function(Obj, Table, ...)
    TweenService:Create(Obj, TweenInfo.new(...), Table):Play()
end)

Also has this bug been fixed yet as not to require this workaround?

2 Likes

Hi there! Thanks for the report. I’ve filed the ticket as a feature request for the future, but the TweenInfo data type was never meant to replicate. For now, as other users have done, I recommend replicating the data manually and creating the TweenInfo when received.

3 Likes