All pages
Powered by GitBook
1 of 6

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

SPhotos

Index

Functions Index

Function Name

Functions

GetUploadedTexture

GetUploadedTexture ()

Function Description

GetSavedTexture

void GetSavedTexture (string path, Closure onComplete)

Function Description

Parameter
Type
Description

GetInventoryTextures

Table GetInventoryTextures ()

Function Description

OpenUploadFileBrowser

void OpenUploadFileBrowser ()

Opens a window that let's you select a file you wish to upload. (white-label)

OnUploadEnd

void OnUploadEnd (Closure c)

Binds the function c to be called when an upload operation ends.

Parameter
Type
Description

OnUploadStart

void OnUploadStart (Closure c)

Function Description

Parameter
Type
Description

Network

SResource GetUploadedTexture ()

void GetSavedTexture (string path, Closure onComplete)

Table GetInventoryTextures ()

void OpenUploadFileBrowser ()

void OnUploadEnd (Closure c)

void OnUploadStart (Closure c)

path

string

onComplete

Closure (Callback)

Closure will be called once the saved texture has been retrieved. onComplete(SResource)

SResource
resourceTexture = Space.Photos.GetUploadedTexture()
function onComplete(SResource)
resourceTexture = SResource
end

Space.Photos.GetSavedTexture('APath', onComplete)
tableInventoryTexture = Space.Photos.GetInventoryTextures()
Space.Photos.OpenUploadFileBrowser()
--this script will open a file upload browser when clicked
thisObject = Space.Host.ExecutingObject

function OnClickFunction()
Space.Photos.OpenUploadFileBrowser()
end


thisObject.AddClickable()
thisObject.Clickable.Tooltip = "Click me to upload photo"
thisObject.Clickable.OnClick(OnClickFunction)
function c()
--
end

Space.Photos.OnUploadEnd(c)
--this script will show a text on screen that says "Uploading..." when a photo upload is initiated
--and will hide it when the upload has ended
thisObject = Space.Host.ExecutingObject
textObject = Space.Host.GetReference("textObject") --add a UIText object to References in Scripting Runtime
textObject.UIText.Text = "Uploading..."

function OnUploadStartFunction()
textObject.Active = true
end

function OnUploadEndFunction()
textObject.Active = false
end

Space.Photos.OnUploadStart(OnUploadStartFunction)
Space.Photos.OnUploadEnd(OnUploadEndFunction)
function c()
--
end

Space.Photos.OnUploadStart(c)
--this script will show a text on screen that says "Uploading..." when a photo upload is initiated
--and will hide it when the upload has ended
thisObject = Space.Host.ExecutingObject
textObject = Space.Host.GetReference("textObject") --add a UIText object to References in Scripting Runtime
textObject.UIText.Text = "Uploading..."

function OnUploadStartFunction()
textObject.Active = true
end

function OnUploadEndFunction()
textObject.Active = false
end

Space.Photos.OnUploadStart(OnUploadStartFunction)
Space.Photos.OnUploadEnd(OnUploadEndFunction)

SChat

Index

Functions Index

Function Name

Functions

OnChat

void OnChat (Closure callback) void OnChat (Action< > trackInfoCallback)

Bind a function to the OnChat event. This function will be called every time a new chat message is received on the local channel.

Parameter
Type
Description

JoinChat

void JoinChat (string name)

Join a chat channel.

Parameter
Type
Description

GetXMPPName

string GetXMPPName (string name)

Get XMPP name.

Parameter
Type
Description

LeaveChat

void LeaveChat (string name)

Leave a chat channel.

Parameter
Type
Description

GetVoiceZone

SVoiceZone GetVoiceZone (string channel)

Get a reference to a voice zone component for the given channel.

Parameter
Type
Description

JoinVoice

void JoinVoice (string channel, int priority=5, int spatial=0)

Join a voice chat channel.

Parameter
Type
Description

JoinGridVoice

void JoinGridVoice (string channel, int priority=5, int spatial=0)

JoinGridVoice is the same as JoinVoice except with a grid wide parameter. (white-label only)

Parameter
Type
Description

LeaveVoice

void LeaveVoice (string channel)

Leave a voice chat channel

Parameter
Type
Description

SVideos

Index

Functions Index

Function Name

SWebService

Set up your web service

To setup your server for communication with space, in the root of your domain, on the port you are using, place a file named 'sinewave.space.scripting.txt' containing 'SPACE_OK'. E.g. - if this file is not present, you will be unable to use scripting to communicate with the domain. Note: you should use HTTPS for all API calls. You may also need to implement a CORS policy in your webserver headers.

void OnChat (Closure callback) void OnChat (Action< SChatMessage > trackInfoCallback)

void JoinChat (string name)

string GetXMPPName (string name)

void LeaveChat (string name)

SVoiceZone GetVoiceZone (string channel)

void JoinVoice (string channel, int priority=5, int spatial=0)

void JoinGridVoice (string channel, int priority=5, int spatial=0)

void LeaveVoice (string channel)

callback

Closure or Action

Invoked when a chat message is received

name

string

Chat channel to join

name

string

Human-readable chat name

name

string

Chat channel to leave

channel

string

Voice channel name/handle

channel

string

Voice channel name/handle

priority

int

Optional. Priority, default 5

spatial

int

Optional. Spatialization flag (0/1), default 0

channel

string

Voice channel name/handle (grid-wide)

priority

int

Optional. Priority, default 5

spatial

int

Optional. Spatialization flag (0/1), default 0

channel

string

Voice channel to leave

SChatMessage
Space.Network.Chat.OnChat(OnChatFunction) 
--this script takes every new chat message and displays it in a UIText 
uiText = Space.Host.GetReference("text").UIText --Add this Text object as reference in Scripting Runtime

OnChatFunction = function(SChatMessage)
uiText.Text = SChatMessage.Sender ..": " .. SChatMessage.Message 
end

Space.Network.Chat.OnChat(OnChatFunction) 
Space.Network.Chat.JoinChat("Test room")
--this script will make the player join a chat when entering a trigger collider and leave it when leaving
--[Requires this object to have a "Trigger" collider]

thisObject = Space.Host.ExecutingObject
thisPlayer = Space.Scene.PlayerAvatar

OTS = function(gameObject)
  if gameObject.Avatar ~= nil and thisPlayer == gameObject.Avatar then 

    Space.Network.Chat.JoinChat("PrivateChatZone")
    
  end

end

OTE = function(gameObject)
  if gameObject.Avatar ~= nil and thisPlayer == gameObject.Avatar then

    Space.Network.Chat.LeaveChat("PrivateChatZone")
    
  end 
  
end


thisObject.OnTriggerStart(OTS)
thisObject.OnTriggerExit(OTE)
Space.Network.Chat.GetXMPPName("Test room")
Space.Network.Chat.LeaveChat("Test room")
--this script will make the player join a chat when entering a trigger collider and leave it when leaving
--[Requires this object to have a "Trigger" collider]

thisObject = Space.Host.ExecutingObject
thisPlayer = Space.Scene.PlayerAvatar

OTS = function(gameObject)
  if gameObject.Avatar ~= nil and thisPlayer == gameObject.Avatar then 

    Space.Network.Chat.JoinChat("PrivateChatZone")
    
  end

end

OTE = function(gameObject)
  if gameObject.Avatar ~= nil and thisPlayer == gameObject.Avatar then

    Space.Network.Chat.LeaveChat("PrivateChatZone")
    
  end 
  
end


thisObject.OnTriggerStart(OTS)
thisObject.OnTriggerExit(OTE)
voiceZone = Space.Network.Chat.GetVoiceZone("AChannel")
Space.Network.Chat.JoinVoice("PrivateVoiceZone")
--this script will make the player join a voice channel when entering a trigger collider and leave it when leaving
--[Requires this object to have a "Trigger" collider]

thisObject = Space.Host.ExecutingObject
thisPlayer = Space.Scene.PlayerAvatar

OTS = function(gameObject)
  if gameObject.Avatar ~= nil and thisPlayer == gameObject.Avatar then 

    Space.Network.Chat.JoinVoice("PrivateVoiceZone")
    
  end

end

OTE = function(gameObject)
  if gameObject.Avatar ~= nil and thisPlayer == gameObject.Avatar then

    Space.Network.Chat.LeaveVoice("PrivateVoiceZone")
    
  end 
  
end


thisObject.OnTriggerStart(OTS)
thisObject.OnTriggerExit(OTE)
Space.Network.Chat.JoinGridVoice("PrivateGridVoiceZone")
--this script will make the player join a Grid voice channel when entering a trigger collider and leave it when leaving
--[Requires this object to have a "Trigger" collider]

thisObject = Space.Host.ExecutingObject
thisPlayer = Space.Scene.PlayerAvatar

OTS = function(gameObject)
  if gameObject.Avatar ~= nil and thisPlayer == gameObject.Avatar then 

    Space.Network.Chat.JoinGridVoice("PrivateGridVoiceZone")
    
  end

end

OTE = function(gameObject)
  if gameObject.Avatar ~= nil and thisPlayer == gameObject.Avatar then

    Space.Network.Chat.LeaveVoice("PrivateGridVoiceZone")
    
  end 
  
end


thisObject.OnTriggerStart(OTS)
thisObject.OnTriggerExit(OTE)
Space.Network.Chat.LeaveVoice("PrivateVoiceZone")
--this script will make the player join a voice channel when entering a trigger collider and leave it when leaving
--[Requires this object to have a "Trigger" collider]

thisObject = Space.Host.ExecutingObject
thisPlayer = Space.Scene.PlayerAvatar

OTS = function(gameObject)
  if gameObject.Avatar ~= nil and thisPlayer == gameObject.Avatar then 

    Space.Network.Chat.JoinVoice("PrivateVoiceZone")
    
  end

end

OTE = function(gameObject)
  if gameObject.Avatar ~= nil and thisPlayer == gameObject.Avatar then

    Space.Network.Chat.LeaveVoice("PrivateVoiceZone")
    
  end 
  
end


thisObject.OnTriggerStart(OTS)
thisObject.OnTriggerExit(OTE)

Table ()

void ()

void (Closure c)

void (Closure c)

Functions

GetInventoryVideos

Table GetInventoryVideos ()

Function Description

Parameter
Type
Description

tableInventoryVideos = Space.Videos.GetInventoryVideos()

OpenUploadFileBrowser

void OpenUploadFileBrowser ()

Opens a window that let's you select a file you wish to upload. (white-label)

OnUploadEnd

void OnUploadEnd (Closure c)

Binds the function c to be called when an upload operation ends.

Parameter
Type
Description

OnUploadStart

void OnUploadStart (Closure c)

Binds the function c to be called when an upload operation begins.

Parameter
Type
Description

Index

Functions Index

Function Name

void (string url, Closure onComplete, Table headers=null, float timeout=0)

void (string url, string data, Closure onComplete, Table headers=null, float timeout=0)

SResource (string url, Closure onComplete=null, Table header=null, float timeout=0)

Functions

Get

void Get (string url, Closure onComplete, Table headers=null, float timeout=0)

Performs an HTTP[S] GET and invokes the callback with an SWebResponse containing the result.

Parameter
Type
Description

url

string

The absolute URL to request. Must pass the domain whitelist check.

onComplete

Closure

Callback receiving a single .

headers

Table (optional)

Supported keys: Content-Type, Bearer (maps to Authorization: Bearer <token>).

timeout

float (optional)

Timeout in seconds. 0 disables timeout.

Note:

  • This call automatically sends diagnostic headers: X-Sinespace-Region-ID, X-Sinespace-Region-Name, X-Sinespace-Instance-ID, X-Sinespace-Script-Name, X-Sinespace-Runtime-Type, X-Sinespace-In-Editor, and X-Sinespace-Preview-Server.

  • Domains must host /sinewave.space.scripting.txt with the content SPACE_OK at the root for requests to proceed (see setup above).

Post

void Post (string url, string data, Closure onComplete, Table headers=null, float timeout=0)

Performs an HTTP[S] POST and invokes the callback with an SWebResponse containing the result.

Parameter
Type
Description

url

string

The absolute URL to POST to. Must pass the domain whitelist check.

data

string

Request body. For JSON, provide a JSON string and set Content-Type accordingly.

onComplete

Closure

Callback receiving a single .

headers

Table (optional)

Note:

  • For JSON: set Content-Type = application/json and send a JSON string body.

  • The target domain must pass the whitelist check (/sinewave.space.scripting.txt with SPACE_OK).

  • HTTPS is recommended; ensure the server sends appropriate CORS headers.

GetImage

SResource GetImage (string url, Closure onComplete=null, Table header=null, float timeout=0)

Returns a valid SResource for a image on a remote domain that can be used via e.g. SMaterial. While the image loads, it will be a white pixel that will be substituted with the real image once loaded.

Parameter
Type
Description

url

string

The absolute image URL to load.

onComplete

Closure (optional)

Callback receiving the resulting .

header

Table (optional)

Accepted but not used for images; pass nil. Reserved for future use.

timeout

float (optional)

http://somewhere.com/sinewave.space.scripting.txt
Space.Videos.OpenUploadFileBrowser()
--this script will open a video upload window when clicked
thisObject = Space.Host.ExecutingObject

function OnClickFunction()
Space.Videos.OpenUploadFileBrowser()
end


thisObject.AddClickable()
thisObject.Clickable.Tooltip = "Click me to upload video"
thisObject.Clickable.OnClick(OnClickFunction)
function OnUploadEndFunction()
--
end
Space.Videos.OnUploadEnd(OnUploadEndFunction)
--this script will show a text on screen that says "Uploading..." when a video upload is initiated
--and will hide it when the upload has ended
thisObject = Space.Host.ExecutingObject
textObject = Space.Host.GetReference("textObject") --add a UIText object to References in Scripting Runtime
textObject.UIText.Text = "Uploading..."

function OnUploadStartFunction()
textObject.Active = true
end

function OnUploadEndFunction()
textObject.Active = false
end

Space.Videos.OnUploadStart(OnUploadStartFunction)
Space.Videos.OnUploadEnd(OnUploadEndFunction)
function OnUploadStartFunction()
--
end
Space.Videos.OnUploadStart(OnUploadStartFunction)
--this script will show a text on screen that says "Uploading..." when a video upload is initiated
--and will hide it when the upload has ended
thisObject = Space.Host.ExecutingObject
textObject = Space.Host.GetReference("textObject") --add a UIText object to References in Scripting Runtime
textObject.UIText.Text = "Uploading..."

function OnUploadStartFunction()
textObject.Active = true
end

function OnUploadEndFunction()
textObject.Active = false
end

Space.Videos.OnUploadStart(OnUploadStartFunction)
Space.Videos.OnUploadEnd(OnUploadEndFunction)
function OnResponseFunction(responseData)
--
end
Space.WebServices.Get('A URL', OnResponseFunction)
-- Example: Retrieve user-specific data from your integration endpoint

-- Typically retrieved dynamically, e.g., from Space.Scene.CurrentUser
local userID = "User123"

-- Identifier for the integrated service or application
local serviceID = "CRMApp"

-- Build the request URL with query parameters
local sentData = "http://www.yourdomain.net/getIntegrationData.php?id=" .. userID .. "&service=" .. serviceID

-- Callback function to handle the API response
local response = function(data)
  if data.Error == nil then
    -- Log the successful response
    Space.Log(data.Response)
  else 
    -- Log any error returned by the API
    Space.Log(data.Error)
  end
end

-- Make a GET request to your integration API
Space.WebServices.Get(sentData, response)

-- You can parse the response to extract and use relevant integration data
function OnResponseFunction(responseData)
--
end
local url = 'https://example.com/endpoint'
local data = 'key=value'
Space.WebServices.Post(url, data, OnResponseFunction)
-- Example: Send user-specific data to your integration endpoint via POST request

-- User identifier, typically retrieved dynamically
local userID = "User123"

-- Identifier for the integrated service or product
local serviceID = "CRMApp"

-- Target URL for the integration API
local url = "http://www.yourdomain.net/postIntegrationData.php"

-- Construct the payload for the POST request
local sentData = "id=" .. userID .. "&service=" .. serviceID

-- Define a callback to handle the API response
local response = function(data)
  if data.Error == nil then
    -- Log the successful response
    Space.Log(data.Response)
  else 
    -- Log any error returned by the API
    Space.Log(data.Error)
  end
end

-- Set the appropriate content-type for the POST request
local tableHeader = {["Content-Type"] = "text/plain"}

-- Send a POST request to your integration API
Space.WebServices.Post(url, sentData, response, tableHeader)
-- JSON POST with Bearer auth and timeout
local url = "https://api.example.com/widgets"
local body = '{"name":"My Widget","color":"blue"}'
local headers = { ["Content-Type"] = "application/json", ["Bearer"] = "YOUR_ACCESS_TOKEN" }

Space.WebServices.Post(url, body, function(data)
  if data.Error == nil then
    Space.Log("Created: " .. data.Response)
  else
    Space.Log("Error: " .. data.Error)
  end
end, headers, 15)
resourceImage = Space.WebServices.GetImage('An Image URL')
-- Example: Load and apply a remote image from your integration media server

-- Image filename to retrieve from the media service
local imageFileName = "user_banner_1024.jpg"

-- Base URL of the content delivery server
local mediaServerUrl = "https://cdn.acme-integrations.com/assets/"

-- Reference to the 3D object where the image will be displayed
local displayObject = Space.Host.GetReference("profileDisplay")

-- Fetch the image from the server
local imageResource = Space.WebServices.GetImage(mediaServerUrl .. imageFileName)

-- Apply the image as a texture to the object's material
displayObject.Renderer.Material.SetTexture("_MainTex", imageResource)
GetInventoryVideos
OpenUploadFileBrowser
OnUploadEnd
OnUploadStart

Supported keys: Content-Type (defaults to application/x-www-form-urlencoded), Bearer (maps to Authorization: Bearer <token>).

timeout

float (optional)

Timeout in seconds. 0 disables timeout.

Accepted but not used for images; pass 0. Reserved for future use.

Get
Post
GetImage
SWebResponse
SWebResponse
SResource

SNetwork

Index

Functions Index

Function Name

Properties Index

Property Name
Description

Overview

  • Local network messages (region/shard scope)

    • Use SendNetworkMessage / SubscribeToNetwork with a string key.

    • Delivery is confined to the current region or shard and only to active subscribers of that key.

    • Payload is a Lua Table (dictionary) of network-serializable types. Messages are ephemeral and not stored.

Functions

SendNetworkMessage

void SendNetworkMessage (string key, Table message)

void SendNetworkMessage (string key, Table message, bool serverOnly)

void SendNetworkMessage (string key, Table message, bool serverOnly, bool loopback)

Sends a networked message to every client with a subscriber listening on 'key'. The message itself can be a table/dictionary of network-serializable types (string, float, int, byte, bool and arrays of those types). Requests may be rate limited.

Parameter
Type
Description

SendNetworkMessageToUser

void SendNetworkMessageToUser (string key, Table message, uint userID)

Sends a networked message to a specific user (userID) with a subscriber listening on 'key'.

Parameter
Type
Description

SubscribeToRegionPropertyUpdate

void SubscribeToRegionPropertyUpdate (string key, DynValue onRecieve)

Subscribes to region property updates on 'key'.

Parameter
Type
Description

SubscribeToNetwork

void SubscribeToNetwork (string key, Action< > onRecieve) void SubscribeToNetwork (string key, DynValue onRecieve)

Subscribes to network messages on 'key', will fire a SNetworkMessage whenever a matching message is received

Parameter
Type
Description

SetRegionProperty

void SetRegionProperty (string key, string value)

Stores a key/value pair in the Regions semi-permanent memory. Will be erased when all players exit the region, but will persist as long as the region is open. Subject to rate limiting (10/second on the main grid and 20/second on white-label grids)

Parameter
Type
Description

GetRegionProperty

string GetRegionProperty (string key)

Retrieves the last set value for 'key' in this region. If you have just joined the region, this may not be populated immedietely.

Parameter
Type
Description

SetShardProperty

void SetShardProperty (string key, string value)

Sets a property named 'key' of the Shard to 'value'. Will persist until the Shard is shut down or restarted. (Use SPersistence for longer term storage)

Parameter
Type
Description

GetShardProperty

string GetShardProperty (string key)

Gets a previously set key.

Parameter
Type
Description

Properties

HasShardProperties

bool HasShardProperties get

Returns True upon successful connection to the Region/Shard properties' storage. Region/Shard property operations may not be ready when used during initialization and this function ill help determine readiness.

Region/Shard properties (server-stored)

  • Use SetRegionProperty/GetRegionProperty for region-scoped semi-permanent storage (persists while the region is open).

  • Use SetShardProperty/GetShardProperty for shard-scoped storage (persists until the shard shuts down or all users leave).

  • Values are strings; operations may be rate-limited and may not be immediately available on join. Use HasShardProperties to detect readiness.

void SendNetworkMessage (string key, Table message, bool serverOnly, bool loopback) void SendNetworkMessage (string key, Table message, bool serverOnly) void SendNetworkMessage (string key, Table message)

void SendNetworkMessageToUser (string key, Table message, uint userID)

void SubscribeToRegionPropertyUpdate (string key, DynValue onRecieve)

void SubscribeToNetwork (string key, DynValue onRecieve)

void SetRegionProperty (string key, string value)

string GetRegionProperty (string key)

void SetShardProperty (string key, string value)

string GetShardProperty (string key)

bool HasShardProperties get

Returns True upon successful connection to the Region/Shard properties' storage. Region/Shard property operations may not be ready when used during initialization and this function will help determine readiness.

key

string

Subscription key to route the message to listeners

message

Table

Table/dictionary of serializable values

serverOnly

bool

Optional. If true, send via server only

loopback

bool

key

string

Subscription key

message

Table

Table/dictionary of serializable values

userID

uint

Target user ID

key

string

Property key to subscribe to

onRecieve

Callback Closure

onRecieve(NetworkPropertyUpdate) will be called on updates. NetworkPropertyUpdate = { Key, Message }

key

string

Subscription key to listen on

onRecieve

Callback Closure

Callback receiving SNetworkMessageLua with fields Key (string) and Message (Table)

SNetworkMessageLua

Optional. If true, also invoke local subscriber on this client

Space.Network.SendNetworkMessage('AKey', {first = "xyz", second= "abc"})
--or
Space.Network.SendNetworkMessage('AKey', {first = "xyz", second= "abc"}, true)
--or
Space.Network.SendNetworkMessage('AKey', {first = "xyz", second= "abc"}, true, true)
image = "mrlee.jpg"
server = "https://middleware.systems/"
obj = Space.Host.GetReference("Gino")

Space.Network.SubscribeToNetwork("smack", onSmack)

function hithere()

  resrc = Space.WebServices.GetImage(server .. image)
  obj.Renderer.Material.SetTexture("_MainTex", resrc)
  Space.Network.SendNetworkMessage("smack",{'smack'})
end

function update()

  resrc = Space.WebServices.GetImage(server .. image)
  obj.Renderer.Material.SetTexture("_MainTex", resrc)
end

function onSmack()

  update()
end
Space.Network.SendNetworkMessageToUser('AKey', {first = "xyz", second= "abc"}, 23123123)
function onRecieve(NetworkPropertyUpdate)
propertyKey = NetworkPropertyUpdate.Key
propertyValue = NetworkPropertyUpdate.Message
end
Space.Network.SubscribeToRegionPropertyUpdate('A Key', onRecieve)
function OnRecieveFunction(SNetworkMessageLua)
--
end
Space.Network.SubscribeToNetwork("AKey", OnRecieveFunction)
local scriptedObject = Space.Host.ExecutingObject;
local textValue = Space.Host.GetReference("Text");
scriptedObject.SubscribeToEvents();

-- This function gets used by other objects that are subscribed to the network
gotAMessage = function(arguments)
  textValue.UIText.Text = "Got a message with the argument " .. arguments.Message["someArgument"];
end

-- This function gets used by "this" object. Plus, it sends out a message to objects on the network.
local updateTextUI = function()
  textValue.UIText.Text = "Got a message with the argument Hi there!";
  Space.Network.SendNetworkMessage("helloworld", {someArgument = "Hi there!"});
end

-- Subscribe to network. Note that "this" object doesn't execute gotAMessage.
-- Only the other objects on the network do.
Space.Network.SubscribeToNetwork("helloworld", gotAMessage);

scriptedObject.OnMouseDown(updateTextUI);

-- "Text" used with GetReference is a UItext canvas object used to display the test text inworld. After you add UI > Text to your scene, drag the text object to the Object References section in your script.
Space.Network.SetRegionProperty("testKey", "Test Value") 
 --this script is a networked and persistent color changing of an object
--note that we put the object's GlobalID in the key to make it specific to this object

thisObject = Space.Host.ExecutingObject
currentColor = nil

OnClick = function() --this writes to the region properties
if currentColor == Color.Blue then
  Space.Network.SetRegionProperty(thisObject.GlobalID .. "color", "red")
else
  Space.Network.SetRegionProperty(thisObject.GlobalID .. "color", "blue")
end
  
end

Sync = function() -- this gets from the region properties
  while true do
    local result = Space.Network.GetRegionProperty(thisObject.GlobalID .. "color")
    if result == "red" then
      currentColor = Color.Red 
    else 
      currentColor = Color.Blue
    end

    thisObject.Renderer.Material.SetColor("_Color", currentColor)  
    coroutine.yield(0.1) --to make sure it doesn't run more than 12/second
  end
end


thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClick)
Space.Host.StartCoroutine(Sync)
 result = Space.Network.GetRegionProperty("testKey")
--this script is a networked and persistent color changing of an object
--note that we put the object's GlobalID in the key to make it specific to this object

thisObject = Space.Host.ExecutingObject
currentColor = nil

OnClick = function() --this writes to the region properties
if currentColor == Color.Blue then
  Space.Network.SetRegionProperty(thisObject.GlobalID .. "color", "red")
else
  Space.Network.SetRegionProperty(thisObject.GlobalID .. "color", "blue")
end
  
end

Sync = function() -- this gets from the region properties
  while true do
    local result = Space.Network.GetRegionProperty(thisObject.GlobalID .. "color")
    if result == "red" then
      currentColor = Color.Red 
    else 
      currentColor = Color.Blue
    end

    thisObject.Renderer.Material.SetColor("_Color", currentColor)  
    coroutine.yield(0.1) --to make sure it doesn't run more than 12/second
  end
end


thisObject.AddClickable()
thisObject.Clickable.OnClick(OnClick)
Space.Host.StartCoroutine(Sync)
local scriptedObject = Space.Host.ExecutingObject;
scriptedObject.SubscribeToEvents();

local testMsg = "Hello";
local updateTextUI = function()
  Space.Network.SetShardProperty("testKey", testMsg);
end

scriptedObject.OnMouseDown(updateTextUI);
local scriptedObject = Space.Host.ExecutingObject;
scriptedObject.SubscribeToEvents();

local textValue = Space.Host.GetReference("Text");
local retrieved;

local updateTextUI = function()
  retrieved = Space.Network.GetShardProperty("testKey");
end

-- this method is called every frame, once "retrieved" gets a value, it displays in text
local onUpdateMethod = function()
  updateTextUI();
  if retrieved ~= nil then
    textValue.UIText.Text = "Retrieved msg: " .. retrieved ;
  end
end

scriptedObject.OnUpdate(onUpdateMethod);
IsReady = Space.Network.HasShardProperties
--This script starts but launches a coroutine that waits for HasShardProperties before continuing

DoWhatYouNeed = function(result)
     if property == nil or property == "" then 
Space.Log("connected but Shard doesn't exist")
      else
Space.Log("connected and Shard exists. Result: " .. tostring(result))
      end 
  
  
end


InitCoroutine = function()
    while not Space.Network.HasShardProperties do 
      coroutine.yield(0) 
    end
    
    local property = Space.Network.GetRegionProperty("A Key")
     DoWhatYouNeed(property)
     
end


Space.Host.StartCoroutine(InitCoroutine)