SLSA Protocols for Sailing version 2
From SecondSailing
SLSA Protocols for sailing Version 2
Status of this document: Under discussion
This document contains a series of guidelines for boat builders to follow if they want their boats to be compatible with the SLSA racing system and be able to communicate with other boats on the water.
We identify communication between:
- racedirector/sailor and wind/wave/current setter
- boat and wind/wave/current setter
- racedirector/sailor and startline
- boat and start/finishline
- startline and finishline
- boat and buoys
- 2 or more boats
- boat and external systems
If a builder uses (a part of) this protocol, he/she commits him/herself to supporting all future changes to the protocol as well. Also will the builder follow the protocol exactly and completely and will implement every applicable mandatory part of the protocol and will not make it's own changes or enhancements to the parts that are used. Instead, any needed changes and enhancements should be made by altering the protocol itself and thus making them available for everyone.
Implementing the wind, waves and current described is made easy for boatbuilders by using the free available WWC Receiver and WWC Interpreter scripts. These scripts provide wind, waves, current, race subscriptions, wind shadowing, wind fluctuations and local conditions. Contact Mothgirl Dibou or Cynthia Centaur for a copy.
Design goals
The following issues shall be covered by this specification:
- The communication shall be extendable, i.e. when new parameters turn out to be important for new boats/applications it shall be possible to add these parameters
- The communication shall allow to implement distributed systems, ie. a set of devices located in several objects which are not necessarily in the neighbourhood of each other (e.g. a race course with buoys on the course that report a passing boat).
- The communication shall allow independant systems which don't interfere, e.g. race wind that only acts on boats "logged in" to that race. This also includes indepedant systems of the same type (e.g. two race winds for two start lines close together)
- the system should be open to every serious boat builder and for every serious builder of racing equipment but it should include a few "secrets" that make it necessary to ask for those. The reason behind that is to disallow anonymous usage of these specifications to discourage griefers.
- explicitely excluded (and not forgotten) cryptographic and similar means to obscure or verify the content of sent messages. This specification assumes that cheating and griefing will not be done by serious members of the sailing community.
Roles
Three "objects" are needed to play a role. The here used word "object" is not identical to SL "objects", see the next chapter for more details.
- The race manager: The race manager is the first object that a boat should have contact with. It announces it's existance and gices further details. It also does the book-keeping for the race, i.e. it keeps track of boats logged into the race, crossings of the start line, ....
- The wind manager: the wind manager is responsible for managing wind, waves, .... and other environmental parameters that influence a race.
- start line: The start line records events important to the race and sends them to the race manager. The term "start line" shall include other devices like buoys, finish lines, .....
remark CC: There is a catch 22 here. The more objects/roles we define the more emails must be sent by a boat to different objects. This will lead to either the use of multiple email sender scripts or heavy delay. This might become a show stopper. We need a solution here. The obvious solution is to join all roles in one object.
implementation of these roles, objects
The above chapter defines roles, not their implementation. It is explicitely legal to implement all roles in one SL object. We advise boat builders to not rely on any implementation so you must expect to get different messages from different SL objects in different mails.
Communication between race manager and boat
Race invitation
A race manager publishes it's existance by sending a message on channel XXX. This message can be sent as region, shout or say. It's up to the implementer to decide this and to follow different strategies with that.
The message has the following format:
message type, (value = "Rc") race id (randomly generated number), race name (f.i. SAILON), class name (f.i.: Flying Fizz, Tako, Tradewind), sailing mode (0,1,2,3 meaning: no requirement, novice, competition, expert), crew size (0 if no requirements, 1, 2, 3, etc), name of race director
Note that these parameters are only for prompting the sailor if he/she wishes to compete in the race, The "official" parameters are send through email.
The boats pick up this chat message and ask the helmsman if he/she would want to subscribe to this race.
Race information
Once a skipper decided to join a race it sents a request to the race manager to get more informations:
Communication between racedirector/sailor and wind/wave/current setter
See WWC Setter help notecard for this.
Communication between boat and wind/wave/current setter
The WWC setter precedes every broadcast it does by a "ping" message on a fixed secret channel channel. Boats use this signal to compute the secret channels for receiving old style wind, cruise settings and race settings.
The WWC setter broadcasts its cruise wind settings 3 seconds after the ping on a secret channel that is calculated according to the rules defined by Kanker Greenacre. The data strings send are also defined by Kanker Greenacre. These broadcasts are for backward compatibility only and ensure that older boats like the Tako can use the wind as well. If a race is started, the race wind will be broadcasted instead.
- Cruise wind/waves/current
This part of the protocol is mandatory. Implementation can be done by using the standard WWC Interpreter and WWC Receiver scripts.
Any boat that uses this part of the protocol will at least use the wind and current settings that are passed. Also the local variances are not optional. This rule is to assure that every boat will behave similar when on the water. Waves can be a little harder to implement, so they are optional for now.
Boatbuilders using this protocol will not offer any other options to the avatar that uses the boat, like user defined wind, switching off current, using SL wind, etc. The whole idea behind the protocol is to make all boats behave the same way to the conditions on the water and therefor no exceptions are allowed. The boatbuilder always has the choice not to use the protocol at all.
The WWC setter broadcasts a notification of its presence on a computed channel by using llRegionSay 3 seconds after the ping. The computation of this channel is not published here for security reasons. The message send is build up as follows:
message type (value="WwcSetter") unique id (numeric value that increases every time the cruise wwc settings have changed)
The boats in this region that have not yet received any winds (or that wish to keep listening for other WWC setters) will pick up the notification and send an email to the WWC setter (the key of the setter has been retrieved from the incoming chat message). The email subject will contain the message type, which has the value "CrWwcReq". The body of the email is empty.
Example: llEmail("a311ce4d-e755-f148-7999-56f289ca3f3b@lsl.secondlife.com", "CrWwcReq", "");
The WWC setter will check for email every 3 seconds and picks up the request from the boat. The WWC setter retrieves the boat's UUID key and sends an email back that stores all the wwc information for cruising. The subject of the email will contain the value "CrWwc"
The message body contains several records with WWC information, that are each comma separated value lists. Individual records are separated by "\n". The message body contains the following records:
wind message:
message type, (value = "CrWnd") wind direction (direction where the wind is coming from in degrees (range 0-359)), wind speed (in m/s (range: 1.0 - 12.0)), wind gusts (max. extra strength of gusts/lulls in m/s (range: 0.0 - wind speed)), wind shifts (max. angle in degrees (range 0 - 180)), wind change rate (rate at which the gusts and shifts come 1.0 = default (range 0.1 - 5.0)), wind external system (name of the external system to use instead) speed multiplier (1.0 is RL realistic speed, at time of writing 1.9 is SL realistic speed (range 1.0 - 2.0))
If the parameter with the name of the external system is used, all other parameters are to be ignored by the boat.
waves message:
message type, (value = "CrWav") wave height (max height in meters (range 0.0 - 5.0)), wave length (in meters (range 5.0 - 50.0)) wave speed (in m/s (range 3.0 - 15.0)) wave height variance (0.0 = all waves the same, 1.0 = waves vary from 0.0 meters to 2x max wave height, 2.0 = waves can get up to 3x wave height (range 0.0 - 2.0)), wave length variance (0.0 = all waves the same, 0.5 = wave length varies from 0.0 meters to 1.5x max wave length (range 0.0 - 0.75)), wave origin X (origin in global cooridinates where the wavers originate from, this is to let waves hit boats in sync), wave origin Y (origin in global coordinates where the wavers originate from, this is to let waves hit boats in sync), water depth (default water depth for current and waves) wave external system (name of the external system to use instead)
If the parameter with the name of the external system is used, all other parameters are to be ignored by the boat.
current message:
message type, (value = "CrCrt") current direction (direction where current is going to in degrees (note: works opposit to wind dir) (range 0 - 359)), current speed (strength of the current in m/s (range 0.0 - 3.0)), water depth (default water depth for current and waves) current external system (name of the external system to use instead)
If the parameter with the name of the external system is used, all other parameters are to be ignored by the boat.
Also contained in the email body are the local variances to the WWC settings (if present in the WWC setter). For each local variance setting there is one separate line.
message type, (value = "CrWwcLoc") global x coordinate, global y coordinate, 100% effect radius in meters (range 0 - 200) 0% effect radius in meters (range: 100% effect radius - 255) wind speed multiplier (range 0.0 - 3.0), extra wind angle (range -180 - 180), wave height multiplier (range 0.0 - 3.0), current speed multiplier (range 0.0 - 3.0), extra current angle (range -180 - 180)
The decay works as follows: the effect is full in a circle with a radius of "100% effect radius" and gradually decays to 0% at a distance of "0% effect radius".
Example:
100% effect radius = 50
0% effect radius = 100
At 40 meters from the specified global coordinates the effect will be 100%, at 75 meters from the coordinates the effect will be 50%, at 90 meters from the coordinates, the effect is 20%.
The boat checks for emails coming in from only the WWC setter because it remembered its key and only messages that contain the right subject.
Example: llGetNextEmail("a311ce4d-e755-f148-7999-56f289ca3f3b@lsl.secondlife.com", "CrWwc");
Every boat builder is free to implement handlers for only a subset of these messages and to ignore the others.
The boat now prompts the helmsman if he wants to accept the wwc settings just received. It would be good practise to display a summary of the settings, to prevent accepting very strong wind or any other unwelcome settings. It is always possible for people to use a fake WWC setter, a copy of a real WWC setter or to simply set the real WWC setter to values that are of the scale, like for instance a wind of 50 m/s. It is not possible to prevent this, but by letting the boat prompt the sailor with the settings that are received, he or she can decide to ignore the received values.
The boat can stop listening for other WWC setters now and stop checking for incoming emails. But this is up to the boatbuilder.
Security: The boats are unlikely to receive emails from any other than the WWC setter, because no other object will know it's key. (at least from this protocol, it is possible to retrieve the key of a boat by listening to other messages send out). But the boat only checks for email send out by the WWC setter, ignoring anything else.
The WWC setter checks only for emails with the correct subject, ignoring anything else. A possible weakness here is to bombard it with emails with the correct format, making the WWC setter stall because it constantly tries to send out emails to all (fake) boats) and after each email the script is paused for 20 seconds by SL. This is difficult, because people need to know the key of the WWC setter. It is possible to retrieve the key by listening to the ping or to informational chat messages on channel 0 that are send out by the WWC setter during configuration of the parameters. A possible remedy might be to check for all emails but after receiving multiple emails from the same sender in a few seconds it could add the sender to a temporary blacklist and send out a warning on channel 0 for all to hear what is going on.
- Race wind/waves/current
This part of the protocol is optional. Implementation however is very easy when using the standard WWC Interpreter and WWC Receiver scripts.
Any boat that uses this part of the protocol will at least use the wind and current settings that are passed. Also the local variances are not optional. This rule is to assure that every boat will behave similar when on the water. Waves can be a little harder to implement, so they are optional for now.
The WWC setter broadcasts a race notification 3 seconds after the ping on a computed channel by using llRegionSay. The computation of this channel is not published here for security reasons. The message send is build up as follows:
message type, (value = "Rc") race id (randomly generated number), race name (f.i. SAILON), class name (f.i.: Flying Fizz, Tako, Tradewind), sailing mode (0,1,2,3 meaning: no requirement, novice, competition, expert), crew size (0 if no requirements, 1, 2, 3, etc), name of race director, unique id (numeric value that increases every time the wwc settings change)
Note that these parameters are only for prompting the sailor if he/she wishes to compete in the race, The "official" parameters are send through email.
The boats pick up this chat message and ask the helmsman if he/she would want to subscribe to this race. If the helmsman confirms, a request is send from the boat to the WWC setter using email. The email subject will contain the message type, which has the value "RcWwcReq". The body of the email contains:
message type (value="RcWwcReq"), race id
Example: llEmail("a311ce4d-e755-f148-7999-56f289ca3f3b@lsl.secondlife.com", "RcWwcReq", "RcWwcReq,1234");
The WWC setter will pick up the request, retrieve the UUID key of the boat and send an email back to the boat with all requested information. The boat checks for any emails coming in from only the WWC setter because it remembered its key and only if they contain the right subject.
The subject of the email send by the WWC setter to the boat will be "RcWwc". The message body contains several records with WWC information, that are each comma separated value lists. Individual records are separated by "\n". The message body contains the following records:
message type, (value = "Rc"), race id, race name, class name (f.i.: Flying Fizz, Tako, Tradewind), boat version (version number of the boat that is required or a seed to check the version numbers of the internal scripts of the boat (to ensure all boats are of the same version, have not been tampered with and are equally fast)), nr of avatars (nr of avatars needed to sail the boat during the race including the helmsman), skills level (0-9, depends on boat type, on a fizz: 0-fun mode, 1-novice mode, 2-competition mode, 3-expert mode), extra value 1 (value depends on the type of boat used), extra value 2 (value depends on the type of boat used)
message type, (value = "RcWnd"), race id, wind direction (direction where the wind is coming from in degrees (range 0-359)), wind speed (in m/s (range: 1.0 - 15.0)), wind gusts (max. extra strength of gusts/lulls in m/s (range: 0.0 - wind speed)), wind shifts (max. angle in degrees (range 0 - 180)), wind change rate (rate at which the gusts and shifts come 1.0 = default (range 0.1 - 5.0)), wind external system (name of the external system to use instead), speed multiplier (1.0 is RL realistic speed, at time of writing 1.9 is SL realistic speed (range 1.0 - 2.0))
If the parameter with the name of the external system is used, all other parameters are to be ignored.
message type, (value = "RcWav") race id, wave height (max height in meters (range 0.0 - 5.0)), wave length (in meters (range 5.0 - 50.0)) wave speed (in m/s (range 3.0 - 15.0)) wave height variance (0.0 = all waves the same, 1.0 = waves vary from 0.0 meters to 2x max wave height, 2.0 = waves can get up to 3x wave height (range 0.0 - 2.0)), wave length variance (0.0 = all waves the same, 0.5 = wave length varies from 0.0 meters to 1.5x max wave length (range 0.0 - 0.75)), wave origin X (origin in global cooridinates where the wavers originate from, this is to let waves hit boats in sync), wave origin Y (origin in global cooridinates where the wavers originate from, this is to let waves hit boats in sync), water depth (default water depth for current and waves) wave external system (name of the external system to use instead)
If the parameter with the name of the external system is used, all other parameters are to be ignored.
message type, (value = "RcCrt") race id, current direction (direction where current is going to in degrees (note: works opposit to wind dir) (range 0 - 359)), current speed (strength of the current in m/s (range 0.0 - 3.0)), water depth (default water depth for current and waves) current external system (name of the external system to use instead)
If the parameter with the name of the external system is used, all other parameters are to be ignored.
Also contained in the email body are the local variances to the WWC settings (if present in the WWC setter). For each local variance setting there is one separate line.
message type, (value = "RcWwcLoc") race id, (the integer number assigned to the race) global x coordinate, global y coordinate, 100% effect radius in meters (range 0 - 200) 0% effect radius in meters (range: 100% effect radius - 255) wind speed multiplier (range 0.0 - 3.0), extra wind angle (range -180 - 180), wave height multiplier (range 0.0 - 3.0), current speed multiplier (range 0.0 - 3.0), extra current angle (range -180 - 180)
The decay works as follows: the effect is full in a circle with a radius of "100% effect radius" and gradually decays to 0% at a distance of "0% effect radius".
Example:
100% effect radius = 50
0% effect radius = 100
At 40 meters from the specified global coordinates the effect will be 100%, at 75 meters from the coordinates the effect will be 50%, at 90 meters from the coordinates, the effect is 20%.
The boat checks for emails coming in from only the WWC setter because it remembered its key and only messages that contain the right subject.
Example: llGetNextEmail("a311ce4d-e755-f148-7999-56f289ca3f3b@lsl.secondlife.com", "RcWwc");
Every boat builder is free to implement handlers for only a subset of these messages and to ignore the others.
If the boat has succesfully received the settings, it sends an email back with the value "RcSub" as subject and a message body in this format:
message type, (value = "RcSub") race id, name of skipper, name of crew member 1, (if present) name of crew member 2, (if present) name of crew member 3, etc.
The UUID key of the boat itself is not necessary, because this is transferred automatically by SL.
It would be good practice to show the name of the race in the boat's display some form, so the race director and other competitors can see if a boat has entered or not. An other good practise would be to show that initials or first name of the sailor in the sails or on the id box.
The boat will continue to check for email, because a race director can always decide to change the conditions for a race. The race director might even do so during a race while the boats are sailing to simulate a sudden weather change. The WWC setter will send out an email to every boat that has subscribed to the race. The message send is the same as the "RcWwc" email, but it does not necessarily contains all record times in its message body. The boats should keep any previous settings and only replace the parts that are received.
Security: Nothing is more fun for some people than to disturb a race. This protocol has some prevention for this build in. The boats are unlikely to receive emails from any other than the WWC setter, because no other object will know it's key. (at least from this protocol, it is possible to retrieve the key of a boat by listening to other messages send out). But the boat only checks for email send out by the WWC setter, ignoring anything else.
The WWC setter checks only for emails with the correct subject, ignoring anything else. A possible weakness here is to bombard it with emails with the correct format, making the WWC setter stall because it constantly tries to send out emails to all (fake) boats) and after each email the script is paused for 20 seconds by SL. This is difficult, because people need to know the key of the WWC setter. It is possible to retrieve the key by listening to the ping or to informational chat messages on channel 0 that are send out by the WWC setter during configuration of the parameters. A possible remedy might be to check for all emails but after receiving multiple emails from the same sender in a few seconds it could add the sender to a temporary blacklist and send out a warning on channel 0 for all to hear what is going on.
It is always possible for people to use a fake WWC setter, a copy of a real WWC setter or to simply set the real WWC setter to values that are of the scale, like for instance a wind of 50 m/s. It is not possible to prevent this, but the person would need to know how to compute the secret channel.
Communication between WWC Setter and startline
Ideally a startline should make a 90 degree angle with the wind. This is not always done this way, but if the startline would receive the wind settings from the WWC setter, it would be able to rotate itself in the correct way. To do this, the startline acts like a boat to receive the cruise wind settings from the WWC setter. If the race director has started a race, the race wind settings are used instead. If the wind direction is changed for some reason during a race (in between individual heats) the startline will automatically be notified by the WWC Setter. But if there is no race and the cruise wind is changed instead, the line does not know this. Therefr the line should have a command to reset itself and ask for new windparameters.
The automatic rotating with the wind should be an optional feature.
Since a startline isnt really a boat, it's request for wind iws a little bit different, so the WWC setter will know it is dealing with the line instead of a boat.
message type (value="CrWwcReqLine")
for cruising, and:
message type (value="RcWwcReqLine"), race id
for races.
Example: llEmail("a311ce4d-e755-f148-7999-56f289ca3f3b@lsl.secondlife.com", "RcWwcReqLine", "RcWwcReq,1234");
See "Communication between boat and wind/wave/current setter" for the rest of this protocol. Startlines will of course not have to subscribe to a race, so the "RcSub" message is not used.
The WWC setter will pass any subscription to the current race on to the startline. It does so by sending an email to the startline or finishline (the WWC Setter will remember the UUID key of any line that has requested the wind settings)
message type, (value = "RcSub") race id, name of skipper, name of crew member 1, (if present) name of crew member 2, (if present) name of crew member 3, etc.
The line will need to be able to store subscription lists for multiple race id's. It is possible to use more than one WWC setter when there is a race for several classes that start shortly after eachother. Each class will have its own list of competitors and its own results. The wind should be the same for all classes of course, but this is the responsibility of the race director.
Communication between racedirector/sailor and startline
To be defined.
Remark CC: Obviously no communication between the start line and the race director is needed anymore. A race is completely controlled by the wind setter.
Communication between boat and startline
The startline will transmit the following upon starting the countdown:
llRegionSay(-8001,"start,"+(string)(llGetUnixTime()+secondsToGo));
All boats and other equipment can pick the message up and know when the actual start will be. This can be used to trigger personal countdown timers. The message is only issued once when the start countdown sequence commences, to notify surrounding boats and objects of the time at which the countdown sequence will finish.
Communication between startline and finishline
- Race lines can be networked to create a course with a separate start and finish line.
- Currently two methods of approach are used:
- Dyn Dns method - using an external protocol to get a key
- HUD method - using a inworld hud to get a key
- Dyn Dns method
- Any line can act as either start/finish, start line with remote finish, or finish line with remote start.
- Communication between separate lines occurs via http / dyn-dns. Each line provides a handle that can be used to look up a corresponding caps_url.
- A line establishes communication with another line by looking up it's handle, then contacting it with the corresponding caps_url. If the contacted line is available for connection, it responds with an ACK message; if it is not, it responds with a BUSY message.
- A race line's handle should be easily discoverable.
- Race-related communications between start and finish lines are similar to internal communications.
Discovery
- Connection attempts originate from the designated start line. Upon request, the start line looks up the caps_url that corresponds to the finish line's network handle.
- When a valid caps_url has been returned, the start line makes a connection request to the finish line using the following syntax:
942, connection request messagetype (start line requests connection to finish line) queryID the UUID key of the avatar operating the start line
- When the designated finish line receives the connection request, it tests itself for availability. If the line is available for use as a finish line in this context, it replies with the following message:
200, status code 200 ACK, connection request granted line name, line name (= object name) line location line location (region name, x,y,z coordinate)
- If the finish line is not available for use at this time, it replies with
200, status code 200 BUSY connection request denied
- The start line should handle both cases appropriately
Usability Considerations
- Race lines with networked features should provide safeguards on both ends that ensure they cannot be triggered accidentally. Race Officers should not be able to use two lines in separate locations without ensuring both are available first.
- The start/finish line must be able to maintain its caps_url handle to ensure discoverability.
- HUD method
- Any line can act as either start or finish.
- to be specified -
Communication between boats
This part of the protocol is optional. Implementation however is very easy when using the standard WWC Interpreter and WWC Receiver scripts.
Two boats that are near eachother will have an effect on eachother. For instance:
They can cover the other boat by blocking the wind.
If they sail closely behind each other, the wind is disturbed and full of turbulence.
One of them will have Right of Way (ROW)
To notify other boats of a boats position each boat should transmit its position and heading at regular intervals. This is done on channel -7001 for cruising and -8001 for racing by using llSay or llShout/llRegionSay (for bigger boats). There are different channels for cruising and racing. This way cruisers will not interfere with races that are being held. Also, race wind and cruise wind are already different, which would make it strange to have wo boats shadowing each other with the wind coming from opposit directions.
The message format is:
message type, (value = "BtPos") x coordinate (global x coordinate), y coordinate (global y coordinate), sail area (sail area in M2), tack the boat is sailing on (P=port tack so the sail is on starboard, S=starboard tack with the sail on port), boat size from root prim to bow (in meters used to determine side by side situations for ROW computation), boat size from root prim to stern (in meters used to determine side by side situations for ROW computation), speed in x direction (in m/s (including any tidal current)), speed in y direction (in m/s (including any tidal current))
The speed is used to interpolate the boats position in between broadcasts. The tack, heading and boatsize can be used to establish simple ROW indications. (leeward boat and port/starboard rules)
Boats that have their sails flapping in the wind do not create a shadow and should therefor not broadcast anything until the sheet is pulled.
Example:
if(relativeWindDir!=0.0 && ((llFabs(relativeWindDir)-sheetAngle)/llFabs(relativeWindDir))>0.2) {
vector pos = llGetPos()+llGetRegionCorner();
string tack = "S";
integer sailArea = 25;
if(gennakerRaised) sailArea+=20;
if(relativeWindDir<0) tack = "P";
llSay(-7001,(string)((integer)pos.x)+","+
(string)((integer)pos.y)+","+
(string)sailArea+","+
tack+
",1.8,2.5,"+ // these are always fixed values
llGetSubstring((string)(llGetVel().x),0,2)+","+ // llGetSubstring is used to shorten the message
llGetSubstring((string)(llGetVel().y),0,2)
);
}
If all boats would broadcast this every second or so, sailing would become very laggy. And this lag would increase exponention with the number of boats in the neighbourhood. Builders are therefor advised to reduce this interval to every 3 seconds.
Also, do not use llShout or llRegionSay for this unless you have a big boat that will rarely be sailed in races with 10+ boats.
If the interval is bigger than the interval of the internal clock of the boat, received windshadow broadcasts will need to be stored per transmitting boat to prevent the next cycle from pushing the boat forward with 0 shadow again.
Communication between boat and buoys
Each mark should broadcast its position to all boats in the neighbourhood using llShout on channel -8001 every 3 seconds. This way, boats that are competing in a race can use this information together with their own position and the positions of the other boats to implement ROW indication within the 2 shiplengths zone.
The message format is:
message type, (value = "Buoy") x coordinate (global x coordinate), y coordinate (global y coordinate), buoy name
Mooring protocol
This protocol describes how a boat could "dock" to a mooring buoy or similar device. Still to be defined.