Proposal: Messaging Layer to Stack manager


I wasn’t in HiFi before the chat was removed, but I have been going over the reasons why such have been removed in the announcement thread… While I do agree with some of it, however I also see why people are completely against its removal. It removes bit of familiarity with any, other virtual world platform out there (even with any of the rift VR platforms out there).

The main problem I see with the third party scripts is that it may distribute the chat channels too much without any standards. We would technically be cursed with a linux like curse in which we have too many distros and too little users per distro, or similar issue with having too many damn frameworks in any scripting language. There is also the issue of hosts:

Id be forced to host the chat service in the same server as my domain as my asset host cant really be used for communications platforms such as this, while Not everyone would also have the capacity to write one or really think up which of a messaging system or framework to use.

Would find it much easier if such messaging layer built into the Stack Manager. I am specifically using the term “Messaging System” because it is the most accurate: Like a voice service, but with text and for Users and Entities.

I feel its kinda off to have everyone re-invent the wheel constantly in different way in different servers, when universal layer could be perfectly available for everyone, while still having the option to reinvent the wheel domain owner wants to. (they can disable the layer)

So here I am with another feature proposal that should match the HIFIs direction of decentralization and username anonymity, Yet maintain some capacity for standardization, and familiarity: It would create a flexible interface that can be used to do cross-entity communication, without having to have the prior back-end knowledge or have an extra server around to handle messaging systems.

The short:

Domains would have their own messaging layer (omni, for entities and user).

It could also pair users for Instant Messaging, Users that are in friends list are only able to message each other cross servers, as they have their “friend” oauth keys shared with each other. Handshake requires both parties to match for each other, otherwise the offended client (where check fails) denies any communication. ( but this could be left to third parties).

The Long:

Allow scripts to connect to the domain messaging layer via a new RESTful API (ON THE domain service stack), where GET requests
is used to retrieve, and POST is used to submit basic Messages. The Domain decides if it should accept or deny communications

Communications between users should be -always- directly, so that the domain only behaves as an initiator and a validator.

The Simple Rules:

  • Store messages in any channels for 30 seconds and and it will there after not be available from the API anylonger.
  • Anything in Channel 0, should be recorded with Log: [timestamp]: [uuid]: [coordinate]: [Message],
  • Channel 0 is the only channel effected by chat distance.
  • Domains must be able to whitelist/blacklist user ids. (and ip addresses)
  • Log UUID validations, and Automatically temporary blacklist any user too many authentication retries in a row.
  • Allow Domain to disable the messaging service.
  • Timestamp is to the millisecond.
  • A user should always have a way to address them: The alias should never, ever be blank. But they can identify as “Guy” or “Gal” or what ever they want. Chat scripts can decide if its displayed as
    Guy#52CDEF, Gal#CDE32 in chat or as Guy and Gal colored depending on their uuid.
  • If channel is not defined in request, then it server assumes its going to be in a public channel
  • The message field can only be 4096 bytes in(1024 utf8 hightier char) and no more than 8 messages a second can be accepted by the server from a source. Also domain will not accept channels that have not been defined, or if user does not exist or is not connected.
  • This also would presume, that channel 0 and 8192 ( 00000000-0000-0000-0000-000000000000 to 00000000-0000-0000-0000-000000002000 ) will be reserved and no other keys will generated into that space.
  • Should be possible to offload to another server.

API requirements

Server make sure that if request ip and sender_id (or other auth method) matches to a user with the sender_id on the server, then stores it.
else it will not allow the message to pass, and automatically blacklists ip if too many requests come, especially if channel is 0.
Do not allow entities to post on channel 0, without prior domain authorization. Entities attached to the user will use the sender_id of the entity, but also include “entity_id”

Server May whitelist users / entities to to talk on channel 0. Entities are not allowed use channel 0, unless specifically allowed to by the domain.

Basically if HiFi DNS works as it should the Domain API isnt really needed: but requests would meet a pattern


Object.getName(Key) - Returns the name of the entity or agent alias if in the same domain. Cached within client, so that if it has loaded it once, it atleast knows what it is named, even if it has left.

Domain interfacing API

(this is, unless hifi dns works in JS as well, so that I can do a request to domain:port/ or something like that),message , function(response))- automatically adds require info. , function(response) ) - Uses channel 0 by default, automatically adds require info. (location etc)
Messenger.get(channel, last_time , function(response) ) automatically adds require info. (location etc)
Messenger.get(last_time , function(response) ) - Uses channel 0 by default, automatically adds require info. (location etc)

Client interface API for messaging agents and entities.

(this has to be done in interface to facilate communication between two users)

User.send( uuid, token message ) - Attempts to send a message to client uuid
User.receive( function(uuid, oauth, message) ) - Binds receive receive callback of the client to the function.

Warning: The Epic

Stop here if your eyes are glazing over.

I am just probably a bit mad, as in insane, in writing this.

A Scenario Example

  • Domain is sets the max public channel chat range
  • Public channel is set to be 0

So Let me explain the process, via the play Othello as a “virtual play written instead of acted” example
in a domain “Venice” in a url location /Street at 200,100,400,
and having one actor plays for two characters,
while another scene on the same server instance, renamed domain “AnotherStreet” also known as Venice/AnotherStreet is at 230,120,420.

Alias Iago, Roderigo @ Venice/Street=
e0046790-fad5-4be2-b30b-27bfb80f4356 username PuppetMaster

Alias Brabantio @ Venice/Street =
6006ccb7-c8e9-4dd2-8d6e-be2d289950e0 username XxSenatorxX

Alias Othello @ AnotherStreet (which is also Venice/AnotherStreet) =
0bed07ef-b54c-4ed2-a240-f908246c9027 , username M00r


Iago: "I am one, sir, that comes to tell you your daughter and the Moor are now,"
Iago: "making the beast with two backs."
Brabantio: "Thou art a villain."
Iago: “You are–a senator.”
[Iago switches alias to Roderigo]
Brabantio: "This thou shalt answer; I know thee, Roderigo."
Roderigo: “Sir, I will answer any thing. But, I beseech you…”
[As the act ends up on Brabantio messages Othello: You ready?]
[Othello Response: Yeah! got my lines copied.]

Before the act, when scripts are initialized, or when location changed, they would get domain time, and sync up to it.
Would go in the following manner.

Iago makes two requests after each other With his scripts:

POST Venice/message
HEAD: POST: "sender_id=e0046790-fad5-4be2-b30b-27bfb80f4356&message=I%20am%20one,%20sir,%20that%20comes%20to%20tell%20you%20your%20daughter%20and%20the%20Moor%20are%20now,&location=<coordinates>" 

POST Venice/message
HEAD: POST: "sender_id=e0046790-fad5-4be2-b30b-27bfb80f4356&message=making%20the%20beast%20with%20two%20backs.&location=<coordinates>" 

After sending, Iago makes a chat refresh. Nothing has been said in the last few seconds thus:

GET Venice/message?time=[last_updated]&coordinate=[coordinates]
Response 200

Mean while Brabantio’s message script refreshes every second or so. So on his script’s cycle

GET Venice/message?time=[last_updated]&coordinate=[coordinates]
Response 200
		uuid: "e0046790-fad5-4be2-b30b-27bfb80f4356",
		message: "I am one, sir, that comes to tell you your daughter.",
		time: [last_updated+500ms],
		location: [coordinate]

last_updated refreshes after each second. When it does this refresh, each request will also check what
the alias of e0046790-fad5-4be2-b30b-27bfb80f4356 is. It will show up on his hud as Iago.

On his Third cycle

GET Venice/message?time=[last_updated+2000]&coordinate=[coordinates]
Response 200
		uuid: "e0046790-fad5-4be2-b30b-27bfb80f4356",
		message: "and the Moor are now making the beast with two backs.",
		time: [last_updated+500ms] ,
		location: [coordinate]

or if his script cycled every 4 seconds, both would be in a single

		uuid: "e0046790-fad5-4be2-b30b-27bfb80f4356",
		message: "I am one, sir, that comes to tell you your daughter.",
		time: [last_updated+500ms],
		location: [coordinate]
		uuid: "e0046790-fad5-4be2-b30b-27bfb80f4356",
		message: "and the Moor are now making the beast with two backs.",
		time: [last_updated+2500ms] ,
		location: [coordinate]

Location info is present to allow for chat bubbles, or which ever as well via script if user has already left the domain by the time of the refresh…

Meanwhile, Othello further than 20 m away from these is waiting for his scene to start. He does not hear Iago and Brabantio are talking about. The server doesnt let him as he is out of domain’s max chat range
As he is located further away. Since he used a different domain url (still of the same), his requests go to the AnotherStreet Domain.

His request would be

GET AnotherStreet/message?time=[last_updated]&coordinate=[coordinates of Venice/AnotherStreet]
Response 200

Back in the main street, Brabantio and Iago continue their scene.

As Brabantio starts his line, Iago switches character to Roderigo.
Roderigo: “Sir, I will answer any thing. But, I beseech you…” etc

When Brabantio’s chat list updates as if another person, Roderigo has started talking, and sees the name tag appear on the person that was earlier Iago.
However his uuid always remains the same, and the chat script can choose to keep this displayed or not (could also maybe recolor the text)

As the scene nears its end, Brabantio’s actor, XxSenatorxX messages Othello’s actor, M00r to get ready.

Private messages would work a bit, differently. Basically a handshake must first be done: To make it easier Brabantio has Othello on his Friend List.
Brabantio’s scripts know Othello is in Domain AnotherStreet. So a request is made to AnotherStreet (which is also Venice)
Each “Friend” or “Contact” will be able to message someone.

POST AnotherStreet/session
HEAD: POST: "auth_key=<users_auth_key_to_contact>&sender_id=6006ccb7-c8e9-4dd2-8d6e-be2d289950e0&contact_id=0bed07ef-b54c-4ed2-a240-f908246c9027"

Server contacts Authentication Provider to check if this is true.
Server would response with 200 when if auth_key checks out.
The communication is transferred to between the two clients instead.

If this checks out, a direct communication line is opened between the two clients.
The script would here would be using the

User.send( uuid, token, message )
User.receive( function(server_uuid, user (object), token, message) ) to receive and communicate

JS API. It can also decide how to show the user names: in this case, it will show the usernames or aliases, depending on the script…

XxSenatorxX: You ready?
M00r: Yeah! got my lines copied.

At anytime, any party in this session can invalidate tokens and mute uuids to avoid reading them through the scripts.

Of course, if such p2p connections can be made completely redundant by third parties, so might as well leave them for them.


:slight_smile: I’ve been mulling over a number of architectural questions that arise out of some things I would want to be able to implement in a domain or sometimes across domains. This one you mentioned is one of them, and too have wondered if low level assists exist or should they be created exactly for the same standards reasons you described. This is a small sample of entity/entity avatar/avatar communications scenarios:

  • I want to make an audio telephone, which means I need the person, who is speaking, conjoined spatially with another person on the other end of the virtual line;
  • I want to have a texting device in which my keyboard input goes to the texting device then gets relayed to the other device, upon which the receiver emits a little tone and displays the text message;
  • I have a flock of birds (rigged entities) flying around and they need to communicate with each other to do swarming behaviors;
  • I have a stargate teleporter system across many domains with locative addresses and some of them might be closed, others might filter who can arrive, and I prefer not to have a central command and control center to run it all.


I’ve been thinking of similar things but along slightly different lines …

Key aspects:
• Communication among Interface scripts, entity scripts, and Assignment Client scripts.
• Authentication of scripts against the domain.
• In addition to GET and POST: a script-to-script Websocket or HTML5 server-sent events publish/subscribe type mechanism would be good; a built-in one-to-many multicast ability could also help reduce overheads.

In regards to local chat in particular:
• Chat “server” script running on Assignment Client (no separate server needed).
• User chat scripts running on Interface instances.

So this does not specifically address:
• Chat ranges.
• Using HiFi’s “friends” facility.
• Person-to-person (script-to-script) messaging across domains.

A further note: In the original HiFi chat and in my current local chat script, when you log in or visit a domain, you get the last N minutes of chat messages rather than just new ones. This is rather nice I think.


Were all circumnavigating the lack of communication systems in HIFI. Were using the forum here like a chat system.
Were using Skype and similar things.
If virtual reality is about immersion then leaving it for whatever reason breaks the illusion.
Its cheating for want of a better word.
We have tried the chat free experiment, and we all cheated.
So we either ditch the forum, gitter, worklist block skype with the interface install
or we accept that we do need global interface based text communication after all.

Let he who hasn’t communicated using text throw the first stone.