Component Creation
To create new components, we need to do a couple of things before starting coding them in the renderer. There is a step-by-step guide that you need to follow. I will list all the steps, and then you can follow each step with a longer explanation.
Create the proto definition in @dcl/protocol
Generate the new proto TypeScript code in the js-sdk-toolchain
Create a test for
js-sdk-toolchainGenerate the new proto C# code in the project
Code the new component
Ensure that the component follows the convention
Create the proto definition in @dcl/protocol
To create a definition, you must go to this repo: https://github.com/decentraland/protocol
Create the proto definition in this folder: https://github.com/decentraland/protocol/tree/main/ecs/components
Create a PR with the news changes
NOTE: After creating the PR, a GitHub Bot will comment with the package link to test the PR. You can use that link for testing in the following steps
Things to take into account
We are using proto 3, so all the definition of the proto must compile with their syntax
We have some common types that cannot be recreated
The proto should have the basic definition
You must add the following code to enumerate the component
Example of .proto
Generate the new proto TypeScript code in the js-sdk-toolchain
Download the following repo: https://github.com/decentraland/js-sdk-toolchain
Inside it, navigate to packages/dcl/ecs (https://github.com/decentraland/js-sdk-toolchain/tree/main/packages/%40dcl/ecs)
And there, you can execute
Or the command generated by the GitHub Bot in your @dcl/protocol PR (this must be temporal for testing the PR's).
Then run the following commands at the root of the js-sdk-toolchain project:
And push the generated code.
Generate the new proto C# code in the project
To generate the C# code, we need to go to the protocol-gen path in the root of the @decentraland/unity-renderer repository. And execute the following commands:
To upgrade to the latest version of the @dcl/protocol (main branch), we should update using
To test a PR, we can use a URL generated by the GitHub Bot in the @dcl/protocol PR: Example:
After merging @dcl/protocol PR, we must use the @dcl/protocol@next and generate the code.
Code the new component
Now it is time to implement the functionality of the new component.
The components have five essential parts.
ComponentID The ID that the component will use. It must be unique and generated from the proto definition
Model This is the model of the component. This is the data that we will use to handle the component. It has been auto-generated with the proto generation and it has the same name of the proto file with a PB in front. For example, if you have a
BoxShape.protodefinition the generated class of the model will bePBBoxShapeComponent Handler The component handler will manage all the functionality of the component. In this class you must implement the
IECSComponentHandler<ModelClass>(ModelClass is the model. It is a generated class from the proto, the name will be PB + name of the file .proto). This interface has 3 method that are important to implement in order to create a component
Serializer Each component is responsible to implement his serialization and deserialization of the component. This serializer must be able to serialize/deserialize to byte array
Register This will register the component into the system, connecting it to the system. This register will register the component in the factory and the component writer
The design of the components is to avoid inheritance so we encourage to use pure functions as much as possible
In order to create them, We must follow the next steps
Create the component folder and assembly. We have all the components unders the follow folder
DCLPlugins/ECS7/ECSComponents. You need to create a folder and a new assembly that will hold the componentIn the new assembly, you must reference the following one
DCL.ECSComponents.Data. This will reference the new model of the component that you just updatedYou must create the component handler with all the logic (Take a look at
ECSBoxShapeComponentHandler.csas an example)You must create the serializer class (probably you can copy it from another class and adapt to your)
You must create the register class
Add the new register to the
ECS7ComponentsComposerclass with his corresponding ID
And now you have your component added and working!
Ensure that the component follows the convention
There is some checklist that we need to have into account while developing new components, this part tries to summarize them.
Unit test All the components must include unit test that cover its functionality, dispose and the serialization/deserialization at least to ensure that the component will work
Take into account what happens when the component is not inside the scene (Check
SceneBoundariesCheckerclass for more info)If the component renders something into the world, It must add the rendereable info to the data store, this way we add the information of the renderer to the scene so it can counts toward the limit
If the component renders something into the world, It must add the
MeshesInfoto the entityIt must be as perfomant as possible. This code will be executed lots of time so we need to ensure that everything work as smooth as possible
It must work with
Hot reloadin the preview mode. If you has coded theOnComponentRemovedcorrectly, this will work out of the box, but the hot reload it a way to test that everything work fine with the dispose of the componentIf the component uses a resource, you must implement the resource management with an
AssetPromiseKeeper. The component should notify theAssetPromiseKeeperwhen the resource is used and when it is not longer used
Last updated