A brief history

Lacewing started out as OINC (OINC Internet/Network Controller), a replacement for MOO.


As OINC was being developed however, Jamie experienced a hard drive crash and lost the source to OINC, forcing him to revert to an older version. At this point he renamed it Lacewing and created the liblacewing library that the client extension would use. There are now three parts to the Lacewing extension set; the Relay Client, the Relay Server, and the Webserver.



Later, Lacewing Blue Client (also known as Bluewing Client) was a rewrite of Lacewing Relay Client, designed to fix several problems the Bluewing developer Phi was getting with the regular Relay Client.

Phi contacted Jamie for the source or for a fix over several avenues, but received no reply over several months, and he instead decided to create an object of duplicate functionality that could be exchanged for the buggy Lacewing Relay Client in any MFAs that used it.


As they use the same Lacewing Relay message format, Lacewing Blue was compatible with Relay servers. So a Relay client could use Blue servers, and a Blue client use Relay servers, and vice versa.


Later, Phi was also funded to work on Lacewing Blue Server. Although payment was called off when the sponsor went into financial difficulty, the coding was done and Phi opted to release it publicly, and later to run free public servers compatible with both Blue and Relay.

The servers were started in October 2014, and are still running free (and no ads) in 2022.

The only money Phi receives from Bluewing is from his Patreon, and a couple of people over the years wanting additional features added.


Blue Server was translated into French by Clickteam users Kakise and Jiyone, and translated into Portuguese by PharaohAnubis.

The Lacewing Relay Protocol

The Relay Client and Relay Server use the Lacewing Relay protocol (spec) to communicate – it is an IRC-like communication protocol that allows for clients to connect to a server, have names, join channels, send messages to the channel to have them relayed to other peers in the channel, send messages to the server, and send messages to other peers in the channel.

It also has support for each channel to have a channel master, which may optionally close the channel when they leave. Clients connected to a server may have the same name as other clients, so long as they are not in the same channel.

The main difference between IRC and the LRP is that in IRC peer messages are sent directly, and in LRP peer messages are sent via a shared channel.

Another difference is that there are three types of messages to be sent in the LRP; Text, Number, and Binary messages. Messages are associated with a specific subchannel – channels have names, but subchannels are just numbers 0 through 255.


The connection requires both TCP and UDP initially, although it may work fine with just TCP.

The distinction between these two is covered under the Sending versus Blasting topic.

Connection handshake

Although this isn't necessary for most users to know, Lacewing involves a complex connection handshake that requires a working UDP connection.


  1. Client sends a raw TCP connect request
  2. Server approves raw TCP connect request
  3. Client sends a Lacewing connect message over the TCP connection
  4. Server sends a Lacewing Connect OK response message back over TCP
  5. Client receives the Connect OK, but does not trigger On Connect yet.
    Instead, it starts sending a UDPHello message, every 500 milliseconds, on a timer. UDP messages can be lost in transit as part of the design, so the repeating nature is necessary.
  6. Server, upon receiving a UDPHello, sends back a UDPWelcome.
    It will do this as many times as it receives a UDPHello, as the UDPWelcome message could be lost in transit too.
  7. Client receives its first UDPWelcome, and finally triggers On Connect.


Several things are of note:

  • At stage 5-6, before On Connect is triggered, the Client can behave in any way a regular client would, outside of Blast actions. So, it can set its name, join a channel, etc, the server will respond like normal.
    This is because the server cannot know if the client received a UDPWelcome, because UDP doesn't have acknowledgment like TCP does.
  • At step 3, any client that sends anything other than a Lacewing connect request or a ping message will be considered untrusted and disconnected immediately, with the rest of their incoming data discarded.
    An error will be generated:
    Dropping connecting client from IP X.X.X.X for sending messages before connection was approved
    Since there was no Lacewing connect request event, there is also no Disconnect event either.

Ping timer

There is a ping timer thread, set to run every 5 seconds, in both Relay and Blue Server.


The ping timer has three activities:

  1. Send TCP pings to any client who hasn't sent a TCP message since the last ping timer tick.
    The next time the ping timer runs, any client who has not responded to the last ping timer's run messages will be kicked. Regretfully, this is necessary as under some network conditions, connections do not close gracefully.
  2. Send UDP pings to any client who hasn't received or sent a UDP message since the last ping timer tick.
    This is to prevent the UDP faux-connection being closed by devices along the route, causing a UDP connection bug, covered more under Known Relay bugs.
  3. If the activity timer is enabled, 10 minutes of non-activity causes the client to be kicked.
    You can read more about activity under the Blue Server's property Enable inactivity timer.
    Some old versions of Blue/Relay did not always close their connections properly, resulting in the client app staying open invisibly in background, and if the server did not close the connection, the app would stay open indefinitely. If you won't be encountering these, then you can disable the activity timer.


The ping timer thread is run regardless of whether you have the server set to multi-threaded or not.

While it also runs under Relay Server, it only does the TCP ping activity, not the other two.

DDOS protection

Blue Server has some level of DDOS protection, covered more under Additional features.

Relay Server does not.

Bad practice error

If you get an error like:

Bluewing Client event occurred, but you have no Bluewing Client > On Error event to handle it. That is BAD PRACTICE.


Then create the On Error event or Cranky will have words for you.

Sure, some errors are expected if you rely on Blue's error checking, like letting the user set their name to blank, but some errors and events are unexpected and indicate an actual problem – like another client using that name already, the server is closing down, the server denied the name, etc.

It is bad practice to ignore errors or not to display them to the user. The "bad practice" popup boxes are not an intended way to handle these events – they're a warning that you already haven't programmed something; you messed up, and here's a bit of duct tape to fix the gaping hole in your program logic.

The error isn't the problem. The fact you don't report it is the problem.


Before this popup message was introduced, people of dubious intelligence were under the impression Blue Client was broken because they coded it wrong, it reported an error, but they had no On Error event to see the error. So all they knew is "I did everything right, but it doesn't work".

Confused by the lack of errors, caused by the lack of error checking in their code, they decided "couldn't be me, I have never coded a mistake in my life, must be the multiplayer", ignored the common sense of asking why a problem's happening instead of immediately trying a different method… and switched back to Relay Client, or just abandoned multiplayer entirely.

Truly, paragons of logical deduction.


Similarly, you can get these popup boxes if you miss out on Connection > On disconnect and other events. This is because while you can test for connection lost with Client > Connection > Is connected [negated], this is inefficient.

Code should run as few times as possible, for minimum impact on CPU; constant checks when the underlying data can't constantly change is a sure sign you're doing something wrong. This is true in Fusion and all other coding languages.

You can multiply by adding several times, and it will work and give you a "multiplied" answer… but it's not the smart way to multiply.

So, use less code – minimize the use of non-triggered conditions.


If you really insist on shooting your CPU in the leg, then you can create an Connection > On disconnect event that doesn't do anything, like sets a global value to itself. Blue only detects the condition being activated in the event sheet, it doesn't check that you actually do anything meaningful with it.