Dernière mise à jour: 31 Decembre 2009
A Kailye message can be viewed as a text containing 5 Blocks: one Version Block, one Simulator Block, one MessageID Block, one Command Block, and any number of Resource Blocks. With more details:
In a general way, the content of the Simulator block will be URL or socket of the simulator, while the content of the Resource Block will be the URI of an object description file, chat system, world description file, audio broadcast socket, etc.
Kailye commands or parameters are recognized from others as they always start with an upper case K. Several parameters are separated with &, as usual with parameters in URLs.
Blocks are separated with either LF, CR or both. A message starts with STX and is terminated with ETX. Other messages may follow on the transmission line, or NUL characters on an idle line (assuming they are the lesser energy consumption, or no signal).
Kailye trajectories and parameters can apply to both simulator name, commands or resource names, when this makes sense. As they are passed as parameters of an URL, they are separated with ? And &, as for any other parameter, and thus Kailye systems can be mixed with any other system.
The Kailye language is intended to be a fast communication language. For this reason, it uses data crunching techniques, computer formats, short names, and tips such as avoiding sending repetitive series of unchanging most significant bytes. However this has to be balanced with interoperability.
The first idea was to have Kailye commands, parameters or trajectories, use a character set allowing them to fit into the query of an URI. (the parameters part, between ? and #). The obvious interoperability advantage is that an URL could pass through a non-Kailye system, and be retrieved later by a Kailye system, while still keeping its Kailye parameters readable. However it appeared that this arises many difficulties: sensitivity to future evolutions of URI syntax (example: ipv6 taking two new separators, [ and ]), no warranty that large trajectories will not be truncated, and especially no way to pass computer format coding (chars, floats...), as they can be mistaken for URI separators.
However the first idea was also to have two syntaxes: a text mnemonics syntax, and a high speed computer formats syntax. This much resembles the Assembler language, and editors of Kailye messages will show them in text form. We can refer at the text version as the «mnemonics» message, and the computer friendly version as the «code» message.
So the latest idea is to use the mnemonics syntax for some parameters in the URLs, where the code syntax cannot work, but interoperability may be important. The «code» syntax can be used for longer trajectories which don't make much sense in an URL anyway, but in a separate line, following the resource which requests it:
Resource Blocks are now formed of two lines: the URI line, and the code line. Of course a code line applies to the URI line it follows. All line separators are CR, LF, or CR LF. Same also applies to the Simulator Block. The Commands Block is not URL-bound, so it is better to use the code syntax when possible.
Of course in case a message has to be displayed in an human readable form, only mnemonics are used.
Only experience will tell what parameters and trajectories are to be put into the URI line or into the code line. Ideally only URI line should be used, but this version 0.0 proposes to put most short parameters into the URI line, while lengthy trajectories are into the code line. And the code syntax uses as much as possible a syntax (mainly separators) compatible with the URIs syntax. Evolution of future versions is hard to predict.
In the mnemonics version, the commands and parameter names use ASCII alphanumerical characters, more some convenient separators: dot, hyphen, underscore. They are separated with ? And &, as for the usual URL's parameters syntax. A parameter name and its value(s) are separated by the equal sign, as in URLs. The dot is used into some URI schemes, and into Kailye's hierarchical names. Free texts, including full ASCII range, entities, UTF-8, etc. are enclosed between double quotes. The $ is similarly used to enclose some names created at runtime, with the same rules as with the double quote. Last remaining ambiguities are solved with the use of escaped characters: \", \$ and \\ (PHP rules). Number and data formats are plain text, for instance a char is written 125, a float 1.4564E-5, etc. Data tables (mainly for trajectories) are built using the coma and semicolon as field and line separators.
In the code version, the commands and parameter names use an UTF-8-like coding on only two chars (three for specialized names) starting with a 128-255 char. Some use 0-32 ASCII characters, and custom-created names not yet registered in the standard will still use alphanumerical writing. Separators remain the same. Free texts remain the same. But now, data tables use only computer formats, without separators, in order to crunch data size. There is still however a first format line in plain ASCII text telling the formats used. This format line is also present in the mnemonics version, and it uses one specific character, the tilde ~. This one is chosen to remain robust toward additions to URI standards.
A Kailye connexion between two simulators may be established permanently, established for a session, or for an unique message, depending on the situation.
As for every data content, it must start with a clear identification of the language used and its version. For instance: Kailye=0.81 stands for an eventual version 0.81, and it is written into plain ASCII into the message. This allows for instance to change the behaviour of a command in a further version, without ambiguity between the two versions.
The version system should not be abused. It is reasonable to have many versions 0.xxx for tries and studies. But this will not be allowed beyond an unique version 1. This version 1 must be mature enough to be forward compatible and propose usable and interoperable systems. Its purpose will be to gather extensive experience and feedback to get the definitive version 2. This version 2 must warrant a professional quality and be free of any known or foreseeable bugs and problems. Eventual version 3, 4... should appear only every 7-10 years, for adding new unforeseen technical possibilities or uses.
The Kailye language must have a standardization committee. For now (2009) it is composed of only Richard Trigaux. Any implementation of the Kailye language is bound to comply to the syntax decided by the standardization committee. Starting with version 1, all elements must e implemented, except some valid exceptions. Partial implementations must provide with a list of implemented or non-implemented elements (this is not required for sex elements, when the context does not require them).
The main applications of the Kailye messages will require a cyphering, preferably at the level of the connection itself. If not, a cyphered Kailye message will add a letter (or several) to its version, telling which cyphering system is in use, for instance: Kailye=0.81M. (of course, this Kversion block is not cyphered!). This is because the cyphering may have to evolve quickly, to cope with emerging threats, to the contrary of the language itself which much remain as stable as possible. Of course the syntax of a cyphered version is exactly the same as the corresponding non-cyphered version. So the Kailye version and the cypher code can evolve independently without interacting on each other. The cyphering letter will appear into the Kversion block or into safety documents, but we shall not speak of it about the evolution of the Kailye language itself.
Some applications of the Kailye messages will require high reliability versions, or other specialities. Such special versions must have the same syntax than the basic version of the same number, save some exceptions precisely justified by the peculiar requirements, such as for instance a redundancy of content. Such special versions, or high reliability versions, will add letter groups as a prefix:
Kailye=R2.00 stands for a high reliability version.
Kailye=R.XLM2.00 stands for a high reliability (R) version which would use <XML> tags instead of the separators used here.
The use of this Block is to identify the sender of the message (a simulator). As there will be millions of simulators, we need a non-ambiguous identification, without the need of some world wide table which will always lack the last updates. URIs were precisely invented to automatically provide each internet object with a unique name, and to always find it wherever it is. So basically the URI line of the simulator Name block will contain an URI ready to use, and some complementary parameters. Typically:
or, after the most general terminology:
The most commonly schemes used for simulators will be HTML addresses or sockets:
IPnumber:portNumber (The port number is optional. For instance: 220.127.116.11: or 18.104.22.168:9900)
Of course this line strictly follows the URI conventions. This is a purposeful and unquestionable choice, for the sake of interoperability. Most often the subdomain of virtual worlds will be something like «meta» (metaverse) in the place of the classical «www». But it can also be something like «John-doe-dreamworld». Of course the path gives the directory of the simulator executable file into the simulator's computer (there may be several).
Each scheme having its advantages or inconveniences, we may need to provide a complementary information from another scheme, using the ?KURI parameter. We can now do things like associating a directory tree to a socket:
or, on the contrary, a port number to an URL:
The ?KURI parameter must specify an URI scheme, because its content does not always allow to infer it:
(in this case we can differentiate a email box from an IM box)
(in this case we tell a 3D viewing point)
Other parameters can be added, such as an human readable name of the simulator, or world, in a free text form:
?KhumanName="Notre île de rêve"
We may also need mime types to open files, when the name is not enough to open it:
The ?KID=ID parameter is intended to replace a long URL by a short identifier, for commonly used resources or simulator names. One of the simulators can propose such a name:
?KID=ID suggests to call this resource's URL or simulator's URL by a short name. The shortest available name must be used.
?KID=ID,ok tells that this name is accepted
?KID=ID,no,ID2 tells that the name suggestion could not be accepted. But there can be a second proposal such as ID2.
?KID=ID,deleted tells that the name is deleted and available to other uses. This happens automatically when the connection is closed or lost.
Into the simulator memory, ID will be some kind of index sending to a memory space containing the full syntax or URL.
When creating a name, the associated parameter values are included into this name. This is fine when it is something fixed such as a human readable name, but more questionable if it is something variable like a position. In this case it will be considered as a default position, and we shall be able to indicate relative displacements. Relative or absolute displacements can be appended later, they will not be included into the name and not be considered as default values.
We need to define the scope in which this name is used. It is even mandatory:
?KID=message$name$ tells that the scope is only the current message. In this case, the name is attributed by the sender, and there is no need of dialogues like ok, no, etc. as the ID is discarded at the end of the message.
?KID=session$name$ tells that the scope is the current Kailye session.
?KID=link$name$ tells that the scope is the current Kailye link (wherever it is established or not).
?KID=simulator$name$ tells that the scope is the simulator.
?KID=object$name$ tells that the scope is only a given object. This will be useful for complex objects like bodies, machines, etc. These names are attributed by the simulator which runs the object.
?KID=scene$name$ tells that the scope is the current scene. Scene must be understood here as a given part of the world, having an unity of purpose, owner, etc. This is not necessarily one simulator.
?KID=character"name" tells that the scope is the current character.
?KID=world"name" tells that the scope is the current world. These names are attributed by the world owner.
?KID=CHC"name"$name$ tells that the scope is the current Character Hosting company. These names are attributed by the considered Character Hosting company.
?KID=WEM$name$ tells that the scope is the whole WEM system. All the simulators must use these names. These names are attributed by the WEM management.
Defining the scope to a given object, simulator, world, etc. must be done carefully: there must be no ambiguity as to which object, simulator, world, etc. the name pertains. Also, a simulator, objects, world, etc. will manage itself its list of names, with ?KID=ID,no,ID2, so that it avoids to have an ever expanding list of names proposed by all the other simulators it may deal with. To avoid such issues, two rules apply, in this order of priority: an authority which hosts something will attribute names in this scope, 2) the computer which initiated the connexion will attribute names in this scope.
The $ separator is used for Kailye created names, and the " for other authorities. Both separators are necessary, as non-Kailye names may contain non-Kailye characters, and Kailye names may be used by other systems using a different char set. But it is required to use only ASCII 0-128 alphanumerical characters, more the hyphen and underscore, as some simulators may use these names for building file systems. Also, a sense of hierarchy in names can be added with the dot as separator, as seen at: 8.3 - The hierarchical naming.
Such a communication seems impossible to establish, if we have to receive a first message before knowing the address and protocol. In fact, the communication between two simulators is first established by a third party, such as a Character Hosting Company, or a world manager. For instance the Character Hosting company finds the address of a world into a metaverse search engine, or the world management tells two of his neighbouring simulators their respective addresses and coordinates. Another possibility is a portal opening a door from one world to another: it mandatorily has a directory of possible destinations. So in further two-parties messages, the URIs or names are here only as non-ambiguous identification of the sender, in a flow which may contain thousands of messages. And the protocol name usually included into an URL is no more used for connexion management, but only as a complementary identification (several coonnexions may use the same address with different protocols).
This may give rise to some funny behaviours of the portal, as an innocent victim will go through it without trouble, while his evil pursuer is rebuffed because it leads to a PG world.
This Block has for purpose to automatically provide an unique message identifier, when messages may fly per thousands from a given sender. The best system seems to be a time stamp, which is also useful for the receiver to handle priorities and obsolescence of messages, or for the simulation itself.
The Unix time looks like the obvious solution. However it arises a format issue, as 10 digits are required for the number of seconds, and further accelerations in computer clocks may soon require 9 or more digits for the fraction of a second. This makes 20 digits, which make even 64 bits floating numbers uncomfortable. Using computer formats may shorten it, if the time gained is not lost into code translation. So keeping to a text with no imposed length seems the simplest way, and more robust toward future evolutions.
So the proposal here is, in the mnemonics format :
For instance: KtimeStamp=1236452325.897456
And in the code format :
where X and Y are one digit hexadecimal numbers telling the number of octets of a binary number, respectively of the integer part and decimal part. In more, .X^Y is coded with only two chars, with the UTF-8-like system. Such a format does not need transcoding, and it can span from far beyond the life of the universe to near the Plank time, so that we have some time left to think at a more powerful one. This syntax will also be used for time.X^Y and Kack.X^Y . A decimal variant of this format will be .y^y, where each octet codes for a number from 0 to 99, x and y telling the number of octets.
When a message is a reply to a previous, we can add the time stamp of the replied message as a second field:
We can make provision of a thread name or topic name:
This name must use the URI allowed characters: alphanumerical characters, more the dot, hyphen or underscore, and be limited to 128 characters in length, because of the possible use of this field as a file or directory name:
Some systems may store Kailye messages as files in RAM drives (piles, buffers or databases can be used too). In this case, the name will be the content of the MessageID block, more the extension «.kailye» (assuming that all systems now accept extensions longer that 3 characters, and a total file name length up to 256 characters). This length also limits the thread name length. However the length of the timestamps being not fixed, we cannot set a determined maximum length to the thread name. Hence the caution to limit it to 128 characters, to avoid bad surprises into the future.
The names set by the ?KID parameter can also be used to build file names or database indexes.
The relation between a given object and a simulator may experience different situations. The simplest is when the simulator owns the object: it animates it at 100%, and stores it into its memory. This is the only way to do until now (2009), and this will remain the case for the majority of objects, landscapes, buildings, etc. If a character rezz a building into a land, he thus issues a request for adding it to the memory and hosting it. Let us say that in this situation the simulator hosts the object.
But if this object comes for instance from a Copyright Server, it will remain stored on this place: the Copyright Server is now the host simulator. The local simulator however will still handle the object: to animate it at 100% without referring to the host simulator, but now without storing it locally. This is true for inanimate objects like clothes, jewels, etc. which wander from simulation to simulation, but don't have custom behaviours, so that any standard simulator can understand and animate them.
A third situation appears when the object has special features that standard simulators will be unable to animate. This is usually the case for a character, which is run by a simulator on a Character Hosting Company, and who then enters into varied simulations. This will be also the case for a personal «movable garden» or spaceship able to travel into other landscapes, complex machines or physics simulations, vendors or teleconference systems, etc. Another case is a copyrighted object, or private/professional objects, which code or content must not be disclosed. Objects or characters in these situations will remain hosted on their own simulator, while being monitored by the local simulator they entered in. The monitor simulator will even not load the object in its RAM memory, only experiencing its behaviours. So in this situation, the monitoring simulator will have to send messages to the host simulator, as what the character is touching something. Up to the host simulator to adapt the character's behaviour accordingly, and in return inform the monitoring simulator of the new behaviour. It is clear that this kind of situations will entail many fast messages, but this cannot be avoided in any way. The Kailye language is just for this.
A special case of monitoring will be the haptic monitoring, when the user has some exoskeleton to directly feel the objects into the world. In this case the haptic monitor will not need to send collision messages, but force return messages instead. And the user will correct his behaviour himself, sending messages to his character in world.
So the first Kailye commands will be requests/acceptance/denials about handling/monitoring objects.
But the most common messages will be requests/issuing/warnings/denials of trajectories, and any other useful data for computing the behaviour of the object.
The WEM messages of the Authorisation management Connexion will mostly deal with monitoring the entry into worlds, teleportations, authorisations, etc. Due to the permanent nature of this link however, it will also be used for establishing connexions. It will also be used for the user to control his character. In the reduced WEM architecture, it will also feed the viewer with trajectories.
Command and parameter names in Kailye always start with K. This is what differentiates them of other commands, and allows any system to correctly interpret them as such, with a known and specified syntax. If it has values, the command name is followed by = and the values. Different commands are separated by &, like the parameters in an URL, for coherence with the other Blocks. However multiple commands are not recommended, and must be used only if they relate to the same event and objects, such as for instance a rezz request and a trajectory request for the same object. Otherwise, a complex syntax would be required to sort out which objects are concerned by which command. In this case it is better to have several messages, each clearly relating to a given (set of) object(s). Some commands however can be appended in any message, such as the connexion flow controls.
Values can be predefined, or free, depending on the command. They are gathered in a table, fields separated with comas and lines by semicolons. Kailye's Hierarchical names can be created with the use of the dot. Contrarily to trajectories, table lines are not required to have the same number of fields. Fields contain the usual set of alphanumerical characters and separators, but some commands will require free texts enclosed into double quotes.
There is no defined limit into lengths of fields, values, etc. However it is wise to keep it short: most systems will limit them to 256, save the free texts, which should be much longer.
Kailye commands tell he purpose of the message. They are separated with &. They apply to all the resources which follow, while parameters or trajectories apply only to the resource they are appended to.
In some cases, the same word can be either a command or a parameter, in other cases only one makes sense. So in the texts which follow, commands are written as such, while parameters have a ? added in the beginning. Versions starting from 1 will have to provide with a clear list of mandatory implementation for one case or for both.
If several objects need each one a different command, it is better to send several messages than creating a complex syntax for this case.
Khosting is a request sent to a simulator to host the following object(s). The object is in a first simulator, where it can be in world, or in a dormant storage, such as a personal inventory. If this command is successful, the second simulator loads the instance of the object into its own memory and no more refers to the first. If the object was dormant, it is attributed a position, and is thus rezzed into the second simulator's scene. If it was already in world, then the first simulator will have to send the position or trajectory. The second will have to build on it, while the first erases any reference to it. Both operations must all take place at the specified time. But if the object is non-duplicable, copyrighted, private or non-editable, etc. then the Khosting will not be denied, but smartly interpreted as an appropriate Khandling or Kmonitoring attempt. This saves a round of error messaging and some hundreds of milliseconds.
However this command can be issued only after a WEM's Kmetaconn command, which checks the authorizations for the object into this place. If this Kmetacomm command denies the transaction, it returns its own motive to the user. In this case, the Khandling transaction must NOT take place. Passing over a Kmetaconn denial is mostly a world rules infringement, it may even be a legal infringement.
Khosting=request,timeStamp.1235675654.66 asks the second simulator to host the dormant object(s), and implicitly to the first to accept to release an instance. timeStamp is the date at which the operations must take place. Implicitly in all what follows, we can also use the code format, with syntax of the MessageID Block:
Khosting=accept,timeStamp tells that the simulator which sends this can host or release the following object(s). If needed, timeStamp is the date at which the operation must be effective.
Khosting=deny,motive tells that the simulator which sends this cannot host or release the following object(s), for the indicated technical motive (error code).
Khosting=accept,handleInstead,timestamp tells that the simulator cannot host the following object(s), but allows it for handling.
Khosting=accept,monitorInstead,timestamp tells that the simulator cannot host the following object(s), but allows it for monitoring.
Khosting=done,timestamp tells that the simulator which sends this is now hosting the following object(s).
KunHosting tells that the simulator which sends this wants to stop the hosting of the object. This will usually result into only the deletion of the object of the memory of this simulator. The dialogue will use: Kunhosting=erase,timestamp, Kunhosting=accept,timestamp, Kunhosting=deny, Kunhosting=done,timestamp.
Khosting=transfer,timestamp asks a second simulator to become the host of an object(s) which is already active into a first simulator. So the second has to create an instance, while the first erases the previous instance. timestamp is the date at which both operations must take place. The second simulator can also in turn get free of the object by transferring it again to a third simulator, with a second Khosting=transfer,timestamp .
If no time is specified into the Khosting command, then the operations take place immediately. But in the case of a transfer there is a risk of seeing the object flickering in and out, or being doubled. So in the case of a transfer, the timestamp is mandatory.
Khandling has the same functioning and syntax than Khosting, save that no second instance of the object(s) will be created into the second simulator's memory. This situation arises with non-duplicable objects, copyrighted objects, private or non-editable objects, etc. However the second simulator still has full freedom to handle the object, such as authoritatively assigning it a position, trajectory, or use any other available control of it (Usually, standard controls that all the simulators are expected to understand. Special controls, thought, may be sent by other objects able to communicate with the first, by special Kailye connexions). So, in this situation, no transfer of 3D code will occur. In case the object(s) is not duplicable, the host simulator will mark it as instantied, and allow no other instance of it. (at a pinch, there can be a maximum number of instances)
KunHandling (and Kunmonitoring) will now result into the inventory or copyright server to uninstance the object, and eventually allows for its use by another simulator. This is especially useful for non-duplicable objects, when they change of owner. But it is also useful when an non-duplicable object goes from one's inventory to a world.
Kmonitoring still has the same functioning and syntax than Khosting, but this time the object is too complicated to be handled by the second simulator. A second reason may be that the object has custom controls or behaviours that the second simulator cannot make work. A third reason may be that the object contains private or copyrighted data, that the second simulator must not access. A fourth reason is with characters (who may often have custom features), complex machines (cars, spaceships, moveable homes, physics simulations...) or complex systems (such as teleconferences for business, etc.) In this case, as with Khosting, the second simulator will not have access to the code or content (text, image, sound) of the object(s). It will know only its place (URL) into the first simulator. But further, the behaviour of the object will be calculated on the first simulator (such as a personal space, character simulator, etc.). So this is the situation where two simulators will have to exchange commands and trajectories to match their action, and this is the purpose of the Kinflex command, which asks for modification of the trajectory. This trajectory is indicated as a parameter appended to the object(s) itself (in the Resource block).
KhapticMonitoring=... still has the same syntax, but in this case the haptic monitor will send force return instead of Kinflex commands. The user will have to actuate his character position using an exoskeleton. Obviously when an exoskeleton is used, the user will need to use a different viewer, which will set this mode automatically.
In the case of Khandling, and also Kmonitoring, we note that the handling or monitoring simulator will not need to know the detailed shape, textures, sounds, etc. of the object. But it will still need to know its URL and its basic properties, such as bounding boxes, and generally a hierarchical geometry model of its different parts, or the skeleton model of a body shape. Any other data will be cumbersome, forcing the simulator to parse into the file for the rare useful data.
We can use this property to avoid disseminating copyrighted objects, private or confidential objects, or objects which have been bought and must not be duplicated. So in these cases, the Copyright Server, or generally the host simulator, will serve only a reduced 3D description file, stripped of any copyrighted 3D shapes, URLs of textures, sounds, etc. So the handling simulator or monitoring simulator will still be able to deal with the object. The full file, with texture URLs, will go only from the Copyright Server to the viewer, that is, ideally, into the case of the integral WEM architecture, from the Copyright Server to the Character Hosting Company. So neither the user or the simulator owner will be able to access copyrighted or private elements.
But still some of the data contained in the plain file may be necessary for the simulator to know, for instance a texture map, in the case where this texture map is to be animated on the fly. Or even the textures URLs, if there is a texture changer. So, in these cases we still need to send this data to the simulator... where it is exposed to pirate simulators. So, at this point, it is up to the object designer to decide which data can be exposed or not. If a texture map or texture URLs can be exposed, the object can be handled by a simulator. If not, then the object will have to be monitored, while hosted by another simulator, eventually the Copyright Server, which thus must be able to animate it... eventually with millions of instances. A service which may be costly, so that designers will have to break their objects into sub-objects which each will be handled or monitored, depending the degree of protection they need. For instance a texture changer will swap, not textures, but sub-objects, which can be handled without exposing the texture's URLs. A texture map changer will provide with some command parameter, so that the map itself can remain safe on the copyright server.
A fine mark would be that the geometry hierarchy into a geometry hierarchy file is translated as a more deeper path into the base URL of the object. For instance, for a character:
is the URI of the geometry hierarchy file of the lazy Smurf. But if we consider an arm, it will get its own name in the geometry hierarchy file. For instance, in X3D, we have:
<Transform DEF='left-forearm' rotation='0 1 0 0.12' translation='0 .02 0'> which sets a name to this body part.
So that we can compose a short computer friendly hierarchical name of this arm:
In the code syntax, two octets codes are provided for all body parts, and only the character name is in plain text, so that this name will require only 15 octets.
Kinflex is the most significant Kailye command, which deals directly with the simulation itself. It tells that the message is for requesting an inflexion point into the trajectory of a monitored object. This happens when a simulator disagrees at a certain point with the planned trajectory of an object it is monitoring, either because an obstacle is encountered, or because another character or a script acted on it. So it sends an inflexion key to the hosting simulator, beyond which the trajectory must be modified. This command implies a specific message structure: the first object in the Resource Blocks will be the impacted monitored object, for instance a character. The other objects may be the ones which are provoking the change, for instance a wall, another user, etc. Also, sending the actual trajectory of the monitored object may help the host simulator to compute a new one.
More details on the Kinflex command are given further, after studying the Resource Block.
The functioning of a Kailye link must be considered as relativistic, due to the hundreds of milliseconds to tread a world wide connexion, compared to the microseconds of a Kailye message. This means that there is no mean for the sender to know things such as the receiver's buffer being full. This makes that the old teletype-like controls, such as STX, ETX, XON, XOFF, EOT, ACK, ETB, etc. are completely useless, to the point that we can without regrets re-use them for other purposes. Maybe to code the following Kping commands.
So we need some means to avoid trite situations like hundreds of messages crashing at an exquisitely high speed against such a stupid thing as a full buffer. In a more general way, simulators will need to know the transmission delays toward their fellow simulators they are working with. As a world wide link delays table would be unreliable and cumbersome to manage, the best is that each simulator measures this ping time on the fly.
The first thing is a simple acknowledgement. If the sender message has the command Kping with this timestamp:
Kping(other content may follow, or not)
the receiver can acknowledge it with the addition of a Kack command, echoing the first time stamp:
This allows the sender to know the ping time of the link.
Of course in this case the target simulator will just echo the Kack message without using the reception buffer, so this works even if the buffer is full or the simulator busy. If the message requires no reply or bears no information, there is nothing past the Kack command. A significant reply may come later, when the target simulator finds the time to compute it.
This pinging system allows for accurately measuring transmission delays, for managing priorities into replies or actions.
But in the case of physically mobile simulators, such as for instance an enhanced reality session of a virtual astronaut performing a task into space, then this delay will vary. In space, clocks will too have relativistic shifts, but this effect is much smaller than transmission delays changes, so it may become noticeable only if we do a simulation of a thing like a neutron star, with each simulator having its clock artificially shifted. This to say that simulators having to run in space will have to ping their connexion at each message. In the case of the neutron star simulation (or for accurate space measurements) they will have to make no assumption on other simulator's clocks, and only deduce their date and rate from the results of the the Kack command. If these precautions are taken, the Kailye system should still work into a strongly relativistic environment. It may be fun to have standard simulators able to work into a strongly relativistic environment. It may even be useful, for things like space games, real space missions, or science education.
To manage the buffer will require other commands:
The letter tells the unit (k=kiloOctets,M=megaOctets, G,T, P, etc.) while the request fields are a request to know. Note that the convention is that the sender always tells first his data about his own reception buffer, as any other convention will necessarily depend on previous messages to be understood. Eventually the sender may place values about the receiver's buffer, so telling the receiver what the sender is guessing, and will send messages accordingly. If this guess is false, the target must correct it.
Starting here, there are two ways to manage the buffers use. The first way is to send messages only accounting to the actually known free space into the reception buffer. This ensures that no message will ever be lost, and is thus privileging reliability. This system is also simpler to implement.
The second way is to make a guess of the space which will be free when the message will arrive. This is faster, but may lead to the loss of messages, which will provoke error messages, will need to be resent, etc. So this way of operating is not recommended, or only with a very pessimistic guess allowing for very occasional losses.
For this to work better, we can add two fields indicating the estimated byte rate in a close future, and the guess for the other partner:
This nows allows for the guess system to work with guaranteed zero message loss, as the emitter now knows at which rate the receiving buffer is emptying, or the receiver knows what to expect (and of course it must be able to empty the buffer at the rate it specified). With the time stamp of the message, we can calculate the buffer content at any time. At a pinch, negative values of the reception byterate tell that the receiver is in an overload situation.
The most complicated case is when several Kailye senders converge together on a given receiver. There are several solutions for this, such as the receiver having the capacity to attribute and handle several ports simultaneously, or to have several instance of the reception system. Or if the receiver is overloaded, it will share its buffer capacity and tell only the share to each sender, using Kbuffer.
So message loss will occur only into an overload condition. But in this case, the emitter will have to prioritize some infos. However this must be done with some knowledge of what the users can tolerate or not: chat is more urgent, then close characters, characters in chat, pointed characters, or the objects the character is currently interacting with. The overloaded simulator can also lower its frame rate. All these tips do that the degradation of the rendering will happen only progressively, and without abrupt loss of vital information (such as characters being ejected from the scene). But the best typical WEM solution is that an overloaded simulator can request another to handle part of its load, most often in sharing the scene between several simulators. This is dynamic attribution of simulators to scenes.
It is to be noted that the reception buffer of a Kailye link is a crucial part, so it cannot be just a simple circular pile. As messages may be more urgent than others, or simply be the concern of the simulator at a given moment, we need to be able to search along the pile, as into a database. This makes that read messages will be deleted at any place into the pile, creating blank spaces. So the circular pile itself will have to contain only indexes, toward random places into the general RAM memory of the simulator, which will be allocated and freed by the main system as any other variable. So the buffer will be a table with at least five fields per line, or more if there are several Resource blocks. This allows for instance to search per message ID, per sender, per resource, etc. When a message is erased, only groups of indexes need to be shifted into the buffer, not full messages. And when a message is received, its content goes directly into the RAM.
We consider as «errors» the result of technical failures of some part of the system. Denials of hosting, accessing, etc. are NOT errors.
There is a huge variety of possible errors, many being specific to a given simulator. However we can get some basic errors reporting system about the Kailye link itself: when a receiver has to deal with an error into the message, it can send a reply containing the Kerror command.
«Place» is the position, in octets, where the error occurred. When a whole Block is in error, the position of the first character is used.
A peculiar case is when a message is only partially received. Usually there will be no ETX character, and the sudden appearance of a series of NULL characters (idle line). In this case, the reception system will have to send the error message directly, without using the buffer, as with a Kack reply:
This will trigger a full resend of the message, which is suspect of having other transmissions errors.
For a full buffer, we have, still as a direct reply:
This will trigger a partial resend of the message, starting from the missing part:
A Kailye version error will be:
where «unsupported_version» is the error code, while «SupportedVersion» is the name of the latest version the receiver can handle.
We can start a list of possible error codes:
Kerror=place,URI_not_found The resource URI was not found
Kerror=place,URI_error.404 This tells the http error code, such as an error 404 in the example. These two examples will often happen when a Konnect command tries to establish a connexion.
Some resources may require a login and password, or a payment, or other access conditions. But this has to be managed previously by the Kmetaconn command. But an error may occur if the condition undergoes a time-out, or is lost, resulting in something like Kerror=place,URI_error.404. In this case, the corrective action is to send again a Kmetaconn command, in order to find a new match for the connexion. A good preventive action is to resend the Konnect command at regular intervals.
Kerror=place,unsupported_command these two can both result from a version problem, or from a transcription error. Note that only commands or parameters starting with a «K» can trigger one of these two errors. Note also that there may be non-Kailye parameters starting with K. For this reason unsupported commands or parameters are just ignored by the Kailye system, without interrupting the processing of the message, and without deleting the concerned parameters if the message is to be forwarded to a non-Kailye system.
Kerror=place,transcription_error There can be many kind of transmission errors, and no sure way to get all of them. So when an incoherence is certain into a message, it is safer to resent it all. If the same error is detected again in the same place, the sender should reconsider its output. If, in a resend, other errors occur again at other places in the same message, the communication is at fault.
It is to be noted that the connexion should have its own checking system, and its own error reporting system, built-in in the protocol, so that appropriate actions can be taken (such as re-opening another connexion). Also such a system will have to deal with transmission packets, as often errors appear on a packet to packet basis.
Kerror=place,unmatching_duplicate In high reliability versions of the Kailye, Kailye Blocks or transmission packets may be duplicated. A difference between two identical Blocks or packets safely points at a transmission error. Having three or more duplicates allows for some self-correction of transmission errors.
Kduplicate.message.KtimeStamp=1236452325.893547 This tells that the message is an exact duplicate of another message which time stamp is indicated. The remarks are the same as with the duplicated Blocks.
The syntax for naming resources, and especially objects, is the same as for the Simulator Block, for the same reasons. Just that, in the URI line we shall have more often the HTTP:// syntax for hand created sites or worlds, socket syntax for things like Shoutcast audio broadcasting channels, or mailto: syntax for chat channels. So we still have the KURI syntax, and at need the ?KhumanName parameter.
We can imagine many useful parameters to accompany an object, such as its position, its owner, its internal states, etc. Some of these can be Kailye parameters. Again, for the sake of interoperability, non-Kailye parameters are mixed with Kailye parameters, in any order. However Kailye parameters are recognizable as they always start with K.
The fragment of the URI (part starting with #) will have to be kept and transmitted in any case, as it will often be used to tell things such as teleport points, which play in 3D the same role as anchors in HTML. Removing this part will produce things such as landing into the 0 0 0 coordinate of the scene. (removing the fragment is done in some languages, like the PHP, as a «safety measure». I suggest the geeks who take this kind of «safety measures» that they also abstain of food, as in may contain poison).
And, as with the Simulator Block, we still shall have the URI line, and the code line. The repartition of parameters will however be similar, with short parameters and non-Kaylie parameters into the URI line, and trajectories into the code line.
When we get the description of an object stored in a file in an URL, it is only the static description. This static description may contain scripts or animations, but it does not tell what the object is actually doing at a given moment of the simulation.
For this reason, trajectories are provided to tell the actual behaviour computed by the simulator. Passing these trajectories is the main function of the Kailye language. Trajectories contain more data than parameters in URLs, and this data is organized in a table indexed with time keys, one time key per line and one data field per column.
These trajectories can be of many types: position and rotation of course, but 3D simulations may also involve changes of colours, shape, texture map, NURB knot vector, and even texts, numbers, logical states. From here the many types or trajectories proposed in the next part.
In more, a given trajectory may tell data of different natures, in order to avoid repeating the time indexes.
For these reasons, the basic syntax for a trajectory is a table of key values, with time keys as indexes. These values are presented as a table of values, with fields separated by a coma and lines separated by a semicolon. Here is an example of a position table of an object accelerating at 1m/s2 along the X axis:
position=1,0,0,0; 2,1,0,0; 3,3,0,0; 4,6,0,0; 5,10,0,0; 6,15,0,0; (This is not the actual syntax!)
This is not very different of a simple indication of a fixed position:
Basic syntax of a trajectory:
It is to be noted that the format line has zero as index.
It is to be noted that the trajectory starts with a ? which is a reminiscent of the statute of URI query part (parameter) of the trajectory. When trajectories are actually into the URI line, they of course start with either ? or &. We can pass trajectories into the URI line of the Block, so long as they are written using the mnemonic syntax (plain text). But long trajectories must be passed into code format into the code line.
One may think that non-moving objects will not require trajectories. However, once trajectories are implemented, it becomes much easier to use them in all cases, to set the position of any object, even if it is always immobile. In this case, the trajectory is sent just once, and it will contain only one line, the format line, with of course the desired position as paddings.