Not translated yet — showing English.
Inheritance & Composition
Modules build on each other, and none of it is subclassing. There is no base module to derive from and no hierarchy to extend: modules form a graph. This page is what "inheritance" means here, and the six mechanisms that do the work instead.
What inheritance means here
The word covers four different mechanisms:
- An entity's RPCs are part of the entity. They exist nowhere else: not on a parent, not in a shared registry. See Entity.
- A preset is a named bundle, not a base class. Stats, abilities, projectiles, drop generators and world objects are presets of
entity— bundles of aspects an entity view applies, which is why they live on one page as Entity Presets rather than as five modules. Applying a preset adds aspects; it does not put your type underneath anything. - Overriding a platform step is an attribute on your replacement. You do not subclass ours; you declare yours, and versions are chosen by condition with the platform default as the fallback. See Extensibility.
- A module borrows another through a decorator that narrows or enriches the borrowed interface, with the implementation swappable behind it. The worked case is a chat inside a room, on Groups.
There is no class hierarchy of modules, because a tree only allows branches and real features cross them. Matchmaking reserves seats in rooms; drops place items through the map; a leaderboard is fed by a hook on a room closing.
The six mechanisms
Each is declared with an attribute beside the thing it composes — the same declarative rule that governs everything else in the SDK.
Mount points, like a filesystem. A module mounts at the root — composing several interfaces into one surface — or into a namespace. A second module claiming an occupied mount point is rejected at mount time, never at the first call. Mechanism on Under the Hood.
Lexical visibility. Name visibility follows the nesting: a global declaration is visible inside a module, a local one never leaks upward. What a module emits is a separate question and is declared in its own contract — a module knows only the events it declared, or that were registered with it.
Encapsulation as a contract. A module never knows who calls it or why. What it exposes and what it emits is its whole public contract, and nothing about the caller changes its behaviour except the caller's grant.
Reuse by decorator and inversion of control. A module refers to another through a decorator rather than by reaching into it, and the implementation behind the interface is swappable. This is the mechanism that lets you replace one of our modules with your own without the modules that depend on it noticing.
Declarations grow the API. Declare an event on a group and group.Send.ChatMessage(…) appears with its contract; declare data members and a typed getter appears. The declaration is the codegen input — which is also why the declaration, not the generated code, is the thing you version.
Three addressing axes out of one module. All instances, one instance, and the administrator of one instance are three distinct APIs, not one API with a flag. Stated in full on Groups.
Implicit arguments
Inside an entity you never pass the entity. The receiver, the caller and the ambient context bind automatically, because all three are already determined by where the call was made and who made it. The mechanism is on RPC.