When selection is changed
This selection mechanic is for the Blue set of Lacewing objects; both Client and Server.
For simplicity, only the Client is used for examples below.
It's not recommended you have more than one Client with the same global ID in a frame, as each triggered Lacewing event is run for each instance of a Client/Server, in order that Fusion created the Lacewing objects.
For example, if you have two Clients, an On Channel Leave will run twice for one Leave.
However, there is an exception: loop events don't run for all Lacewing instances, only for the one that starts the loop. So you can run a peer loop in a sub-app, without peer loop conditions firing on the parent app.
Local objects' selection
When you use a non-global Lacewing, also called a local Lacewing, selection and the connections are always unique to that one object instance, as if there were no other objects.
Try not to use a duplicated local Lacewing, though… you will confuse yourself in events, by not knowing which Lacewing is holding Connection A and which is holding B, forcing you to fill your event sheet with fixed value comparisons. Better to use a different Lacewing entirely.
Global objects' selection
Global objects use the same connection, sharing it with all instances that have the same name, but each instance has a unique selection of channel/peer.
The selection is not shared across sub-apps or extension instances.
Selection is kept across frame switches, though, see below for more details.
So if you select channel "TestChannel" in a parent app, the child app's Bluewing will not have it selected; if for some reason you have multiple Clients with that global ID in one frame, they will not have it selected either.
They will all share the one Client connection, but have different channel/peer selections.
When a Lacewing object is set to global, and the last instance of the Lacewing object is destroyed (e.g. when switching frame), the currently selected peer/channel is saved. When a Lacewing object with the same global ID is created in the new frame, the connection and the selection is restored. So selection is kept across frames.
This depends on it being the last instance, though. So if you create a second Lacewing, it will not keep the selection of the first Lacewing.
If you create a sub-app with a Lacewing, when there is still a global Lacewing with the same global ID in the parent app, the channel/peer selection is not copied over when it's created, although the connection is shared with the parent app's instance.
If you restart a sub-app with its Lacewing, when the parent app still has the global Lacewing, the selection won't be saved, and so the restarted sub-app will not have the selection restored either.
That's because when the child app closed down, the parent instance was open, so it was not the last instance being destroyed.
Automatic event selection
If there was no previous selection, what was in the triggered event is kept. So, on the first channel join for a Lacewing, because no channel was selected, the channel will remain selected after the Channel Join event.
However, when the second Channel Join runs, the first channel is selected again after the event ends. So make sure you select your channels explicitly, if the triggered event hasn't already picked the right one.
The auto-selection is easy to work with. For example, on a peer message sent via a channel, when the peer message events, the channel and peer will be selected before the condition starts. This allows you to do code like this:
And in practice, this is how the above code responds to another client:
(notice no response to "not ping", but response on same subchannel to "ping")
Notice how you don't need to re-select the sending peer to send a message back, as the triggered event selects it temporarily; this is useful for a bounce-back exchange like that.
The channel is also selected as well as the peer, so you reply to a peer message via the channel it came on. This is useful if your game has multiple channels in use at the same time.
This is useful for checking channel names during channel events, and peer names/peer IDs during peer events, as they are auto-selected.
If you want to select Active objects that are players, don't use Compare Two General Values! Refer to the selecting player objects example for why.
Manual selection (outside of Lacewing events)
If Lacewing is not triggering the event, then there is a separate, manual selection is only modified by actions only, and by triggered conditions that make the manual selection invalid; e.g. you cannot keep a channel selected after it's closed.
Make sure you explicitly select the channel and/or peer before doing any actions or reading from expressions, or your old selection will be used. In servers, select the channel or client explicitly.
To confirm you do it before, you can switch to event list editor, or double-click at any part of the event line's boxes in event editor to open the action editor. Selecting after sending a message will use whatever was selected before… which might work, or might not.
Manual re-selection during a triggered event
Due to the auto-selection resetting to what was previously selected after an automatic event, you may not have the manual selection you expected.
- You select Peer A on TestChannel manually, so Peer A is selected.
- Then, Peer B connects to TestChannel.
- Peer B is auto-selected, Peer Connect event is run.
- Peer Connect actions start; you can do stuff with Peer B, like read their name, ID, or message them like in the ping example above.
- In actions, you use Channel > Peer > Select by name to select Peer C instead of B.
- Peer C remains selected until the Peer Connect event finishes (as in, all the Peer Connect event lines finish)
- Peer Connect event finishes, so the pre-Peer Connect selection, Peer A, is re-selected.
In visual form:
This may seem confusing, but it's very useful, as you can run channel/peer loops and do stuff immediately with the pre-loop peer/channel afterwards.
If you're in a scenario like above, and you want to select C then B again, you can simply copy out the peer name to a global string, or peer ID to global value, and re-select yourself.
Selection when closing down
Blue has "read-only" or "closed" mode for its data; for example, when a channel is left by the client, the server will send an On Leave Success message. When the client receives that message, the channel is marked as read-only instantly, then the On Channel Leave event is run. Once the leave event is finished, the channel is deleted.
In Blue, if you run a channel loop during a channel leave event, it will include the read-only channel you are leaving. As you might expect, a read-only channel can have its name, ID, peer list read from; once the On Channel Leave events finish, the channel will no longer be in the lists.
Likewise, when a channel closes, after the On Channel Leave event finishes, the previous channel/peer before the event will be restored as the selected channel.
If the previous channel was the closed one, no channel will be selected afterwards. If the peer you selected was on that closed channel, then no peer will be selected either.
When a peer leaves, the same applies; the previous peer selection is restored after the event finishes, but if it was the leaving peer, then no peer will be selected.
The server and clients work the same way. Relay may behave bizarrely with selection restoring. Blue will always explicitly behave as documented here.
Selection by name
Clients are usually identified by their unique ID number, so having two clients with the same name is no problem, because clients cannot interact outside of channels.
In Blue, re-using similar names is not allowed, though.
Both Relay and Blue use case-insensitive naming, allowing you to select a user "Jamie" by selecting by name "jamie". However, Blue will not allow a name to be reused by another client even if the casing is different.
Blue additionally uses simplified naming on select actions, allowing you to select "Jáck" by name "Jack", making UI design simpler.
If you want to explicitly allow this reusing feature for different users, consider putting a number before the channel or client name, and hiding the number from end users. For example, using Str$(Random(89)+10) will result in text "10" – "99", and the no-number name can be read via Right$(name, Len(name)-2), whether you use self name or peer name.
Blue Unicode name limitations
Since Blue's Unicode build (b95 client, b26 server), special characters will be stripped and simplified for case insensitive comparisons, so if a user "Jamie" is present, another user could not name themselves "Jamíe".
This is to prevent users impersonating each other by subtle differences in characters, causing moderators to take action against the wrong users. In the previous example, one of the 'i' has a dot, the other has an accent.
These name restrictions apply to both client and channel names, including the channels created by the server or named modified by the server.
It should be noted that in default server configuration, you can still change your own casing; e.g. a client named "Jamie" could set their name to "Jamíe" or "jamie" even though other users could not.
More details are covered under Blue Extension Set > Unicode notes.
Avoiding errors from conditions
Normally, this won't be an issue, as you would normally code so the channel is manually selected, as described above.
However, if you keep changing the manual selection between different channels or otherwise thinks this might happen anyway, you can consider creating a precursor event that will select the right channel/peer. As a demonstration:
To be fair, these are rare scenarios. And if you think errors are annoying, be assured having no error and no messages being sent will be even more so.
Peer is stored per-channel
Relay stores peer selection as a subset of channel selection. In other words, for each channel, the peer selection can be different.
Imagine the scenario where you are joined to two channels, Channel A and B, and there is a Peer A on Channel A, and a Peer B on Channel B, but they are not in the other channels.
So, if you:
- Select Peer A in Channel A
- Switch to Channel B
- Select Peer B in Channel B
- Switch back to Channel A
- Your peer selection will be changed back to Peer A (for Relay).
Blue always deselects the peer if they are not found in the newly selected channel, to prevent accidentally sending messages to the wrong client.
So for Blue, if:
- Peer B is on Channel A and B, then at step 5, Channel A and Peer B will be selected.
- Peer B is only on Channel B, then at step 5, Channel A and no peer will be selected.
At the end of loops, in an On Loop Finished event:
- Relay leaves the channel/peer selection as it was on the last On Loop event, effectively giving the last channel two events (On Loop, and On Loop Finished).
- Blue will restore the pre-loop channel/peer selection at the start of On Loop Finished.
(It will not restore it again if you manually edit the selection during a Finished event.)
After the On Loop Finished event, when the code resumes at the loop starting event:
- Relay restores the pre-loop channel/peer selection once the Finished event completes.
- Blue will have already restored it at the start of On Loop Finished, and if you have not manually changed it in On Loop Finished, it will remain selected.