Allow for Server-Only instances (And possibly resolve issues which arise from Camera replication)

As a Roblox developer, it is currently too hard to have server sided modules and instances which will not ever replicate to clients, and will behave consistently in Team Create servers, and its additionally too hard to create Cameras for use in ViewportFrames without a script.

If Roblox is able to address this issue, it would improve my development experience because it would reduce usage of Camera instances for this behaviour, which is hacky, and leads to very unexpected results, especially in Team Create, and it would generally resolve a lot of issues, such as usage of Cameras in ViewportFrames mentioned in topics linked below.

What this could entail for the replication behaviour of Cameras:

As requested here:

This would allow for Camera instances to start being replicated to clients, and in TC to the server, which would fix usage within ViewportFrames as seen in this bug report (related to ViewportFrames).

This could, however, possibly change behaviour in old (or recent) games using Cameras to block replication to clients if it was not opt in, but, would likely in a majority of cases not cause anything bad to happen.

Here are a list of problems I can think of where a change to Camera replication like this could potentially cause game-breaking behaviour:

  1. A LocalScript is contained within the Camera and is expected not to run.
  2. Cameras are recreated on clients by client code where modifications are made to the specificly creaeted camera, and other scripts are not expecting a second Camera. (E.g. in ViewportFrames)
  3. Instances with special behaviour are contained within the Camera, such as Explosions, and the Camera is in a location where the Instances can activate their behaviour.

I would like for it to be opt-in, but that likely won’t need to be the case. The solution I propose below offers a way for this to occur smoothly. The only other bigger side effects I can think of if legacy behaviour wouldn’t be kept would be that devs wanting to protect server sided ModuleScript source from decompilation would then have them exposed to the client.

A few solutions

Personally, I believe that a few elegant solutions to this problem would be to have a property on instances, or perhaps a single class such as a Folder getting a unique property, or a unique class which carries the above behaviour. This would allow for clauses to exist within Team Create to prevent the sorts of desync issues Cameras currently cause (as mentioned in my bug report above)

Proposed solution:

I would propose that the best solution would be that all Instances get a CanReplicate property which is by default enabled. If disabled, the instance in live servers, not TC servers would simply not replicate to clients at any time, and, if it already had replicated, it would be immediately removed. In the case of services and Terrain, this property shouldn’t take effect and I’d expect it to be hidden/inactive. Instances within services such as ServerStorage and ServerScriptService I’d expect to keep the property available as well since instances could move out of these locations.

In the aforementioned changes to Camera behaviour, an elegant way to take advantage of a property like this for legacy purposes would be to in the case of old Cameras, make the property false by default. Newly inserted Cameras would then, like other instances get a true value. Additionally, this would allow for the game to make the CurrentCamera of the workspace non replicable which keeps existing behaviour.

Use cases:

This would be extremely useful for developers who wish to protect their ModuleScripts that are only used on the server from being decompiled because it would allow a supported way to do this that works in Team Create. This is currently one of the primary use cases of how Cameras currently behave. Additionally, developers who want certain instances to remain server only would be able to do so without being restricted to ServerScriptService or ServerStorage.

Lastly, this would allow for Camera usage in ViewportFrames to work within live servers and Team Create, and would allow for ThumbnailCameras and other Cameras to properly replicate in Team Create and live servers.

Mockups of what I think this could look like

Here is a mockup of what I think my feature request could look like in both cases (Using some mockup code from my own projects):
image
image

On the client, these would then appear as the following:
image
image

List of relevant bug reports & feature requests:

10 Likes

I do not understand the usecase exactly. Besides being a possible route to fix an issue with camera instances in team create, why do you need to have server only modules that live outside of ServerStorage or ServerScriptService?

2 Likes

You mean things under ServerStorage replicate to the client?!
That sounds too insane to be true… :cowboy_hat_face:

Do you have any proof ServerStorage replicates?

@VitalWinter,
The first, primary part of this is to fix two issues:

  1. Cameras in Team Create (e.g. ThumbnailCameras which are used to change the thumbnail of an uploaded asset, this behaviour makes it particularly difficult to work with, in fact, impossible in Team Create). This can lead to desyncs and a lot of strange/unintended behaviour.
  2. Cameras in ViewportFrames – Say you want to have a viewport frame with a predetermined Camera. Technically, this is possible, you can create a camera instance and move it or copy your own, and put it under the ViewportFrame, then you can set the ViewportFrame’s camera. The problem comes in in a server environment. The Camera will exist on the server when the game starts, but, it will never be replicated to clients, therefore, the predetermined camera no longer exists.

The second half is with developer’s current usage of Camera instances. Developers (including myself) use Camera instances to create server only locations outside of ServerStorage or ServerScriptService. This is useful if you need objects in a location outside of these services.

For example, as I mentioned server only modules. As for why you may want server only modules outside of these services, my second most common use case is server modules within GUIs (which would be especially true for ones being imported at runtime through LoadAsset or require), my first being within prefab sorts of models where a very large amount of copies of a server module may be made.

For example, say I have a build system in my game, and certain placeable objects need to have a module in them, to, maybe define certain behaviours or stats on the object. Well, my options are as follows:

  1. Put the module in anyway, and allow exploiters to decompile it. (I personally hate having server-only code possible to decompile, why should it be sent if its not used on the client?)
  2. Put the module in ServerStorage or ServerScriptService and somehow reference it, e.g. via a path, or an ObjectValue and do some complicated setup to direct requires this way, create copies of it first, etc. This is a rediculously messy way to do it, but, its the only alternative besides through Cameras. (And, I can’t use script.Parent to access the instance in this case!)
  3. Use a Camera instance, put the module within it, and require it that way. This is both clean to develop with, and I can simply use script.Parent.Parent to access the instance. BUT I am also relying on bad behaviour, and I can’t use it in Team Create.

A lot of developers, understandably, take option three, including myself. This, is bad. Not only has this behaviour been frowned upon by Roblox prior, it also leads to Team Create issues, and still isn’t a truly clean solution to the problem. There is no way to effectively, and cleanly create prefabs with server-only modules in them without a lot of hackiness or issues.

One further caveat, Camera instances do not allow physics to simulate for parts, and a lot of behaviour is missing from certain instances. You can’t have server only parts that can move, you can’t have server only constraints, etc.

@dispeller,
No, things under ServerStorage do not replicate to the client and I didn’t mean to suggest that was the case, I apologize for the confusion (Is there something specific I worded poorly?)…

Rather, the issue is that Camera instances are not ever replicated to the client, and (as mentioned in my reply to @VitalWinter) this both causes issues with things such as ViewportFrames, and is additionally used to prevent replication from server to client outside of ServerStorage/ServerScriptService, which, is a bad way to do that. (Unfortunately there is not really a good alternative, hence why I made this request)

3 Likes

One of my projects recently made me aware of how annoying it can be that Cameras don’t replicate to the client.

For a while now, I’ve been working on a little hobby project alongside school. The game uses an object oriented system for its entities, and, I’ve run into a roadblock: I want to have some entity code available to clients, some to the server, and some to both. Currently, my solution is to have two packages, one for server entities, and one for client entities, then, entities shared between the two are wrapped in this ugly wrapping:

Client modules in ReplicatedStorage
image
Server modules in ServerStorage
image

My only options to merge these into a unified package are using Camera instances.
This could look like the following using Camera instances to prevent modules from replicating:
image

The problems with this:

  1. I can’t share or edit this code whenever I enable Team Create
  2. This is technically an unintended use of Cameras
  3. Its not compact at all

Here is another example where I already use Cameras in this project (which I am about to completely get rid of for the sake of not using Cameras):
image
This package is shared in several places in my game, one of which is accessible to the client despite only being used in server code.

The best solution I could come up with

The best solution I could come up with for this problem is to hold a copy of the entities folder temporarily, strip out all of my server code, and place it into ReplicatedStorage. This is what some plugin based frameworks do, and, its the best solution.

The caveats to this are that I can’t make modifications to properties after this has been done without extra code to synchronize these changes.

As for the entity module, the best solution I can come up with is place it in ServerScriptService or ServerStorage. This unfortunately makes it impossible to bundle it in with my server code and turn it into a unified package, which, I eventually want to do.

Other annoyances

I have been using packages a lot, and, I have been using ThumbnailCameras in some of them to produce thumbnails. I like to use Team Create’s Team Test feature rather than launching a server, and, I like to show friends some of my code sometimes. Using Camera instances in the way that I do makes it impossible for me to do this, and, it also makes it impossible to work on anything with Camera instances.

Mockups of what I think this could look like

Here is a mockup of what I think my feature request could look like in both cases:
image
image

On the client, these would then appear as the following:
image
image

4 Likes