Packages can be very useful for sharing code and other assets between places and among developers on a team. Previously all the copies of a package had to be exactly the same, blocking many potential use cases.
Today, we are extending packages with a standard configuration mechanism to open up use cases where you need to tweak the behavior of each instance of a package.
The Upgrade
You can now use attributes on the root Instance of a package as configuration for that package. That is, you’ll be able to modify those attributes on each copy of a package and have that configuration kept when you update or change the version of the package.
Adding or removing attributes on the root Instance of a package will still count as a modification, however, once you’ve published these attributes they will count as a default configuration for the package and you may change them without it counting as a modification.
When you modify existing attributes on the package root, they are considered “configured”. Configured attributes are shown in BoldItalics in the properties pane to highlight what behavior tweaks a package has.
When you update the package (manually or thanks to having AutoUpdate enabled on the PackageLink), the configuration you set will be reapplied to the new version of the package. Attributes you left as the default will be updated to the latest default value so that it’s easy to adjust defaults as you prototype your content.
Undo Changes to Package will only reset modifications, it will not reset your configuration. If you want to go back to the default configuration a Reset option has been added to the cog menu to reset an attribute back to the default value.
When you Publish to Package, the current configuration will become the new default configuration. If you only want to publish modifications and not update the default configuration you should publish on a copy of the package without any configured values or Reset them first.
Other Changes
We have made some other smaller changes to give a similar treatment to the name of the package root and any tags on the package root:
Previously, packages ignored tags entirely but this was a bug. Now, adding tags on instances within a package will count as a modification as it should have.
Tags added to the root of a package will count as configuration, and be reapplied to the new version when updating a package.
The name of the package root will work the same as the attributes - It will change during updates unless you’ve customized it to something other than the default name, in which case it will be kept.
Note: This is a slight difference in behavior from how the root name was previously handled, where the root name never changed after inserting a copy of a package.
Finally, a couple of other related updates on attributes:
Alongside these other changes we’ve enabled Enum attributes. For now they can only be created via scripting, but once created they’ll have the expected dropdown editor.
There’s a known issue where Enum attributes storing Enums with a very large number of values such as Enum.KeyCode aren’t editable. There’s a fix for this on the way.
More attribute capabilities are in the works. In particular we know there’s a lot of demand for Instance reference attributes.
Looking Forwards
Configuration on packages opens up many use cases but still has the limitation that code can only consume the configuration at run-time. Ideally developer code could consume the configuration at edit time as well, allowing for smart objects which can do stuff like rearrange their geometry as you configure them in the properties pane.
We’re keenly aware of this and these changes are one more step along the path towards having a smart object system in the engine.
Let us know how you end up making use of these package improvements! For example, we plan to make use of them in the Developer Modules to offer you simple customization capability without having to fork them.
Attributes, why not adding properties so we can do like Package.AIControlled = true instead of Package:SetAttribute("AIControlled", true), though I can’t make packages public, which is an issue, I made a topic asking how and colbert2677 said that roblox may add that, which I still didn’t get, and I might not create packages until we are able to make them public, and I like packages as we can automatically update them, but the issue is that only packages from Roblox is available, and we can only use packages we made, but i like this new package update
An easier way to access attributes is something we’ve considered.
Directly using . probably isn’t viable as an option since both child and property access using . already creates enough issues as is, but you may eventually see something a bit more terse than a method call with a long name.
Yes, getting packages into the creator marketplace is an obvious move. There’s people working on it right now.
(this might be already possible so if it is just ignore this)
Package management plays an insane part of a toolchain in modern software development, I want the ability to share and distribute my packages with anyone that can then use my code, it would also be useful if I had a script-accessible API to insert packages (like GetObjects but it creates the packagelink)
Fantastic to hear this news–it would be great to have data type parity with value instances. This way there would be no need for a mix of attributes/valuebases/config scripts
Yes, there’s a bug with it not letting you edit “long” enums which have too many elements (it will work for shorter ones, but of course the long ones like keycode are the most useful so they’re obviously the ones that would break ). I’ve got a fix in for that which will be enabled next week.
Pretty sure attributes holding functions would lead to many bugs especially since functions and other values would then be able to be referenced between different thread identity levels which BindableFunction prevents.
Will we ever get a workspace enum to disable the error when indexing a nil child of an instance. I assume the main reason this even exists is to aid developers who don’t know what they’re doing however :FindFirstChild is very slow relative to the dot operator.