Skip to content

Commit 47c1191

Browse files
nezuoLPGhatguy
andauthored
Create polished version of generate_reflection named rbx_reflector (#249)
See PR #221 Co-authored-by: Lucien Greathouse <[email protected]>
1 parent a7a0367 commit 47c1191

33 files changed

+1319
-260
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ members = [
33
"generate_reflection",
44
"rbx_binary",
55
"rbx_dom_weak",
6+
"rbx_reflector",
67
"rbx_reflection",
78
"rbx_reflection_database",
89
"rbx_types",

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ Roblox reflection types for working with Instances in external tooling.
5151

5252
Bundled reflection database using types from rbx_reflection. Intended for users migrating from rbx_reflection 4.x and users who need reflection information statically.
5353

54+
## [rbx_reflector](rbx_reflector)
55+
56+
Command line utility to generate a reflection database for rbx_dom_lua and rbx_reflection_database.
57+
5458
## [rbx_util](rbx_util)
59+
5560
Command line utility to convert and debug Roblox model files.
5661

5762
## [rbx_dom_lua](rbx_dom_lua)

docs/patching-database.md

Lines changed: 24 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# How to Fix a New Property Added by Roblox
2-
When Roblox introduces new properties, usually tools like Rojo can use them without any additional changes. Sometimes, though, properties are added with different names, multiple serialized forms, or aren't listed at all in the reflection dump that Roblox gives us.
2+
When Roblox introduces new properties, usually tools like Rojo can use them without any additional changes. Sometimes however, properties are added that have a different serialized name or that need to be modified with a special API in Lua.
33

4-
This document describes some common scenarios, and what work needs to happen to fix them.
4+
This document describes some common scenarios and the necessary steps to fix them.
55

66
## Roblox added a new property and it serializes with the expected name and type
77
When Roblox introduces a new property, try saving a place or model in the XML format (rbxlx or rbxmx) and look for the property.
@@ -30,33 +30,11 @@ This is not ideal, though. To let Rojo users write the nice, short property synt
3030
Make sure you're running the latest version of Roblox Studio, then run the `./gen-reflection` script from the [rbx-dom repo][rbx-dom]. Patching Rojo's dependencies will let you test the change and make sure it works.
3131

3232
## Roblox added a new property and it serializes with a _weird_ name
33-
Sometimes Roblox adds properties whose serialized names are different than their canonical names (the names exposed to users). To fix these issues, we need to introduce a _property patch_.
33+
Sometimes a property is added with a serialized name different from its canonical name (the name exposed to users). To fix this issue, we need to introduce a _property patch_.
3434

35-
Property patches live in the [patches][patches] folder of the rbx-dom repository. There is roughly one YAML file per class that has changes applied to it. The `generate_reflection` tool reads these patches and uses them to generate a higher-quality reflection database for Rojo and other tools.
35+
Property patches live in the [patches][patches] folder in the rbx-dom repository. There is roughly one YAML file per class that has changes applied to it. The `rbx_reflector` tool reads these patch files and uses them to generate an accurate reflection database for Rojo and other tools.
3636

37-
To fix this kind of issue, we need to introduce two different patches:
38-
1. Add a new property descriptor for the funny name version of this property
39-
2. Change the canonical property to indicate that it serializes with that funny name
40-
41-
One property that serializes with a different name is `Sound.MaxDistance`. It serializes with the name `xmlRead_MaxDistance_3`. Funky! Let's look at the two patches we need to write.
42-
43-
The first part of our patch file should introduce the serialized version of the property:
44-
45-
```yaml
46-
Add:
47-
Sound:
48-
xmlRead_MaxDistance_3:
49-
AliasFor: MaxDistance
50-
DataType:
51-
Value: Float32
52-
Scriptability: None
53-
```
54-
55-
The first two lines indicate that we're adding one or more new property descriptor for the class named `Sound`. We can have many properties here.
56-
57-
Next, we name the property that we're going to add. We say that it's an alias for `MaxDistance`, the canonical name for this property. It is a value type, not an enum, and the type is `Float32`. Because this property is only for serialization, it is not scriptable.
58-
59-
The second part of the patch we need is for adjusting the existing property, `MaxDistance`.
37+
One property that serializes with a different name is `Sound.MaxDistance`. It serializes with the name `xmlRead_MaxDistance_3`. Funky! Let's look at the patch we need to write to fix it:
6038

6139
```yaml
6240
Change:
@@ -65,70 +43,48 @@ Change:
6543
Serialization:
6644
Type: SerializesAs
6745
As: xmlRead_MaxDistance_3
46+
xmlRead_MaxDistance_3:
47+
AliasFor: MaxDistance
6848
```
6949
70-
Similar to before, the first two lines indicate that we're going to change some properties on the `Sound` class. We give the property name, `MaxDistance`, and then say that we're going to change its `Serialization`. We spell out that it will serialize as `xmlRead_MaxDistance_3`.
71-
72-
For this property, we're done!
50+
The first two lines indicate that we're changing one or more properties for the class named `Sound`.
7351

74-
Here are a couple other common cases that can come up:
52+
Next we change the `Serialization` of `MaxDistance` to serialize as `xmlRead_MaxDistance_3`.
7553

76-
### The serialized property name already exists
77-
Sometimes, we don't need to add the serialized property name as it's already in the database from the reflection dump.
54+
Finally, we say that `xmlRead_MaxDistance_3` is an alias for `MaxDistance`, the canonical name of the property.
7855

79-
One example of that is `Players.MaxPlayers`, which serializes as `MaxPlayersInternal`. For whatever reason, that property is reflected to users, and so it's already in the database.
56+
For this property, we're done!
8057

81-
Instead of adding a new descriptor, we can update `MaxPlayersInternal` to point to its canonical form:
58+
## Roblox added a new property, but modifying it from Lua requires a special API
59+
Sometimes a property is added that cannot be assigned directly from Lua. For example, the `Model.Scale` property:
8260

83-
```yaml
84-
Change:
85-
Players:
86-
MaxPlayers:
87-
Serialization:
88-
Type: SerializesAs
89-
As: MaxPlayersInternal
90-
MaxPlayersInternal:
91-
AliasFor: MaxPlayers
61+
```lua
62+
-- This line of code throws an error: "Scale is not a valid member of Model"
63+
model.Scale = 2
9264
```
9365

94-
## Roblox added a new property, but modifying it from Lua requires a special API
95-
Sometimes a property is added that cannot be assigned directly from Lua.
96-
97-
First up, modify the reflection database to either add or change the property's `Scriptability` to `Custom`:
66+
To fix this, first patch the property's `Scriptablity` to `Custom`:
9867

9968
```yaml
100-
# To add the property:
101-
Add:
102-
LocalizationTable:
103-
# 'Contents' is the name of the field in the Roblox file formats, so it
104-
# makes sense to use it as the canonical name of this property.
105-
Contents:
106-
Serialization:
107-
Type: Serializes
108-
DataType:
109-
Value: String
110-
Scriptability: Custom
111-
11269
# To change the property:
11370
Change:
114-
LocalizationTable:
115-
Contents:
71+
Model:
72+
Scale:
11673
Scriptability: Custom
11774
```
11875

119-
Next, add an entry in [`rbx_dom_lua/src/customProperties.lua`][custom-properties] and implement the `read` and `write` methods. They return whether they succeeded as their first value.
76+
Next, add an entry in [custom-properties] and implement the `read` and `write` methods. They return whether they succeeded as their first value.
12077

12178
```lua
12279
return {
12380
-- ...
124-
125-
LocalizationTable = {
126-
Contents = {
81+
Model = {
82+
Scale = {
12783
read = function(instance, key)
128-
return true, instance:GetContents()
84+
return true, instance:GetScale()
12985
end,
13086
write = function(instance, key, value)
131-
instance:SetContents(value)
87+
instance:ScaleTo(value)
13288
return true
13389
end,
13490
},

gen-reflection

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ set -e
44

55
if [ "$1" = "--dry-run" ]; then
66
# If run with --dry-run, don't emit the reflection database anywhere.
7-
cargo run --bin generate_reflection \
7+
cargo run --bin rbx_reflector generate \
88
--patches patches
99
else
10-
cargo run --bin generate_reflection -- \
11-
--patches patches \
12-
--msgpack rbx_reflection_database/database.msgpack \
13-
--json rbx_dom_lua/src/database.json \
14-
--values rbx_dom_lua/src/allValues.json
10+
cargo run --bin rbx_reflector generate \
11+
rbx_reflection_database/database.msgpack \
12+
rbx_dom_lua/src/database.json \
13+
--patches patches
14+
15+
cargo run --bin rbx_reflector values rbx_dom_lua/src/allValues.json
1516
fi

patches/body-movers.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ Change:
3333
maxForce:
3434
AliasFor: MaxForce
3535
velocity:
36-
AliasFor: Velocity
36+
AliasFor: Velocity

patches/camera.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ Change:
33
CoordinateFrame:
44
AliasFor: CFrame
55
focus:
6-
AliasFor: Focus
6+
AliasFor: Focus

patches/csg.yml

Lines changed: 0 additions & 10 deletions
This file was deleted.

patches/fire-and-smoke.yml

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,3 @@
1-
Add:
2-
Fire:
3-
heat_xml:
4-
DataType:
5-
Value: Float32
6-
AliasFor: Heat
7-
Scriptability: None
8-
9-
size_xml:
10-
DataType:
11-
Value: Float32
12-
AliasFor: Size
13-
Scriptability: None
14-
15-
Smoke:
16-
opacity_xml:
17-
DataType:
18-
Value: Float32
19-
AliasFor: Opacity
20-
Scriptability: None
21-
22-
size_xml:
23-
DataType:
24-
Value: Float32
25-
AliasFor: Size
26-
Scriptability: None
27-
28-
riseVelocity_xml:
29-
DataType:
30-
Value: Float32
31-
AliasFor: RiseVelocity
32-
Scriptability: None
33-
341
Change:
352
Fire:
363
Size:
@@ -39,24 +6,34 @@ Change:
396
As: size_xml
407
size:
418
AliasFor: Size
9+
size_xml:
10+
AliasFor: Size
4211

4312
Heat:
4413
Serialization:
4514
Type: SerializesAs
4615
As: heat_xml
16+
heat_xml:
17+
AliasFor: Heat
4718

4819
Smoke:
4920
Opacity:
5021
Serialization:
5122
Type: SerializesAs
5223
As: opacity_xml
24+
opacity_xml:
25+
AliasFor: Opacity
5326

5427
Size:
5528
Serialization:
5629
Type: SerializesAs
5730
As: size_xml
31+
size_xml:
32+
AliasFor: Size
5833

5934
RiseVelocity:
6035
Serialization:
6136
Type: SerializesAs
62-
As: riseVelocity_xml
37+
As: riseVelocity_xml
38+
riseVelocity_xml:
39+
AliasFor: RiseVelocity

patches/instance.yml

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,28 @@
1-
# Patches up basic properties of Instance.
2-
3-
Add:
1+
Change:
42
Instance:
5-
# Tags serialize as a \0-delimited BinaryString of the tags on the instance.
6-
Tags:
7-
DataType:
8-
Value: Tags
3+
archivable:
4+
AliasFor: Archivable
5+
Archivable:
96
Serialization:
10-
Type: Serializes
11-
Scriptability: Custom
7+
Type: SerializesAs
8+
As: archivable
129

1310
# Attributes serialize as a BinaryString with a strange name, but we want to
1411
# refer to them with a different name.
1512
Attributes:
1613
DataType:
17-
Value: Attributes
14+
Value: "Attributes"
1815
Serialization:
1916
Type: SerializesAs
2017
As: AttributesSerialize
2118
Scriptability: Custom
2219
AttributesSerialize:
2320
AliasFor: Attributes
24-
DataType:
25-
Value: BinaryString
26-
Scriptability: None
27-
28-
Change:
29-
Instance:
30-
archivable:
31-
AliasFor: Archivable
32-
Archivable:
33-
Serialization:
34-
Type: SerializesAs
35-
As: archivable
3621

3722
className:
3823
AliasFor: ClassName
3924

40-
SourceAssetId:
41-
Scriptability: None
25+
Tags:
26+
DataType:
27+
Value: "Tags"
28+
Scriptability: Custom

patches/joint-instance.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
Change:
22
JointInstance:
33
part1:
4-
AliasFor: Part1
4+
AliasFor: Part1

patches/localization-table.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
Add:
1+
Change:
22
LocalizationTable:
33
# 'Contents' is the name of the field in the Roblox file formats, so it
44
# makes sense to use it as the canonical name of this property.
55
Contents:
6-
Serialization:
7-
Type: Serializes
8-
DataType:
9-
Value: String
10-
Scriptability: Custom
6+
Scriptability: Custom

patches/model.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
1-
Add:
1+
Change:
22
Model:
33
ScaleFactor:
44
AliasFor: Scale
5-
DataType:
6-
Value: Float32
7-
Scriptability: None
8-
9-
Change:
10-
Model:
115
Scale:
126
Serialization:
137
Type: SerializesAs
148
As: ScaleFactor
15-
Scriptability: Custom
9+
Scriptability: Custom

patches/package-link.yml

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
Add:
2-
PackageLink:
3-
PackageIdSerialize:
4-
DataType:
5-
Value: Content
6-
Scriptability: None
7-
AliasFor: PackageId
8-
91
Change:
102
PackageLink:
113
PackageId:
124
Serialization:
135
Type: SerializesAs
14-
As: PackageIdSerialize
6+
As: PackageIdSerialize
7+
PackageIdSerialize:
8+
AliasFor: PackageId

0 commit comments

Comments
 (0)