Change background image
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

The Integrated Circuits Guide Absolutely Nobody Asked For

Discussion in 'Tutorials & Information' started by Cheb Pomidorov, Sep 20, 2019.

  1. Cheb Pomidorov

    Cheb Pomidorov Bartender

    Hello kids, I'm Cheb and I'm here to teach you how to make Integrated Circuits. As the title says, nobody asked for it and nobody needs it, but that won't stop me from wasting your time and cluttering the Tutorials subforum with this mess until an admin removes it.
    I'll assume you have no experience with circuits and no knowledge of information technology principles/subjects such as Algorithms and Data Structures, Computer Architecture and Low-level programming. Not that I'm particularly fluent in those myself.
    While writing this guide I realised it's become less of a theoretical guide and more of a training dojo of sorts, so that's nice.

    DISCLAIMER
    There is already a Circuits guide on the /tg/station 13 wiki. Unlike this guide made specifically for Baystation 12, that guide has actual pictures, nice formatting, neat icons and cute little diagrams with arrows made in MS Paint. This guide has none of that, so if you must, here's the link:
    https://tgstation13.org/wiki/Guide_to_circuits
    (The link above is tiny on purpose).
    The only reason you should be reading this guide instead of that one is that /tg/ is bad. No wonder they removed circuits from their code.
    But really though, it's an alright guide, much superior in quality to this one.
    I will be showing some stuff that guide doesn't, so there's still some merit in reading this.
    For actual disclaimery stuff, you can use whatever circuits I show off here, not that I can stop you. Not that anyone would use the stuff I make.

    Chapter one: What's this then, eh?
    What are circuits?
    Unlike the usual items of the game like toolboxes, insulated gloves and water-potassium grenades, whose behaviour is coded into the game by some high-level nerds, circuits are entirely modular, flexible items made out of a multitude of ridiculously inflexible components. They are custom-built items to which you assign a behaviour of your choosing.
    Each circuit is made up of:
    • An assembly, a case which houses all your components. This is the first thing you decide on. Assemblies come in different sizes, and some have different functions. Assembly size determines the amount of components that can be placed inside, and increases the upper complexity limit.
      • Drones are the only ones capable of autonomous movement.
      • Wall-mounted assemblies can be... mounted on walls. Most others can only be fitted on floors.
      • The gun-shaped mechanism is the only one that isn't a drone AND can fire ranged weaponry.
    • The components, the modules that make the assembly do what you want it to do. There are power generation modules, item manipulation modules, pathfinding modules, arithmetic and logic, and others. Each component adds a certain amount of complexity to the assembly, which will prevent you from adding too many high-complexity components.
    • A battery, needed for the assembly to function and whose charge is consumed by its components.
    Research's Miscellanous Laboratory, Petrov's Equipment Storage and Robotics all contain a black metal box called an Integrated Circuit Printer, not to be confused with an Integrated Positronic Chassis. You can construct additional ICPs in the Protolathe. The printer performs two functions: printing and cloning.
    Printing refers to the creation of assemblies and components out of metal (steel). 25 sheets of steel fill up the ICP's metal reserves to capacity. Note that some components will require an Upgrade Disk available from R&D. You should be maxing out R&D anyway, so this is hardly a concern.
    Cloning refers to the creation of complete circuits using some incomprehensible code. The code is generated by using a Circuit Analyser tool on the completed assembly you want to clone. Cloning takes time, unless you obtain a Cloning Upgrade Disk from R&D and use it on the ICP, and metal.
    Get ahold of one, preferably fully upgraded. Fill it with metal, and you're good to go.
    You still need tools to perform your work, but these can be printed from the ICP in the appropriate section, aptly named Tools. The Big Three are:
    • Circuit Wirer: the most used, this allows you to connect the components together and actually setup your circuit. Essential.
    • Circuit Debugger: not just for debugging, this allows you to more easily assign values to your parametres, toggle components manually, and some other stuff. Not essential in most cases, but life would be hell without one.
    • Circuit Analyser: as mentioned, generates some code that you can save to some fancy .txt file on your computer (mine's called Soap's Shitty SS13 Sircuits.txt) and clone them in later rounds as you see fit. Not essential.
    Now navigate to the Arithmetic tab and print something like a Multiplication circuit. Examine it directly and you'll see a panel you'll learn to hate. It has two types of wires: data wires and pulse wires.
    • Data wires are the blue ones on the sides, and they come in two types.
      • Input wires are located at the left side and provide the input for the component. In the case of a Multiplication circuit, the wires represent the Multiplicand and the Multiplier (obviously in interchangeable order). Input wires must almost always contain some form of data for the component to function.
      • Output wires are on the right side and represent the output of the calculation performed, or the "state" of the component. They update every time the component is used. Whenever they update, even if their value remains the same, all data wires connected to them carry their value over to themselves. This is very important.
    • Pulse wires are the red ones and they also come in two types.
      • "Pulse in" wires receive a "pulse out" from some other component. Whenever a component is "pulsed in," it simply activates. That's all there is to it. In the multiplication example, it'd perform the operation and push the multiplication output to its output wire.
      • "Pulse out" wires send a pulse to another component's "pulse in" wire when certain conditions are met. These conditions are outlined on the component itself and are fairly obvious.
    A given component doesn't necessarily need to have any data wires, while some have like, 18. Same for pulse wires, they don't need to be there, but some components have more than two.
    The wires themselves can be connected together by a circuit wirer. The components need to be housed in an assembly to do this. Wires are disconnected by using the wirer in your hand, setting it to Disconnect mode. Note that you can do some tricks like wiring a component's output to its own input (useful) or wiring a component's output to another's output (not so much).
    And here's an explanation of most data types you'll be working with:

    All: this type is usually for input wires. You can provide such wires any type of input.
    Number: self-explanatory. I'm pretty sure the system can't make any floating point calculations, though, so you'll need to provide integers.
    Text: also known as String. Data of this type is enclosed in double quotation marks " ". Be aware that using the symbols [, ], { and } may make the circuit impossible to clone.
    List: a variable amount of data condensed into a single entity. One list may contain hundreds of values. These are, functionally, arrays of variable size. The "Lists" tab of the ICP provides components that work with lists.
    Boolean: a TRUE/FALSE value. You'll usually use the numbers 0 and 1 to set these to FALSE and TRUE respectively, but be aware that "" (empty string) and null (nonexistent value) also set it to FALSE, and anything else sets it to TRUE.
    Ref: this is a reference to an object. It can't be set manually: you either have to scan an object with the Circuit Debugger and copy its reference, or obtain a reference through other components, like sensors. Refs are usually provided by Input components and used by Manipulation components, but there are other categories that use them.

    The debugger is most useful for when certain data values, once set, are supposed to never be overwritten. Use the debugger in your hand to access a menu and enter a value into its internal memory, then use it on a data wire to write data to that wire.
    And speaking of the debugger, there's an oft overlooked trick: you can use it to pulse an input wire on a given component and, provided the assembly has a power cell installed, it'll activate the component.
    I used the word "component" too many times

    Chapter Two: Electronic Boogaloo
    If you read the previous part, you should have at least a basic understanding of how this stuff works. The rest must come from experience, so here are some examples you can try, starting with the most banal and increasing in complexity. This chapter is the core of the guide, and teaches several advanced techniques.
    I tried to come up with some challenges, but my circuit ideas are admittedly lacking.
    This chapter won't teach any basic stuff like Universal Translators, ID access broadcasters, and other common circuits. The point of this chapter is to teach technique rather than provide examples. Problem solving is an inherent part of integrated circuits, so you're encouraged to do these challenges and come up with your own solutions.

    1: Basic flashlight
    Flashlights are possibly the easiest circuits you can make, and with good reason. There's very little room to mess up all the wiring (and in this case, there's literally no room to mess up the wiring). Make a simple white flashlight one can toggle on or off with a button.
    In this case, the "button" and "toggle button" components are interchangeable. Their respective PULSE OUT wires do the exact same thing. The only difference there is between the two is that the toggle button has an extra output wire which isn't useful for this example.
    Not trying to be a big meanie, but if you need the solution for this example, perhaps circuits aren't for you.
    Code:
    {"assembly":{"type":"type-a electronic assembly"},"components":[{"type":"button","name":"Light"},{"type":"light","name":"Output"}],"wires":[[[1,"A",1],[2,"A",1]]]}

    2: Emergency flashlight
    Useful for drawing attention to yourself during a crisis, especially if the power is out. Help the EMT find your dying-in-the-dark self more easily with this circuit!
    Make a circuit that, if a button is toggled on, sends out a pulse every second, toggling a red light on and off repeatedly.
    The Advanced Light component accepts a <COLOUR> data type. It's a very specific type of string: a "#" followed by a 6-digit hexadecimal number. The colour red would be #FF0000.
    Code:
    {"assembly":{"type":"type-a electronic assembly"},"components":[{"type":"toggle button","name":"Light"},{"type":"custom ticker","name":"Tick","inputs":[[2,0,10]]},{"type":"advanced light","name":"Output","inputs":[[1,0,"#FF0000"],[2,0,100]]}],"wires":[[[1,"O",1],[2,"I",1]],[[2,"A",1],[3,"A",1]]]}
    The debugger is used 3 times here.

    2.5: For Nerds, Improved Emergency flashlight
    Unfortunately, toggling off the toggle button of the above circuit doesn't necessarily mean the light will stay off: it may stay on instead. Fix this by adding some logic elements. When the button is toggled, the light, if off, should stay off, whereas if it's on, it should turn off.
    The light being turned off should occur when the button is toggled off AND the light is still on. That AND is a hint.
    The advanced light, unlike the toggle button, doesn't provide an output wire indicating its current state. You'll need to figure that out in some other way, that may be logic, arithmetic or memory operations, which are all valid solutions (as long as it works!)
    Code:
    {"assembly":{"type":"type-a electronic assembly"},"components":[{"type":"toggle button","name":"Light"},{"type":"custom ticker","name":"Tick","inputs":[[2,0,10]]},{"type":"advanced light","name":"Output","inputs":[[1,0,"#FF0000"],[2,0,100]]},{"type":"JK latch","name":"ToggleState","inputs":[[1,0,1],[2,0,1]]},{"type":"not gate","name":"ButtonIsOff","inputs":[[1,0,0]]},{"type":"and gate","name":"ButtonIsOffAndLightIsOn","inputs":[[1,0,1],[2,0,0]]}],"wires":[[[1,"O",1],[2,"I",1]],[[1,"O",1],[5,"I",1]],[[1,"A",1],[5,"A",1]],[[2,"A",1],[3,"A",1]],[[2,"A",1],[4,"A",1]],[[3,"A",1],[6,"A",2]],[[4,"O",1],[6,"I",2]],[[4,"A",1],[6,"A",2]],[[5,"O",1],[6,"I",1]],[[5,"A",2],[6,"A",1]]]}
    This one is tricky as it uses a very seldom used component called a JK Latch. It's not exactly the most proper way to use the Latch, but it gets the job done. If J and K are both TRUE, then the JK Latch toggles its state every time it's pulsed. Q is its state, !Q is the state's negation (they're always logical opposites).
    Other solutions include having arithmetic components switch between 0 and 1, or having memory components, set to 0 and 1, switch data one to another (although swapping requires the use of a temporary variable).

    3: Hydroponics Uprooter
    Hydroponics/Xenobotany can be tedious because plants and trees take many hits to cut. In a similar manner to the circuit directly above, make a handheld tool that combines the functionality of a mini hoe and a hatchet. A toggle button should toggle whether the tool removes weeds or plants. Here's a secret: removing plants with an integrated circuit removes weeds as well.
    You'll need to use something similar to the former example in order to track the status (weed/plant). You'll also need some kind of way to remember the 1 and 2 (1 is the selector for weeds and 2 is the selector for plants). Finding out the best way to do so is the challenge here.
    Code:
    {"assembly":{"type":"type-a electronic assembly"},"components":[{"type":"sensor","name":"GetRef"},{"type":"constant chip","name":"UprootWeeds","special":1},{"type":"constant chip","name":"UprootPlants","special":2},{"type":"plant manipulation module","name":"Uproot","inputs":[[2,0,1]]},{"type":"toggle button","name":"Remove Plants"},{"type":"JK latch","name":"ToggleState","inputs":[[1,0,1],[2,0,1]]}],"wires":[[[1,"O",1],[4,"I",1]],[[1,"A",1],[4,"A",1]],[[2,"O",1],[4,"I",2]],[[2,"A",1],[6,"A",3]],[[3,"O",1],[4,"I",2]],[[3,"A",1],[6,"A",2]],[[5,"A",1],[6,"A",1]]]}
    JK Latch returns, and it's still not used very elegantly, but I'd say it's a bit better. What's new here is the constant chip, which is a memory component that's supposed to be used with a debugger. Don't let the description fool you: overwriting its output data is as simple as connecting it to some other component's output. Don't do that, as it defeats the purpose of a constant chip.
    As circuits become more and more complex, the usage of memory will become more and more relevant and necessary.

    4: Countdown
    While the above circuits have some degree of usefulness, this one is not of that kind, but teaches an important technique. Starting at n=10, make it so that every n tenths of a second, the following occurs:
    1. A text message is stated aloud/a light is toggled/whatever you can imagine, and
    2. n is decremented by 1.
    When n reaches 0, reset it back to 10.
    The two crucial procedures here are the one that decrements n and the one that resets n when n=0. As with every single solvable problem in existence, there are infinite solutions, but it makes sense to strive for a simple and efficient one.
    Code:
    {"assembly":{"type":"type-a electronic assembly"},"components":[{"type":"toggle button","name":"Power"},{"type":"constant chip","name":"TEN","special":10},{"type":"custom ticker","name":"Tick","inputs":[[2,0,10]]},{"type":"light","name":"Output"},{"type":"subtraction circuit","name":"Count","inputs":[[1,0,10],[2,0,1]]},{"type":"less than or equal gate","name":"CountIsZero","inputs":[[1,0,5],[2,0,0]]}],"wires":[[[1,"O",1],[3,"I",1]],[[2,"O",1],[3,"I",2]],[[2,"O",1],[5,"I",1]],[[2,"A",1],[6,"A",2]],[[3,"I",2],[5,"O",1]],[[3,"A",1],[4,"A",1]],[[3,"A",1],[5,"A",1]],[[5,"I",1],[5,"O",1]],[[5,"O",1],[6,"I",1]],[[5,"A",2],[6,"A",1]]]}
    I used a light in this case. It doesn't look the best, but it does what it's supposed to. Central to the whole thing is the subtraction component I labelled "Count." Note how its output wire is connected to its own input wire.

    5: Renald Dalton is a legend
    Arkter, the guy who plays Renald Dalton, hates lists. So let's reference him in this list example. First, clone this circuit:
    Code:
    {"assembly":{"type":"type-a electronic assembly"},"components":[{"type":"at circuit","inputs":[[1,0,["Renald","Dalton","is","a","legend."]]]}]}
    The task here is to make the circuit say the phrase contained in the list, not as a single string, but as 5 different strings. There should be a delay of 1 second before one string being spoken and the next. This time, it should start saying the phrase at the press of a button, and only say it once (No looping). Pressing the button again will start the phrase from the beginning.
    The preinstalled component is essential in this task.
    Code:
    {"assembly":{"type":"type-a electronic assembly"},"components":[{"type":"constant chip","name":"ZERO","special":0},{"type":"button","name":"Speak"},{"type":"addition circuit","name":"Count","inputs":[[2,0,1]]},{"type":"at circuit","name":"GetNext","inputs":[[1,0,["Renald","Dalton","is","a","legend."]],[2,0,0]]},{"type":"text-to-speech circuit","name":"Output"},{"type":"greater than or equal gate","name":"IterationOver","inputs":[[2,0,5]]},{"type":"one-sec delay circuit","name":"Delay"}],"wires":[[[1,"O",1],[3,"I",1]],[[1,"A",1],[2,"A",1]],[[2,"A",1],[3,"A",1]],[[3,"I",1],[3,"O",1]],[[3,"O",1],[4,"I",2]],[[3,"O",1],[6,"I",1]],[[3,"A",1],[7,"A",2]],[[3,"A",2],[4,"A",1]],[[4,"O",1],[5,"I",1]],[[4,"A",2],[5,"A",1]],[[4,"A",2],[6,"A",1]],[[6,"A",3],[7,"A",1]]]}
    Finally, something larger than 6 components. What we've built is called an iterator, as it accesses all elements of a list/all characters of a string. Of particular note is the fact that the "Count" number isn't just used for iteration, but also for access to the list (by index). String manipulation components are found under the Conversion tab.

    6: Lights, for the last time
    I know flashlights have become cliché and quite boring already, but this is a nice challenge. Make it so a circuit contains an advanced light that, every 0.6 seconds, changes its colour to a randomly generated one. Try to use as few components as possible.
    As in examples 2 and 3, you need a string formed by a "#" followed by 6 hexadecimal digits. These digits must be randomly generated, but the only random generator in our repertoire is one for numbers. That doesn't mean it can't be used, if a way is found to quickly convert a [0, 15] integer into a hexadecimal digit.
    The Multiplexer and Demultiplexer are useful.
    Code:
    {"assembly":{"type":"type-a electronic assembly"},"components":[{"type":"constant chip","name":"ZERO","special":0},{"type":"button","name":"Light"},{"type":"addition circuit","name":"Count","inputs":[[1,0,3],[2,0,1]]},{"type":"random number generator circuit","name":"RandomNum","inputs":[[1,0,1],[2,0,16]]},{"type":"sixteen multiplexer","name":"Mux","inputs":[[1,0,2],[2,0,"0"],[3,0,"1"],[4,0,"2"],[5,0,"3"],[6,0,"4"],[7,0,"5"],[8,0,"6"],[9,0,"7"],[10,0,"8"],[11,0,"9"],[12,0,"a"],[13,0,"b"],[14,0,"c"],[15,0,"d"],[16,0,"e"],[17,0,"f"]]},{"type":"eight demultiplexer","name":"Demux","inputs":[[1,0,3],[2,0,"1"]]},{"type":"greater than or equal gate","name":"IterationIsOver","inputs":[[1,0,3],[2,0,6]]},{"type":"tenth-sec delay circuit","name":"Delay"},{"type":"concatenator","name":"Concatenate","inputs":[[1,0,"#"],[2,0,"1"],[3,0,"1"],[4,0,"1"],[5,0,"e"],[6,0,"1"],[7,0,"0"]]},{"type":"advanced light","name":"Output","inputs":[[1,0,"#47EE10"],[2,0,100]]}],"wires":[[[1,"O",1],[3,"I",1]],[[1,"A",1],[2,"A",1]],[[1,"A",1],[7,"A",2]],[[2,"A",1],[3,"A",1]],[[2,"A",1],[10,"A",1]],[[3,"I",1],[3,"O",1]],[[3,"O",1],[6,"I",1]],[[3,"O",1],[7,"I",1]],[[3,"A",1],[8,"A",2]],[[3,"A",2],[4,"A",1]],[[4,"O",1],[5,"I",1]],[[4,"A",2],[5,"A",1]],[[5,"O",1],[6,"I",2]],[[5,"A",2],[6,"A",1]],[[6,"O",1],[9,"I",2]],[[6,"O",2],[9,"I",3]],[[6,"O",3],[9,"I",4]],[[6,"O",4],[9,"I",5]],[[6,"O",5],[9,"I",6]],[[6,"O",6],[9,"I",7]],[[6,"A",2],[7,"A",1]],[[7,"A",2],[9,"A",1]],[[7,"A",2],[8,"A",1]],[[7,"A",3],[8,"A",1]],[[9,"O",1],[10,"I",1]]]}
    This one uses both the multiplexer and the demultiplexer to great effect. The multiplexer and the number generator could, in theory, be replaced with a "pick circuit" drawing from a list[16] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}, but said list would first have to be constructed, which is a great tedium and uses at least 1 extra component.
    Why 0.6 seconds? Because a 0.1 second delay is necessary for each iteration.

    7: For Nerds, Caesar Cypher
    My favourite circuits are ones that operate on strings and do something fancy with them. Construct a list[26] containing all the letters of the alphabet, in order. Then implement a Caesar cypher in such a way that the "letter shift" is configurable by the user (it can be set manually to any positive integer). Allow the user to input a string that will be encoded by the cypher. Iterate over the entire string, leave the values that aren't contained in the alphabet list unchanged (push them to the output without making any alterations). Mind the lowercase/uppercase distinction.
    The biggest problem here is that list/string indexing always starts at 1, like in DM. Explaining why this is retarded is best left for another time, but just remember that the allowed indexes are not between 0 and 25 but between 1 and 26.
    A lot of times, you'll be pushing several data values to the same input wire. It's up to you to decide when and how these values should overwrite each other, depending on time, condition, or something else entirely. Oftentimes, you'll push some data to input, but only perform an operation on that particular value if it suits you (otherwise you'll wait until the value is overwritten by something else and then pulse the component).
    If the example's taking you a lot of time and many components, and you're frequently stumped, there's a reason the header says "For Nerds." Don't worry too much about it, as the problem is inherently more complex than any other encountered so far in this guide.
    Code:
    {"assembly":{"type":"type-a electronic assembly"},"components":[{"type":"constant chip","name":"NULL"},{"type":"constant chip","name":"ZERO","special":0},{"type":"append circuit","name":"Alphabet","inputs":[[1,0,["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]],[2,0,"z"]]},{"type":"number pad","name":"Shift"},{"type":"text pad","name":"Input"},{"type":"lowercase string converter","name":"StringLowercase","inputs":[[1,0,"TEST!"]]},{"type":"get length","name":"GetLength","inputs":[[1,0,"TEST!"]]},{"type":"addition circuit","name":"Count","inputs":[[1,0,6],[2,0,1]]},{"type":"less than or equal gate","name":"ContinueIteration","inputs":[[1,0,6],[2,0,5]]},{"type":"indexer","name":"GetChar","inputs":[[1,0,"test!"],[2,0,6]]},{"type":"search circuit","name":"GetCharIndex","inputs":[[1,0,["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]],[2,0,"!"]]},{"type":"addition circuit","name":"AddToIndex","inputs":[[1,0,0],[2,0,7357]]},{"type":"subtraction circuit","name":"DecrementIndex","inputs":[[1,0,7377],[2,0,1]]},{"type":"greater than gate","name":"GreaterThanTwentyFive","inputs":[[1,0,7376],[2,0,25]]},{"type":"modulo circuit","name":"GetModulo","inputs":[[1,0,7376],[2,0,26]]},{"type":"addition circuit","name":"IncrementModulo","inputs":[[1,0,18],[2,0,1]]},{"type":"at circuit","name":"GetAlphabetLetter","inputs":[[1,0,["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]],[2,0,19]]},{"type":"small concatenator","name":"Concatenate","inputs":[[1,0,"sdrs!"],[2,0,"!"]]},{"type":"custom delay circuit","name":"Delay","inputs":[[1,0,10]]},{"type":"small screen","name":"Output","inputs":[[1,0,"sdrs!"]]}],"wires":[[[1,"O",1],[18,"I",1]],[[1,"A",1],[5,"A",1]],[[2,"O",1],[8,"I",1]],[[2,"A",1],[5,"A",1]],[[3,"I",1],[3,"O",1]],[[3,"O",1],[17,"I",1]],[[3,"O",1],[11,"I",1]],[[4,"O",1],[12,"I",2]],[[5,"O",1],[7,"I",1]],[[5,"O",1],[6,"I",1]],[[5,"A",1],[7,"A",1]],[[5,"A",1],[6,"A",1]],[[6,"O",1],[10,"I",1]],[[7,"O",1],[9,"I",2]],[[7,"A",2],[8,"A",1]],[[8,"I",1],[8,"O",1]],[[8,"O",1],[10,"I",2]],[[8,"O",1],[9,"I",1]],[[8,"A",1],[19,"A",2]],[[8,"A",2],[9,"A",1]],[[9,"A",2],[10,"A",1]],[[9,"A",3],[20,"A",1]],[[10,"O",1],[11,"I",2]],[[10,"O",1],[18,"I",2]],[[10,"A",2],[11,"A",1]],[[11,"O",1],[12,"I",1]],[[11,"A",2],[12,"A",1]],[[11,"A",3],[18,"A",1]],[[12,"O",1],[13,"I",1]],[[12,"O",1],[17,"I",2]],[[12,"A",2],[13,"A",1]],[[13,"O",1],[14,"I",1]],[[13,"O",1],[15,"I",1]],[[13,"A",2],[14,"A",1]],[[14,"A",2],[15,"A",1]],[[14,"A",3],[17,"A",1]],[[15,"O",1],[16,"I",1]],[[15,"A",2],[16,"A",1]],[[16,"O",1],[17,"I",2]],[[16,"A",2],[17,"A",1]],[[17,"O",1],[18,"I",2]],[[17,"A",2],[18,"A",1]],[[18,"I",1],[18,"O",1]],[[18,"O",1],[20,"I",1]],[[18,"A",2],[19,"A",1]]]}
    What a clusterfuck. The Modulo component is vital in ensuring cyclicity, but the indexing starting at 1 doesn't work terribly well with it.
    Problem being: n mod 26 should never return 0, because it's an invalid index. The workaround is pretending momentarily that we're working in a system where indexing does start at 0 (that's why the value is decremented,) get our result, and convert it back to the "lists start at 1" hell.
    The delay component is set to 1 second, but it could also be set to 0.1 seconds. The delay must be there due to the fact that each and every component has a pulse cooldown of at least 0.1 seconds (10 seconds at most, to my understanding), during which it cannot be pulsed again.

    8: Radio
    Up until now we've worked with single, standalone assemblies, but there are many designs and concepts that could benefit from having 2 or more assemblies interact with each other. Build a radio device with a microphone and text-to-speech capabilities. Clone the device. It should be able to transmit to, and receive messages from, any of its clones.
    This is an incredibly simple device, but it's the first device where the advanced integrated signaller is needed.
    Code:
    {"assembly":{"type":"type-a electronic assembly"},"components":[{"type":"microphone","name":"Input"},{"type":"advanced integrated signaler","name":"SendReceive","inputs":[[1,0,1357],[2,0,"Radio"]]},{"type":"text-to-speech circuit","name":"Output"}],"wires":[[[1,"O",2],[2,"I",3]],[[1,"A",1],[2,"A",1]],[[2,"O",1],[3,"I",1]],[[2,"A",3],[3,"A",1]]]}
    This implementation is annoying in-game, but you could improve on the radio's concept by adding toggleable microphones, microphones that only transmit if a certain word or phrase is heard, and other improvements you can think of.
    Beware: you'll likely need to use the debugger to overwrite the "id tag" variable (just write the same value to it) after cloning. This is a bug we have to live with for now. Just remember that if nothing's working despite the cell being charged and all the wires being correctly placed, you probably just need to update the "id tag."

    9: Drones
    Drones are assemblies capable of movement if a "locomotion circuit" is installed. There's only so much a handheld/stationary assembly can do, so movement is a pretty big deal. There are infinite ways to make a drone move, but the simplest, both in usage and in implementation, is the remote-controlled drone that moves to the tile/object/character you point the remote towards. Make a drone base, which you can later clone and add new functionality to, using the point-to-tile method.
    The ranged scanner is a very high-complexity item, adding 36 to the assembly's complexity. As a general rule, the remote should only have inputs and signallers. Leave all the arithmetic/logic operations to the drone itself, as the drone is a size 75 and complexity 225 assembly. It also makes the whole mess a lot more organised and comprehensible.
    The advanced integrated signaller only accepts a string for its "command" variable. However, we're scanning a ref here. If only there were a way to encode a ref into a string.
    Remote:
    Code:
    {"assembly":{"type":"type-a electronic assembly"},"components":[{"type":"ranged sensor","name":"GetRef"},{"type":"reference encoder","name":"RefEncode"},{"type":"advanced integrated signaler","name":"RefSignal","inputs":[[1,0,1357],[2,0,"Ref"]]}],"wires":[[[1,"O",1],[2,"I",1]],[[1,"A",1],[2,"A",1]],[[2,"O",1],[3,"I",3]],[[2,"A",2],[3,"A",1]]]}
    Drone:
    Code:
    {"assembly":{"type":"type-a electronic drone"},"components":[{"type":"advanced integrated signaler","name":"GetRef","inputs":[[1,0,1357],[2,0,"Ref"]]},{"type":"reference decoder","name":"RefDecode"},{"type":"custom ticker","name":"MoveTick","inputs":[[1,0,1],[2,0,1]]},{"type":"basic pathfinder","name":"GetDirection"},{"type":"locomotion circuit","name":"Move"}],"wires":[[[1,"O",1],[2,"I",1]],[[1,"A",3],[2,"A",1]],[[2,"O",1],[4,"I",1]],[[3,"A",1],[4,"A",1]],[[4,"O",1],[5,"I",1]],[[4,"A",2],[5,"A",1]]]}
    Very basic implementation. If the ref you scan with the remote changes its position, this drone will follow it. It's up to your personal tastes whether or not this is a good thing. Of course, there's a way to make it only follow the ref's coordinates at the time of the scan: use an examiner.

    10: For nerds, Stack
    A simple data structure, the Stack is a list (in reality, an array of fixed size, but let's ignore that) with, at its most basic, two algorithms that permit it to function properly: Push() and Pop().
    Push is very descriptive of what it does: it pushes a value to the top of the stack.
    Pop removes the top value and outputs it.
    Stacks operate on a Last In - First Out principle, LIFO for short. The last value pushed into the stack is the first value to be removed when Pop is called.
    Implement a Stack in this way. The Push algorithm will only accept numbers.
    Since Push and Pop must operate on the same list, don't forget to send the right output data to the right components!
    Code:
    {"assembly":{"type":"type-c electronic mechanism"},"components":[{"type":"number pad","name":"Push"},{"type":"append circuit","name":"PushAdd","inputs":[[1,0,[]],[2,0,29]]},{"type":"button","name":"Pop"},{"type":"at circuit","name":"PopGet","inputs":[[1,0,[5,2,25,29]],[2,0,0]]},{"type":"delete circuit","name":"PopRemove","inputs":[[1,0,[]],[2,0,0]]},{"type":"len circuit","name":"GetListLength","inputs":[[1,0,[]]]},{"type":"addition circuit","name":"IncrementListLength","inputs":[[1,0,0],[2,0,1]]},{"type":"join text circuit","name":"ListToString","inputs":[[1,0,[]],[2,0,", "],[4,0,1]]},{"type":"small screen","name":"Output"}],"wires":[[[1,"O",1],[2,"I",2]],[[1,"A",1],[2,"A",1]],[[2,"I",1],[2,"O",1]],[[2,"I",1],[5,"O",1]],[[2,"O",1],[6,"I",1]],[[2,"O",1],[8,"I",1]],[[2,"O",1],[4,"I",1]],[[2,"O",1],[5,"I",1]],[[2,"A",2],[6,"A",1]],[[3,"A",1],[4,"A",1]],[[4,"I",2],[6,"O",1]],[[4,"A",2],[5,"A",1]],[[5,"I",1],[5,"O",1]],[[5,"I",2],[6,"O",1]],[[5,"O",1],[6,"I",1]],[[5,"O",1],[8,"I",1]],[[5,"A",2],[6,"A",1]],[[6,"O",1],[7,"I",1]],[[6,"A",2],[7,"A",1]],[[7,"O",1],[8,"I",4]],[[7,"A",2],[8,"A",1]],[[8,"O",1],[9,"I",1]],[[8,"A",2],[9,"A",1]]]}
    The "join text circuit" is a bit wonky, I'll be honest.
    The "at circuit" has no real purpose here other than to show that the removed element is also supposed to be used someplace else.

    These examples use several advanced techniques, like iteration, JK Latch toggling, list operations, the use of modulo, the use of signallers and others. These may be employed in more complex scenarios for better complexity economy, allowing you to use fewer high-complexity items by substituting them with arithmetic and logic operations.

    Chapter Three: This One WEIRD Trick
    This short part focuses on Integrated Circuit tips that make your life easier.
    General
    • Label all your components. When you're tackling very complicated circuits, this becomes essential. Imagine having 5 constant chips and having to click each of them to check their output data. Labels should be clear, concise, and ideally explain what they accomplish rather than simply what they do with the input data (but it's not always easy to label them this way).
    • If your circuit is very complex, you'll likely want to split it into small subproblems I refer to as "functions" or "methods" or "procedures." Each of them will do their own task, and provide an output that can be fed into another function. The system doesn't actually provide ways to work with functions: they're an abstract concept. Say you have functions Verify and Switch. You can label their components like this for easy reference:
      1. VerifyCount
      2. VerifyIterate
      3. Verify <- (This one could do the main operation of the function)
      4. SwitchCheck
      5. Switch <- (Same here)
    • Order your components. This will give your circuit a nice, organised feel. Work out the component order you're most comfortable with, and each time you add a new component to the assembly, choose the best position for it. My circuits' components roughly follow this structure:
      1. Constants
      2. Other memory components
      3. Inputs, ordered by how they should appear on the UI
      4. All the operation circuits, ordered by whatever makes the most sense
      5. Outputs, ordered by how they should appear on the UI
    • You don't really have to plan ahead when creating an assembly. You can choose the smallest assembly available and upgrade it if you need to. Smaller assemblies are more valuable due to their portability, but a complex program simply won't fit in one. To upgrade your assembly, analyse it. The code should begin with something like "type-a electronic assembly." Change it to "type-b electronic mechanism," for example, and clone the result. Now you have a bigger assembly that's wired in exactly the same way as the smaller one.
    • To empty out an assembly, remove its power cell and use it on the Printer. To recycle an empty assembly, use it on the Printer again. The metal used for the circuit is refunded 100%.
    • A word on iterators: the time delay is critical for iteration, but how small can you make it without breaking your loop?
    The common iterator is constructed as such:
    [1] Reset constant (pulsed at the beginning of the iteration as a whole)
    [2] Addition/subtraction (increment the counter by 1)
    [3] Less than/greater than (check if the iteration is over or not)
    [4...n-1] Actions (anything you wish to be done repeatedly)
    [n] Delay
    So how small can the delay be?
    All arithmetic/logic operations only have 0.1 seconds as their pulse cooldown. The smallest delay possible, then, will be the largest pulse cooldown among all the components labeled above as "Actions." Not following this rule may bring unexpected results, for instance:
    You want to fire a weapon every 1 second, 10 times, so you set the delay variable to 10 tenths-of-a-second, and the upper bound for your less-than-or-equal circuit to 10. But when you test it, it only fires once. This is because the weapon firing component has a pulse cooldown of 10 whole seconds, and pulsing it repeatedly is meaningless, but the counter has no trouble at all being incremented every 1 second, so it reaches 10 before the weapon has a chance to fire again. Setting the delay to 100 tenths-of-a-second fixes the problem.
    • Try to make circuits fun for everyone. There are some circuits that can ruin people's enjoyment, like:
      • A small ranged sensor device that scans a character and updates their coordinate position every second. Scan an antag with this and Security will be on their arse until the round is over. Not very fun, considering the antag toggling suit sensors off to conceal their location becomes meaningless.
      • A similar sensor that scans the holder, and provides a constant feed on their vitals to Medical, giving a loud alert to Medical personnel if they're severely injured (of course, including their exact coordinates). This is an extra layer of suit sensors and it's a bit powergamey.
        • Powergame bonus: also scans for all characters in a 8-metre radius and relays the complete list to Medical when you're injured.
      • Instakill/stun weapons: an assembly that contains more than one gun, all being pulsed in parallel. Especially bad if used against characters, with the lethal setting. Good for fighting the Class 7, otherwise removes the fun in firefights since everyone is either downed or critical with a single shot.
      • All the big explodey stuff doesn't become better because your remote drone does it. If you really want to make a 300:300 water-potassium grenade and slot it in a drone, intent on removing a large portion of 3-4 decks, at least have it spit out some lines like "SELF DESTRUCTION PROTOCOL ACTIVATED. TIME TO DETONATION: 20 SECONDS." and then have it count down to 0. This will allow people to evacuate.
      • In general, don't use circuits for validhunting, powergaming or bad antagging. Just because you can make it doesn't mean you should use it.
    Tools
    • The order in which your wires are does matter, and differently ordered wires will occasionally produce different results. If your shit is breaking due to bad wire order, you'll have no choice but to unwire the conflicting wire at the top and wire it again, placing it at the bottom.
    • Wiring is a 2-step process. You'll usually be wiring a PULSE OUT to a PULSE IN and an output wire to an input wire, but the reverse also works: you can wire input to output and it'll work the same way.
    • The debugger's Ref function allows you to scan an object and save its Ref to be inserted into your assembly, but you can't make Ref into a persistent data type you can save forever. This is because a Ref is a reference to an object saved on the server's memory, which will eventually be de-allocated. There's no guarantee the same memory address will contain the same object in later rounds, so the system doesn't allow you to reference that same memory address (for your own sake). Correct me if this is bullshit/too inaccurate.

    NOTES
    I'd like to mention some honourable gentlemen of the present Circuit scene. Starting with Arkter, whose Renald Dalton first taught me Circuits around February or March 2019. He's an alright noodle man, reach out to him for some in-game guidance if you need it.
    Other mentions: Roland410. The player of Carson Johnson (His key is too hard to type). The player of Shunk. Et al.
    In-game, you can occasionally find me as Ensign Aria Guinness, Researcher. I sit in the fabrication lab making circuits and processing fabrication requests (after maxing out R&D, of course).
    Please feel free to post fancy circuits of your own, better/alternative solutions and other examples.
    Inb4 "NERD"

    EDIT: some clarifications.
     
    Last edited: Oct 9, 2019
  2. Arkter

    Arkter Chef

    As Resident Circuit Shitlord Renald Dalton I approve of this guide.
     
    Cheb Pomidorov likes this.
  3. Astrospacedude

    Astrospacedude Bartender

    Thanks for this, my dream of making a computer is a bit closer now.
     
  4. Cheb Pomidorov

    Cheb Pomidorov Bartender

    Glad you find it useful. I've already made a simplistic computer using Integrated Circuits, so I'd be open to give you a few extra pointers if you need them.
     
  5. Astrospacedude

    Astrospacedude Bartender

    Integrated circuits? The exist in game?
     
  6. Cheb Pomidorov

    Cheb Pomidorov Bartender

    They are what the guide is about. The guide wouldn't exist if they didn't exist in-game.
     
  7. Astrospacedude

    Astrospacedude Bartender

    As in the circuit which is a small amount of logic gates on a board
     
  8. Cheb Pomidorov

    Cheb Pomidorov Bartender

    Yeah, you can use the system outlined above to make whatever logic gate, arithmetic operator, bistable, memory unit, etc. you desire
     
  9. Syncron

    Syncron Assistant

    Jim Mason here. I need to figure more circuits out. I can make weapons and dodads, But I need to learn how to properly use JK latches, and all sorts of that stuff. I like to 'research' my ideas, But admittedly I've been stumped on stuff thats made me stop working with circuits for a little bit.

    EDIT: Only a little salty that I don't get a mention for my dodads. They have enraged security, and saved exploration before. Hah. (This salt is a joke.)
     
    Last edited: Oct 20, 2019 at 12:50 AM