Itan-Vistha's "Rock Goliath Lasso" Game: A Psuedo-Guide to an Advanced Circuit by Marvin

“Back on my homeworld, we had a game we played. Rock, Goliath, Lasso! A simple game that we used to settle arguments or pass the time. Two players face off, and on the count of three, make a symbol for a rock, a goliath, or a lasso. Goliath destroys rocks, lasso tames goliaths, and rock smashes lassos!”

As part of a few deadpop shenanigans, I set a challenge for myself. Recreate Rock, Paper, Scissors flavorfully in universe, and then implement it in circuits with battle requests, win detection, and multi-user support. Thus, Rock Goliath Lasso (RGL) was formed.

The goal was “simple”:

A user with a BCI would have a button to prepare an attack against another Rock Goliath Lasso user. They would prepare the attack, and use a target interceptor to declare that they wanted to battle. The other person would get a notification that someone wanted to battle, and would have a brief period of time to send an attack back. The two attacks would be compared, and the winner determined and announced.

Due to all that logic, I ran into the upper limit of the number of components that can be stuck into a BCI, and had to expand it to a game server and the BCI. The server handles the win detection and announcement, while the BCI handles the battle request and data transfer.

I’m going to show the circuit diagrams a few times, with increasing amounts of highlighting and description, so that those following along can attempt to decipher the circuit. This can be the best way of learning, so I want to leave that open for people.

RGL BCI Module

RGL Game Server

The Basic Flow

  1. The player is presented 3 buttons on their BCI: Rock! Goliath! Lasso! Pressing one of these buttons prepares an attack against someone else.
  2. Once the button is pressed, a target interceptor grabs the target of the attack. Technically, anything can be targeted, but only a mob with a RGL circuit will be able to respond and trigger a battle.
  3. The attack request is sent out on NTnet with one encryption key signaling a battle request. The first index in the data packet is the first player, the second is their attack, the third is the targeted player.
  4. The attacked player gets a notification that someone wants to fight and to respond in 10 seconds.
  5. If the attacked player pushes one of their attack buttons and targets anything in 10 seconds, the whole data packet with the second attack in index 4 is forwarded to the RGL server.
  6. The RGL server decodes the whole packet and determines a winner.
  7. If the attacked player doesn’t push one of their attack buttons, the system resets to the initial state where that player can become the attacking player.

Breaking It Down: BCI

The first step behind RGL is the BCI.

This image breaks the BCI up into logical boxes (but doesn’t label the steps). If you are looking to try to decode this circuit by yourself, this would be a good image to look at.

RGL BCI with Blocks Boxed

This image labels all of them.

RGL BCI with Blocks Labelled

And finally, a description of how the entire BCI works. Stop reading here if you are trying to figure it out yourself. The server will be described in a later section.

The whole chain of events starts in the upper left hand corner in the targeting logic. The BCI action blocks provide a clickable button in the HUD, which prepares your attack. Pushing the button causes the variable setter to store a number for which attack was selected into a variable (fittingly called “attack”). Afterwards, those signals trigger a target interceptor, which allows you to click on a target, and that will be output as the “targeted object”.

From there, the circuit gets a little bit weird. This is where the data management block comes in. Depending on if you are initiating the fight, we need to organize where each of the entities involved in the fight is stored into the list to send around.

The final list is a 4 index list, with the following format:

  1. (Entity) Entity initiating fight.
  2. (Number) Initiator’s attack.
  3. (Entity) Entity being fought (target).
  4. (Number) Their attack.

When initiating a fight, you have to store your entity information in the first slot, and the attack in the second.
If you are being fought, you have to store your entity information in the third slot, and your attack in the fourth. The first two indicies are directly copied from the received attack initiation.

Once we store the data where it needs to go, we need to transmit it around. If we are the initiator, we send it to the “player” encryption key, which causes all BCI’s to see if they are under attack. If we are responding to a fight, we use the “rgl” encryption key to send it to the server to adjudicate the result.

But, how do we tell if we are under attack or initiating?

Well, we look for anything coming in on the “player” encryption key as mentioned above. The radio input logic takes in the NTNet packets from that key, and break it up into the correct datatypes (index + typecast). From there, we filter it, by checking if the entity in index 3 is the same as who we are (the “mob” input that comes from the “User” BCI core). If we match, we pass a signal to the notification chain, telling the user that someone wants to fight them.

The magic comes in the “reset logic” block. Once the notification goes off, it triggers the iterator block to take a step, from 1 to 2. A delay block waits 10 seconds, and then triggers the reset of the iterator, resetting the iterator back to 1.

So, when you are targeted, you have 10 seconds to respond, since you are in the “2” state. The multiplexers at the top will use the second input, which sends your information to the server instead of the other players.

Breaking It Down: The Adjudication Server

Once the final packet is created and sent on the “rgl” encryption key, we need to determine who won. I tried to fit this in the BCI, but couldn’t due to the number of components. Thus, I created a server, which can support the large number of components. Plus, it can be put next to an intercom, so that people can hear what is happening. The biggest constraint is that it needs to be in view of both players, because Get Name requires line of sight.

RGL Server with Blocks Boxed

This image labels all of them.

RGL Server with Blocks Labelled

Before an attack is resolved, the server announces that a fight is coming. This happens by the server listening for any activity on the “player” encryption key. It decodes the two entities that are going to fight (index 1 and index 3), and gets their names, and then speaks a concatenated string of “[Fighter name] wants to fight [target name]!”

Once the target responds, it goes to the Incoming Battle Radio Logic block. The “rgl” encryption key has all the details the server needs to fight. That block looks complicated, but all it does is break the array down into its component pieces (index), then converts them into the correct datatype as the index doesn’t do that step (typecast), and then gets the names of the entities, and finally stores all of the information into variables using variable setter blocks. These are very useful, because otherwise those 4 values go everywhere.

In the server images, can you spot the error that I accidentally made in this screenshot? The variable setters are set to hardcoded first and second, as I was debugging my circuit by attacking myself, but that would result in: “Itan-Vistha fights Itan-Vistha, rock beats lasso, Itan-Vistha wins!” which is not very conducive to checking the logic. Thus, I just cut the wire between the get name and the variable setter, and hardcoded it for debugging, and forgot to reset it.

Once that’s all sorted, the signal heads to a synchronization delay. You’ll notice that all the battle radio logic is in parallel, so the signal chains finish at slightly different times. To ensure total accuracy, I put in a “no-op”, or a do nothing except delay for one tick so that everything can finish. The block used is not important, I just use NOT because it’s close to “nop” which is micro-controller assembly language for a no-op.

Numbers are great for passing around and manipulating, but they are not good for lizards humans to read, so the Attack Number To Name Lookup block converts the attack number to a string by indexing a list with the attack names in it. Nice and simple, but effective.

Then, we determine who actually won.

The first step is to make sure the players didn’t tie. That’s accomplished by just comparing the two numbers, and if they are equal, we tied. We give it a unique tie announcement: “[ X ] and [ Y] tie, with [attack]!” and speak that.

If the values are not equal, we now need to actually see who won. Bigger number wins, except for one slight edge case. Rock is 1, and Lasso is 3. Rock should beat lasso, so we need to detect this.

We compare both attacks to see if attack 1 is 1 and attack 2 is 3, or attack 1 is 3, and attack 2 is 1. If either case is true, we pass that to the winner announcement logic.

If both cases are false, we pass the data to the remaining win logic, which compares to see which number is greater.

The winner announcement compiles a string of “[ X ] beats [ Y ]!” You might notice something about this block. The top half and bottom half are actually duplicated, and I fixed that in the final revision. Saves you having to wire up 4 more blocks.

We combine that string with the Who Played What block, which outputs a concatenated string of “[ X ] plays [attack], [ Y ] plays [attack].” The two strings are combined together into the final string: “[ X ] plays [attack], [ Y ] plays [attack]. [ X ] beats [ Y ]!” and spoken.

Nefarious Uses

There’s no anti-cheat in this game… so an enterprising player could modify their BCI to always have their opponent make the same attack. It’s your word against theirs of course, so be prepared to defend your honor!

Theoretically, you could use remote signalers to trigger bombs if a certain player loses. Challenge Cappy to a battle for your life!

Conclusion

This whole setup worked well, and I did get a few comments in round and post round that people enjoyed playing it. I figured I’d release this out to the wild so people could see it and maybe recreate it.

I didn’t put this in guides, because it’s almost more of a story thread due to the circuit complexity. If admins determine it worthy of Guide status, feel free to move it there. Thanks, Crossed!

Edit: Images are Potatoes. I have high quality images, but the forums are resizing them.

2 Likes

Vaguely related circuit fuckery wise, Sydney Shaw has a very cool program for hide and go seek as well.

Might be worth reaching out to them

1 Like

You could also use the text declaration of “ Beats [Y]” as the trigger phrase for nanites.
Send your opponent (and everyone else in earshot) to the shadowrealm (False death)

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.