Hello fellow developers!
This tutorial is going to talk about attributes, which are in the process of being added to Roblox right now! I will be showing a little bit of how you can use attributes to watermark your places and credit your models (which can be applied elsewhere!). At the end of this tutorial, I additionally have some extra information on how the current Attribute system works as well as how the binary format for attributes currently works!
As you may have seen in Roblox’s release notes (specifically 408) Roblox is in the process of implementing Attributes. These are like custom metadata for instances and my game will be heavily using them! For a long while now I’ve been looking for reliable ways to “watermark” places. I’ve explored rbxl metadata, instances, tags, etc, and not many turn out to be great solutions or just plain don’t work.
Currently, there are two current easy ways to watermark your places:
- Hide an instance
- Hide a tag
Hiding an instance is not great since it will be visible in the explorer, and tags are much easier to work with and harder to keep extra information for such as keeping multiple developer names or contact info.
With the upcoming additions of instance Attributes I’ve devised two main ways to create a better watermarking system. People have sometimes asked if this was possible and I think I can safely say that Attributes make this a lot better.
Easy Watermarking
Firstly, I’d like to start with the easier method. Simply setting an attribute on some instance (e.g. workspace). Attributes support many values and even tables. This makes a great way to add credits to models and places. For places you’d usually want to be more subtle though if you don’t intend the place to be public. You’d keep the watermark there more as proof that you own the place.
To set an attribute you’d simply use the SetAttribute function. This attribute will save with the instance or place anywhere it goes! (And yes cloning will copy them!) Here’s an example:
workspace:SetAttribute("Developers", {
Scripters = {
"Scripter123"
},
Modelers = {
"Modeler11"
},
Sound = {
"SoundDesigner456"
}
})
(I know right? My fake naming is so creative!)
Advanced Watermarking (File editing)
With a little knowledge of what instances are hard to get to you can do some file editing to make your attributes super hidden! Yayy! I think one of my favorite services is the CSGDictionaryService because of how utterly locked down it is. (I mean seriously try clicking it in the explorer and watch official Roblox plugins that are built in to studio start spitting out errors)
CSGDictionaryService cannot be accessed by scripts and its children are hidden in the explorer. And we know that GetAttribute(s) requires a script. And we know plugins or even the command bar can’t access it! So this makes it the perfect object to put our attributes on!
In order to do this you’re going to need to:
- Save your place to a Roblox xml file (rbxlx)
- Apply the attribute you want to a dummy instance
- Save the dummy instance to a Roblox xml file (rbxmx)
- Open both files in your favorite text editor (even plain old Windows notepad will suffice!)
- Find and copy the AttributesSerialize line from your dummy instance. This contains a Base64 encoded representation of the instance’s attributes.
- Search for “CSGDictionaryService” using your text editor’s find/search feature.
- Paste the entire AttributesSerialize line into the Properties section of the CSGDictionaryService instance.
Now you have attributes applied to CSGDictionaryService! CSGDictionaryService’s Attributes cannot currently be viewed in studio even with a plugin so it’s pretty hard to find them. Now all you need to do to check if there’s a watermark of yours on a place is reverse this process by copying the attributes from CSGDictionaryService to a dummy instance and using GetAttribute!
I hope you find this tutorial to be somewhat useful, or if not, hopefully you’ll have learned new information about Attributes!
Other Uses/Info of Attributes
Attributes have a lot of potential and watermarking is a very basic example of what could be done with them. I mentioned before my game will be using these a lot, and I’d like to share my ideas! Here are some cool uses I’ve come up with for attributes:
- Storing data for structures, items, and entities in your games (Since attributes are so easy to work with and are similar to datastores, you can serialize it into a datastore fairly easily using GetAttributes! That means you can store stuff such as item ids, amounts, names, and more in only one spot!)
- Storing custom data via a plugin for user submitted content (for example, you could have a plugin which simply stores their script’s sources as an attribute for use in an asset SDK. That would allow your game to automatically make modifications to user code for security)
- Compacting simple game data (I use a TON of modules to store game info. Why not organize some storage into attributes now?)
- Custom classes (Now your instance based classes can support custom data to remember what they are without cluttering up the game or creating a bunch of data modules!)
- Version metadata for your game to keep changelogs and updates (For example, a model you can insert into your game to check version info via LoadAssetVersion and GetLatestAssetVersionAsync to query the model occasionally)
Here are some questions you may have about attributes:
- Does attribute data get copied when an instance is cloned? The answer is yes it does as of this post!
- Does attribute data save for the
game
instance (DataModel)? Not currently! The DataModel of your place is not saved as a full instance meaning it doesn’t save its attributes. - Does this attribute data save to the cloud and files? Yep! This data is meant to be saved and it’s a part of your instance.
Attribute Data Format
If you’re looking for how the binary data works, I’ve partially reverse engineered Roblox’s current format used! Keep in mind, these features are not released yet so this could change by the time Attributes are released!
Here’s a specification file I wrote for the current base64 encoded attribute data (I use my own format for this spec file by the way). This data is pretty basic for binary formats and the programmers behind this format did an absolutely great job at keeping things simple and small! RobloxAttributes.spec.xml (1.1 KB)
I don’t have most types in there, but I have the most essential ones down. Using my spec you can understand how most of the current file format works! I may have made a mistake, for example, type id 1 is marked as nil however it could have some special kind of use since there are 4 bytes used by it. Additionally, there are 3 bits missing from the last byte of Roblox numbers which I haven’t figured out the use for.