Somnium Space World Development
In Somnium Space Worlds you can build and program your own experiences inside Unity using the Somnium Space Unity SDK and Visual Scripting. The World NFT can be placed on your parcel and then is open for anyone to enter.
We will explain how we developed a Somnium Space world in Unity and how we integrated it into our parcel.
To develop a Somnium Space world you first need to have Unity 2019.2.4f1 installed including the Somnium Space SDK. The Somnium Space SDK will want you to login into your Somnium Space account to playtest or upload your scene. In your Unity scene there will be a gameobject called “World Config” with a script attached to it that will be used to upload your Unity scene onto the world NFT item that lies in your wallet. The Somnium Space SDK will filter out anything it does not want to have or will give you an error if something in your scene does not meet the upload criteria. Important to note is that the SDK will only allow visual scripting via the asset Bolt and will remove any other custom C# scripts that are present in the scene.
Compared to Somnium Space parcels the world does not have a rent feature. This means the developer of the world needs to have the world NFT in his MetaMask wallet.
The way we did it is to share the account details from the owner to the developer which in the end makes the rent parcel feature redundant because you need to have access to both NFTs. Of course you could give the developer the world NFT and rent him the parcel but we thought it would be safer to let the owner have full control of his NFTs because the developer with access to the Somnium Space account cannot transfer or manipulate the wallet with the account knowledge alone. When you have access to the world NFT item you will see it in the editor as a world item that can be placed and as any other building item costs a specific amount of credits.
To develop a world for Somnium Space you first need to get used to visual scripting. Secondly if you want to have multiplayer and synchronize events and states between all clients you will need to learn to use the asset Photon PUN 2 and of course integrate that into your visual scripting. Finally you will need to understand the Somnium Space specific quirks like which layers should be used and for example how to reference the player.
Instead of using written code you will use, as we like to describe them, boxes with specific behavior. You connect the in- and output of the boxes in a meaningful way to create logic. In the following pictures are two simple examples to show how Bolt scripts, or more specifically “Flow macros” as they are called, look like. The first on the left shows how you can rotate a gameobject around their Y-axis by accessing the Transform component and giving a constant float value “speed” as an input to the ,,yAngle” value. We are using the Update event to rotate it every frame. The second picture on the right puts out the famous “Hello World!” quote in our Unity console.
Visual scripting does contain some more advanced functionalities that we are going to describe briefly. At some point in the development when you start to have more complex logic the amount of boxes will rise substantially it is recommended to use ,,SuperUnits” to have a better overview and to better organize reusable logic. With ,,SuperUnits” you can combine the logic of multiple boxes into one. Furthermore, there are ,,CustomEvents” to create for example manager objects to handle playing sounds. This is handy because instead of giving every object that needs to play a sound the AudioSource component and call it in the script you can have one object containing all used sounds and play a specific one if the right event is called.
It is crucial for a metaverse game to have proper synchronization and it is the same for Somnium Space worlds if multiplayer interactions are intended. Photon PUN 2 is used for example when you want to play soccer with your friend then both of you should see the correct position of the ball. When entering a Somnium Space world everyone has their own instance of the scene and if you want to synchronize objects like a ball it is important to manage ownership of the ball because when both of you interact with the ball at the same time there is a conflict happening. By default Photon PUN 2 will give full control to the ,,MasterClient” and will only update interactions made by him. To change that behavior we need to give the object a script called ,,PhotonView” to make it an object that will be synchronized. In the settings we can change the ,,OwnershipTransfer” to ,,Takeover” which changes the ownership of the object on an event without asking the current owner for permission. Depending on the synchronized object you will need to add additional scripts like ,,PhotonTransformView” to synchronize position, rotation or scale and “PhotonRigidbodyView” when the objects need to use a rigidbody.
- 1.What can be synced:
- 1.Transforms, Rigidbody and Animator
- 2.Essential layers: It is important to use the right layer. It is not recommended to use the rest of the layers because they can break the scene.
- 1.Terrain: for static/non-moving objects
- 2.Vehicle: for dynamic/movable objects or objects need to be grabbed
- 3.PostProcess: for post-processing
- 4.Player: for player referencing
- 3.Referencing the player: When entering the world the player avatar has the name “Player [Username] [User ID]”. A Somnium Space world can be entered in 2D or VR mode and each of the player avatars are built differently.
For VR, to instantiate an object on the player you will first need to find the player in the scene looking for a game object with the substring "Player" [and then find the right path to each body part. The different paths should be:
- 1.RightHand: "Motion/UnityXRCameraRig/RightHand/RightAnchor”
- 2.LeftHand: "Motion/UnityXRCameraRig/LeftHand/LeftAnchor”
- 3.Head: "Motion/UnityXRCameraRig/Head/HeadAnchor”
- 4.Tablet: "Motion/UnityXRCameraRig/TabletPoint”
For 2D I always chose the object that collided with the Trigger itself.
- 1.Debugging: You can only test in the Somnium Space world itself. That means if you only own one world there can be only one Unity scene uploaded to your world NFT item. So you delete your previous world, upload the new one, replace/relink your world NFT item in the Somnium Space Builder, get into the 2D Mode of Somnium Space if you do not own a VR headset, reload the parcel because often times it is not loaded properly after reuploading the world, and finally enter your world to test. For synchronization testing you will need an additional Somnium Space account and computer to login and enter the world together with your other account. We had the following fixes for my problems that helped on the workflow.
- 1.If you start to learn Bolt you can test scripts inside Unity with a test player object with a collider and camera attached to it to try out Triggers etc.
- 2.If you want to test networking behavior with Photon PUN 2 inside Unity you can write a C# scripts where you use Unity custom events that can be called in Bolt using their custom event box.
- 2.Lack of documentation: Somnium Space provides no documentation and most of the knowledge we have was asked in the Somnium Space discord or can be found in the Somnium Space livestreams. A bit of information can also be found on the independent Somnium Space guide website ("https://somniumspace-guide.com/”).
- 3.Networking/Synchronization: So far not every gameobject that needs to be synchronized is synchronized and some objects are but they should not. We still need to understand how Somnium Space initializes their worlds and playtest more.