As a formality: As a Roblox developer, it is currently too hard to manage the relationship between objects and its code, particularly when these objects need to inspect/interact with each other.
The goal is straightforward…developing would be easier (and more modern) if we could define our own classes (which inherit from existing ones) and use them like this…
local bomb = Instance.new("Bomb")
bomb.Position = Vector3.new(0,10,0)
bomb.BlastRadius = 10
bomb.Parent = workspace
bomb:Explode()
I don’t want to get too caught up in the implementation details, and I’m not really looking for an alternative using existing features since they are typically complicated and require an advanced understanding of lua (self referencing metatables and the like) and still doesn’t really combine the object and its code in oop fashion. I’d really like a Roblox engineer to look at this and let us know if this could work or not. So, here is my latest idea of how this could work with minimal impact…
First there would be a new Script type called InheritModule, it could be placed anywhere but you’d probably place in ReplicatedStorage/ReplicatedFirst to make sure it gets replicated to Clients. The script object would have a drop down property called Inherits which you would be required to select an existing class to inherit from “Part”,“Union”, etc…
When the game engine loads on server and client it automatically runs these scripts to build this type and make available for use. The name of the InheritModule becomes the name of the new class.
So, in the above example we’d make an InheritModule, place in ReplicatedFirst, name it “Bomb” and set Inherits to “Part”,
the code would essentially work like a ModuleScript:
local this = {} -- this will refer to the physical object once it is bound
this.BlastRadius = 5 -- Creates a new property in our class
this.Size = Vector3.new(1,1,1) -- Overrides the default Size of Part (but must be the same datatype)
function this:Explode()
explosion = Instance.new("Explosion")
explosion.BlastRadius = this.BlastRadius -- self would also work as referring to the same instance
explosion.Position = this.Position
explosion.Parent = this
end
return this
And finally, how to serialize/store these custom objects. The engine either knows what Bomb is or doesn’t depending on the presence of the InheritModule. So, the xml would use all the same elements that you’d see in a Part object plus any custom properties we defined (BlastRadius). The key though is the inherits attribute, this gives the engine a fallback if it has no definition for Bomb. In that case, it would just create a Part object ignoring the properties that it doesn’t recognize (BlastRadius).
<Item class="Bomb" inherits="Part" referent="RBXC882FAA61930474884A6020A0CDB9052">
<Properties>
<int name="BlastRadius">10</int>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">4</token>
<token name="BottomSurfaceInput">0</token>
<CoordinateFrame name="CFrame">
<X>0</X>
<Y>10</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<bool name="CanCollide">true</bool>
<int name="CollisionGroupId">0</int>
<Color3uint8 name="Color3uint8">4284702562</Color3uint8>
<PhysicalProperties name="CustomPhysicalProperties">
<CustomPhysics>false</CustomPhysics>
</PhysicalProperties>
<float name="Elasticity">0.5</float>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">false</bool>
<token name="Material">256</token>
<string name="Name">Bomb</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<BinaryString name="Tags"></BinaryString>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">3</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0.200000003</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<token name="formFactorRaw">0</token>
<token name="shape">1</token>
<Vector3 name="size">
<X>1</X>
<Y>1</Y>
<Z>1</Z>
</Vector3>
</Properties>
</Item>