You either have to update the package, resulting in using VersionNumbers to deal with variants, or you have to make an entirely new package (defeating the point of packages)
Proposed Behavior
Uploading
Make a package
Make a different variant (color, style, etc.)
You are given the option to upload the package as either a “package” or a “package variant”
If you wish to make a package variant, you give the package variant a name and select the package it is a variant of
You can update variants via this upload system
Selecting Variants
Either the package itself or the PackageLink has a variant dropdown enum which allows you to pick the package variant you want
Switching the enum automatically changes that package to the last uploaded variant
Why
The current package system is not intuitive to making package variants. You are forced to either use different packages or VersionNumbers.
Paired with this thread. In order to make a red, blue, and green version of the same package, you need to upload 3 different versions. In order to update each package, you have to update three unique instances. This means more hassle, this means more time wasted.
Benefits
Makes the packages system more flexible
Makes making variants of the same/similar objects easier
Allows easy package variant randomization via script
If you put Color, Brightness and Range as Color3Value, NumberValue and NumberValue respectively into a Folder called Config inside the lamp Model then a Script in the Model can then read those values and apply them to the light at run time:
Unfortunately if we publish this lamp Model as a Package then the Values under Config will also be part of the package, and any changes will ask you to publish the changes. We are unable to specify that This lamp is red and bright while this lamp is blue and dim.
Interestingly, there is already a “Configuration” Instance in Roblox that is just a special case of Folder that supposed to contain only value objects for configuration. However it is not really useful in it’s current state because it functions EXACTLY like a Folder. I would propose the following update to make it mor useful:
If a Configuration instance is found inside a Package, the change made to it’s children will be ignored at publish time
Values already existing inside Configuration are not ever overwritten on package update
New Values not already existing will be copied on package update
Further I suggest the following update of the Configuration Instance for general usability upgrade:
Give it syntax to gracefully fall back to a default value upon trying to read missing values. For example: local val = config.myVal.Value or 4 will return 4 if myVal did not exist inside the config folder
Give it syntax so that the .Value part can be skipped. With the example above, this would be equivalent: local val = config.myVal or 4
Give it syntax so that when setting a value that does not already exist, it will create the value object on the fly with the most spesific type. For exampe; config.myVal = 4 would create a new object myVal under config of type NumberValue and set the value to 4.
Alternatively, there could be an attribute set on children inside the package that marks them as “not synchronized”. This is more general and probably easier to implement by Roblox, but puts more work on the dev and is far less opinionated/purpose driven.
I actually found out that packages can have custom attributes, which can adjust the package on an instance-by-instance basis. Extremely useful if you know how to code in the functionality.
For your use case, the package can probably contain both models combined with one of them transparent, with a script that chooses which variant should be visible based on a custom attribute within the package. You can read the specific post about it below. Hope this helps!