×
Create a new article
Write your page title here:
We currently have 276 articles on Waste Of Space Wiki. Type your article name above or create one of the articles listed here!



    Waste Of Space Wiki

    Programming/Staging: Difference between revisions

    Content added Content deleted
    mNo edit summary
    m (revised quiz)
     
    (19 intermediate revisions by 2 users not shown)
    Line 1: Line 1:
    See [[Talk:Programming]]

    '''new'''

    [[Waste Of Space Wiki|Waste Of Space]] features a fully fleshed out programming system, allowing players to program [[Microcontroller|Microcontrollers]] using a sandboxed subset of [https://luau-lang.org/ luau] (which is itself a superset of [https://lua.org lua]) called Pilot.lua. Programming allows players to easily and efficiently implement complex logic and automation into their builds by writing code.
    [[Waste Of Space Wiki|Waste Of Space]] features a fully fleshed out programming system, allowing players to program [[Microcontroller|Microcontrollers]] using a sandboxed subset of [https://luau-lang.org/ luau] (which is itself a superset of [https://lua.org lua]) called Pilot.lua. Programming allows players to easily and efficiently implement complex logic and automation into their builds by writing code.


    This article serves as an introduction to programming in-game. It provides a [[Programming/Staging#Tutorial|brief no-frills tutorial]] to get you jumpstarted, a list of commonplace and useful [[Programming/Staging#Parts|programming-related parts]] to consider, some [[Programming/Staging#Resources|useful resources]] to keep you learning even after you've read through it, and at the end; a few [[Programming/Staging#Examples|inspiring examples]]. The talk page of this article hosts a [[Talk:Programming/Staging|community board]] to share useful and unique projects/code.


    This article serves as an introduction to programming in-game. It provides a [[Programming/Staging#Tutorial|handy yet detailed tutorial]] to get you started, a list of commonplace and useful [[Programming/Staging#Parts|programming-related parts]] to consider, some [[Programming/Staging#Resources|useful resources]] to help you with programming successfully, and at the end; a few [[Programming/Staging#Examples|inspiring examples]]. The talk page of this article hosts a [[Talk:Programming/Staging|community board]] to share useful and unique projects/code.
    == Tutorial ==
    {| class="wikitable" border="0" cellspacing="0" cellpadding="5" style="width:700px" ||
    | bgcolor=#ccf |
    <quiz display=simple>
    {Complete the text from the Wikipedia article on [[w:Aristotle|Aristotle]].
    |type="{}"}
    <big>'''Early Years:'''</big>
    Aristotle was born in { Stageira|stageira _8 } in Chalcidice. His parents were
    { Phaestis|phaestis _8 } and { Nicomachus|nicomachus _10 }, who became physician
    to King Amyntas of Macedon.

    Aristotle was educated as a member of the aristocracy. At about the age of
    { eighteen|18 _8}, he went to { Athens|athens _6 } to continue his education
    at { Plato|pluto _5 }'s Academy.
    <br>

    <big>'''Later Years:'''</big>
    Aristotle remained at the Academy for nearly twenty years, not leaving until
    after Plato's death in { 347 _3 } BC.
    </quiz>
    |}

    <quiz display=simple>
    {Type the question here...
    |type="()"}
    + The correct answer.
    - Wrong or misleading answer.
    - Wrong or misleading answer.
    - Wrong or misleading answer.
    </quiz>


    == Tutorial ==
    === Foreword ===
    === Foreword ===
    [[Microcontroller|Microcontrollers]] are perhaps one of the most powerful tools waste of space provides you with. Knowing how to use them is paramount if you want to implement any kind of advanced automation or autonomy into your builds. This is not to say they are only for drones and factories, however. Programming expands your already large range of possibilities to a nearly boundless one.
    [[Microcontroller|Microcontrollers]] are perhaps one of the most powerful tools waste of space provides you with. Knowing how to use them is paramount if you want to implement any kind of advanced automation or autonomy into your builds. This is not to say they are only for drones and factories, however. Programming expands your already large range of possibilities to a nearly boundless one.
    Line 43: Line 10:
    This tutorial will provide you with a brief guide on programming and coding in-game. Namely; programming and coding are not the same, though they are often confused as such. Coding is just writing instructions to the computer (code), while programming is the engineering of software. A programmer creates algorithms and solves problems, and then codes them to create a fully-fledged software solution.
    This tutorial will provide you with a brief guide on programming and coding in-game. Namely; programming and coding are not the same, though they are often confused as such. Coding is just writing instructions to the computer (code), while programming is the engineering of software. A programmer creates algorithms and solves problems, and then codes them to create a fully-fledged software solution.


    Please do not feel intimidated by this, as if it something out of reach to you. Though serious programming is not for everyone's cup of tea, you do '''not''' need to be an ''AAA++'' software engineer with 15 years of experience to code up your little idea. Everyone needs to start somewhere, even the pros; and Waste of Space is hardly a source of difficult problems. If you haven't already gotten the gist, this guide is aimed at newcomers to programming. Perhaps, if after reading this tutorial you find out that you like programming, you may even become one of those pros one day. Even in the worst case though, you will have learned another, increasingly relevant skill, and will have developed your logical thinking.
    Please do not feel intimidated by this, as if it something out of reach to you. Though serious programming is not everyone's cup of tea, you do '''not''' need to be an ''AAA++'' software engineer with 15 years of experience to code up your little idea. Everyone needs to start somewhere, and Waste of Space is hardly a source of difficult problems. Perhaps, if after reading this tutorial you find out that you like programming, you may even become one of those pros one day. Even in the worst case though, you will have learned an increasingly relevant skill and will have developed your logical thinking. If you haven't already gotten the gist, this guide is aimed at newcomers to programming.


    If you still aren't sure, perhaps a well-known example (it's on the game's thumbnail!) of programming in waste of space can win you over.
    If you aren't sure whether or not to commit to learning programming, perhaps a well-known example (it's on the game's thumbnail!) of programming in waste of space can tip you over to either side.


    {{#ev:youtube|https://yewtu.be/watch?v=waYNQq3f60Q|1000|center|Example description|frame}}
    {{#ev:youtube|https://yewtu.be/watch?v=waYNQq3f60Q|1000|center|A video of the space arcade by iiMurpyh|frame}}


    === Learning to code ===
    === Learning to code ===
    === Computational thinking ===


    === Coding revisited ===
    ==== Getting started ====
    While you may be tempted to start writing code right away you'll need to set up an environment for this first. This is what's called a '''development environment'''.


    As you'll just be writing some basic [https://luau-lang.org luau] (a dialect of [https://lua.org/ lua]) throughout this tutorial, this will consist of just a '''text editor''' (and something to run your code with). A text editor can be as simple as just a notepad program so you have somewhere to jot down your code, or can be more complex and specialised for writing code. These types of text editors (code editors) often offer useful features such as automatic code completion and syntax highlighting (it colour-codes smaller bits of code, conveying their meaning or data type). A few suggestions for a code editor are listed below, complete with pros, cons, images, and links.
    === The Microcontroller ===


    * (the list)
    === Programming ===


    === Afterword ===


    == Parts ==


    Once you've set up a text editor, there's one more thing to do before you can start coding: setting up a '''runtime environment'''. As lua is a '''scripting''' language - a programming language in which the instructions to the computer are stored as '''source code''' (the code as you wrote it, in textual format) - it must be translated to the computer in real time because computers can only understand binary (0s and 1s). This is what a runtime environment is for (in this case); it allows for the execution of '''scripts''' (source code) by translating them to '''machine code''' (instructions understandable to the computer) on the go.
    == Resources ==


    In this case, you'll need something that can run luau code. This guide recommends that you use Roblox Studio for these purposes. Using Studio to test your code isn't exactly the best, but studio is approachable for a beginner such as yourself. Besides, there aren't really any other options anyways. Later on, you'll switch from using Studio to testing code on [[Microcontroller|Microcontrollers]] in-game.
    * [https://github.com/iimurpyh/pilot-lua/wiki iiMurpyh's pilot.lua wiki] - Documents all the special objects and functions that microcontrollers can use.
    * [https://wos.mawesome4ever.com/ Mawesome4ever's part list] | Note: May not show all information associated with a part.
    ** [[Module:PartJSON]] - Extracted JSON used for the above website. Displays everything, but doesn't provide you with a nice GUI


    * https://create.roblox.com/docs/ - Roblox's documentation for rblx.lua.


    * [https://www.lua.org/manual/5.1/manual.html Lua 5.1 Reference Manual] - Provides a tutorial to get started with plain lua, as well as its built-in functions.


    To set up Studio for testing your code, do the following:
    == Examples ==
    [[File:FlappyBirdGif.gif|thumb|A flappy bird arcade machine, made by iiMurpyh|302x302px|alt=|center]]


    * Install Roblox Studio if necessary.
    ** Go to https://create.roblox.com/
    ** Click the 'Studio' button in the left side menu (under 'Quick links': at the bottom of the list). Alternatively, if you are not logged in, click the 'Start creating' button.
    ** Click the 'Download' button
    ** Install Studio by running the newly downloaded file
    * Open Roblox studio and under the 'New' tab click on the 'Baseplate' template
    * Open the file tab (Top left) and save this new experience (click 'Save to Roblox')
    * Close all of the windows except the 'Output' window (if present) and the 'Explorer' window.
    ** If you don't have an output window, click the 'View' tab at the top of your screen and then click the 'Output' button to turn the window on
    * Resize the output window to be a bit bigger than by default if you have the screen space for it.
    * In the Explorer, hover over the 'ServerScriptService' and click the plus (+) icon beside it. Then, add a script to it (a regular script: make sure it's not a LocalScript or ModuleScript).<br />




    If you've done everything correctly, you should now be in the built-in script editor. You should see the following:<syntaxhighlight lang="lua" line="1">
    print("Hello world!")
    </syntaxhighlight>


    Go ahead and run this by clicking play at the top of your screen. You'll do this from now anytime you need to run your code. Unless you've chosen the built-in studio editor as your text editor of choice, you'll have to copy and paste the code you write into this script. Make sure to first select all of the text and only then paste your code so as to replace the existing contents.


    Once everything's loaded, you should see the following in the output window:
    '''old'''
    Hello world!


    This means everything's working! You're now ready to start coding. If this isn't the case, double check you followed all of the instructions to the letter.
    [[File:ComputerDiagram.png|alt=|thumb|300x300px|Diagram for how to construct a basic computer including a MicroController.]]Waste of Space features a programming language named '''Pilot.lua'''. Pilot.lua lets players manipulate the states of objects in-game. As Pilot.lua is a superset of [https://luau-lang.org/ Luau] – Roblox' superset of [https://en.wikipedia.org/wiki/Lua_(programming_language) Lua] 5.1 ''–'' learning Luau (or at least Lua 5.1) first would be benificial.
    Important parts for programing:


    What just ran is the print function - one of the simplest '''functions''' there is. You'll learn more about what a function is later, but for now know that it's basically a black box that does something with whatever you put between its parentheses - which are like the function's mouth into which you feed it values. In this case, the value you're feeding it is some text - a '''string''' (again, you'll learn more about these later; for now remember the name and that you create one by putting some text in between quotation marks, e.g. "text"). What the print function does is that it prints out (displays in the output) the text you gave it. In this case - Hello world!
    *[[Microcontroller]] - Runs code when triggered by polysilicon if it is powered. This is an essential part, as it is the only way to run code unprivileged. <!-- "..as it is the only way to run code unprivileged" as administrators can use the terminal. -->
    *[[Port]] - Allows the microcontroller to interact with other objects, configure them, and send triggers. While not strictly essential, it is still a core part of programming as it is the only way for a microcontroller to interact with its surroundings.
    *[[Screen]] - Displays user interface objects on its surface (such as TextLabel, ImageLabel, ..). It is one of the most common ways to provide the user with feedback as it is able to display it in a clear, visual way. It can be to a certain extent supplemented with the much easier to program [[Sign|signs]].
    *[[Disk]] - Stores values in a [https://create.roblox.com/docs/education/coding-5/intro-to-dictionaries dictionary] format. Can store large amounts of data like code and [[Model Builder|model codes]]. Data stored on a disk is permanent, as opposed to variables on a microcontroller (which are lost when the microcontroller is powered off, or the server is restarted).
    *[[EthernetCable]] (Optional) - Extends the range of a port, similarly to how [[Wire|wires]] extend the [[Power and logic|power]] from a [[PowerCell]]. Note: The [[EthernetCable]] needs to be touching the hole on the [[Port]] in order to work.
    *(UNSTABLE) [[Router]] (optional) - The router is the [[Antenna]] of [[EthernetCable|ethernet cables]]. It does the same thing as [[EthernetCable|ethernet cables]], only wireless. This is incredibly useful, as it allows for wireless connections, and allows for parts to be connected from across the region. Note that this is ONLY in [https://www.roblox.com/games/4569607361/Waste-Of-Space-UNSTABLE unstable].


    Other less-important items in coding include:
    *[[Modem]] - Allows for cross-region message passing and communication with arbitrary www domains (Sends GET and or POST requests to either the WOS internet, or the real (www) one). Allows for the creation of an internet of sorts. See the article for more details.
    *[[LifeSensor]] - Returns the names of players and their Vector3 location, if they are within its range. Can be used to make, for example, smart turrets.
    *[[Gyro]] - Not programming-exclusive, though still widely used as it has a programmable method called gyro:PointAt(vector3 position). This, along with [[LifeSensor]], can make an accurate turret, or if you just want to make the gyro point at a certain place.
    *[[Keyboard]] - Used for inputting text, commands, or when attached to a [[Seat]] or [[VehicleSeat]], can be used to get keys pressed to make keybinds.
    *[[Microphone]] - Retrieves chat messages. Can be used for chat logs or chat commands.
    *[[Instrument]] - Measures physical properties such as temperature or velocity.
    *[[TouchScreen]] - A improved version of the [[Screen]], as it allows you to get the X and Y (in offset) of the cursor on the screen.


    As an example, the code below is code for a smart turret that takes chat commands and targets players accordingly, with the command <code>target playername</code>:<syntaxhighlight lang="lua" line="1">
    local Gyro = GetPartFromPort(1, "Gyro") -- Gets gyro attached to port 1
    local Microphone = GetPartFromPort(2, "Microphone") -- Gets microphone attached to port 2
    local Commanders = { -- List of usernames allowed to use the smart turret
    ["Robuyasu"] = true;
    }
    -- Connects to the microphone, adding an event to it that will listen for chat input
    Microphone:Connect("Chatted", function(Player, Message)


    When you started reading your language for the first time, you needed to learn in what order to read the words before you. Code is read from left to right, line by line.
    -- This simply makes sure that the player speaking is allowed to run a command
    if not Commanders[Player] then return end


    The code before you currently only occupies a single line. Copy it, press enter, then paste it.
    if Message:lower():sub(0, 6) == "target" then -- If the message starts with target

    local Victim = Message:sub(8) -- Gets the rest of the message
    You should now see the following two lines of code:<syntaxhighlight lang="lua" line="1">
    Gyro:Configure({Seek=Victim}) -- Configures the seeker to target that person
    print("Hello world!")
    end
    print("Hello world!")
    end)
    </syntaxhighlight>
    </syntaxhighlight>
    There are many functions in Pilot.lua that allow you to interact with other objects:


    *<code>GetPort(ID)</code> - Returns a port instance that can be used in other functions. It is only really recommended if your going to do something like <code>port:Connect("Triggered")</code>
    *<code>GetPartFromPort(ID or Port Instance, ClassName)</code> Returns a part if found directly attached to a port. An example would be GetPartFromPort(2, "Screen")
    *<code>TriggerPort(ID or Port Instance)</code> - pretty self explanatory, sends a [[Button|trigger signal]] from the given port or port instance
    *<code>GetPartsFromPort(ID or Port Instance, ClassName)</code> Returns an [https://create.roblox.com/docs/luau/tables array] of different parts attached to the [[Port]]. In order to use, it is recommended to use [https://create.roblox.com/docs/education/coding-5/pairs-and-ipairs ipairs], however, a <code>'''for i =''' number, number do</code> along with <code>Parts[i]</code> will work too.


    Next, modify the code on the second line so it prints out <code>Hi World!</code>:<syntaxhighlight lang="lua" line="1">
    All objects will contain certain programmable properties and functions. However, all instances will contain the following properties and methods:
    print("Hello world!")
    *Properties
    print("Hi world!")
    **Configurable properties, for example an IonRocket's thrust speed property
    </syntaxhighlight>Run this code. The output should be <code>Hello World!</code> and <code>Hi World!</code>; one after the other.
    **<code>ClassName</code>, which is simply the name of the object
    *Methods
    **Object:Trigger(), which simply triggers the object
    **Object:Configure({Property=NewValue}), which configures the part to the given dictionary/table
    **Object:Connect, connects a function to an object's event


    This should give you a good idea of how code flows if you haven't already figured it out.
    *Events
    **part:Connect("Triggered", function)
    Certain parts however will have their own special properties.
    *Screen
    **Methods
    ***Screen:CreateElement(string GUIClassName, dictionary Properties), an example includes Screen:CreateElement("TextLabel", {Text = "Hello World!"; TextScaled = true});
    ***Screen:ClearElements(), which clears all elements in a gui


    You're now ready to move on onto the first real lesson: variables.
    *Disk
    **Methods
    ***disk:Write(string Key, any Value) writes a value in the disk with the given key.
    ***disk:Read(string Key) Reads the value in the disk with the given key. If there is no value, returns nil.
    ***disk:ClearDisk() clears the disk
    ***disk:ReadEntireDisk() returns a dictionary of all the values and keys in a disk.


    ==== Variables, scope ====
    *Keyboard
    **Events
    ***keyboard:Connect("KeyPressed", function(keycode key, string key, string player) end) fires when someone presses a key while sitting on a [[Seat]] attached to the keyboard
    ***keyboard:Connect("TextInputted", function(string Text, string player) end) fires when someone presses on the [[Keyboard]] to open the text menu, and submits text. Note: the keyboard adds an extra character at the end on accident, because you press enter to submit, and so it adds an extra character.


    Say you want to store some information for future use; let's say that your friend later needs it so they can do something and you can't tell them it directly. Assume that you decide to write that information on a slip of paper.
    ==Tutorials==

    These tutorials are assuming you know a thing or two about coding already. More are yet to come.
    Now imagine that you also have an almost limitless number of really small boxes at your disposal. This is the computer's memory in this analogy.
    ===Events===

    One of the most important parts about programming in WoS is events. Events allow you to get player input, detect when something happened, and more. For example, if you are using the [[Microphone]], in order to get when a player has talked, you need to use the chatted event. A full list of events can be found [https://github.com/iimurpyh/pilot-lua/wiki here]. To get an event, you need to first do the connect method on the part, like this; microphone:Connect(). Within the parenthesis, you need to put two parameters. The first one is simple, just put the name of the event within a string (example: "Chatted"). As the second parameter, we put the function we want it to run when the event happens. This is known as a [https://en.wikipedia.org/wiki/Callback_(computer_programming) callback]. Basically, its when you pass a function as a parameter to another function. In this example, we want the :Connect() method to run a function whenever the "Chatted" event happens. In that second parameter, we can reference an already existing function, or make a function within the parameter. Here is our code so far:
    You can't just place your slip of paper anywhere as it'd get lost, so you decide to place your slip of paper into the nearest currently unused box.
    <syntaxhighlight lang="lua" line="1">

    local microphone = GetPartFromPort(1, "Microphone") --this gets the microphone object
    But how can your friend know which of those boxes to check for the slip of paper?
    microphone:Connect("Chatted", function() --so we call the connect method, then we tell it to run the function whenever it detects the event

    print("Someone talked!!!")
    The solution is to also label the box into which you place the slip of paper with a name specific to it: the entire box including its label is what's called a '''variable:''' a symbolic name (what you labeled the box with) associated with a storage location (the actual box itself).
    end)--we need to end the function, and close the open parenthesis

    The information inside the box is the '''value''' of the variable. This value can be whatever, and can change with time.

    It's key to note that the box in this analogy is opaque. You can only know what's inside the box if you open it.


    Let's see how that translates into code; it turns out it's really simple.

    Delete any code you have in the script you're using to test your code, then add the following:<syntaxhighlight lang="lua" line="1">
    local x = 3
    print(x) --prints out 3
    </syntaxhighlight>
    </syntaxhighlight>
    Let's break this down line by line:
    Now, this isn't very useful on its own. We have no way of telling what the person even said! All we know is when someone talked. However, we are in luck. When the connect method calls the function, it also passes the parameters along with the function (once again, all the events and what they return can be found [https://github.com/iimurpyh/pilot-lua/wiki here]). In the case of the chatted event, it returns the players name, and the message they sent. Here is the example code:

    <syntaxhighlight lang="lua" line="1">
    * <code>local x = 3</code> defines some variable x to be equal to 3
    local microphone = GetPartFromPort(1, "Microphone") --this gets the microphone object
    ** <code>x</code> is the name of the variable
    microphone:Connect("Chatted", function(player, message) --so we call the connect method, then we tell it to run the function whenever it detects the event
    ** <code>=</code> assigns the value of the variable to be whatever is on the other side of it
    print(player.. " Said: ".. message) --print what was said and who said it (eg. Playername Said: Hello!)
    ** <code>3</code> is the value you're assigning to the variable. In this case, it is a number.
    end)--we need to end the function, and close the open parenthesis
    * <code>print(x)</code> prints the value of the variable
    * <code>--prints out 3</code> is a comment - an annotation to source code. It's always at the end of a line and is created by using two dashes (-). It is ignored when running the code.



    Try playing around a bit with this code by changing the value of the variable: perhaps by changing it to another number, or perhaps to a string ("Hello world!", for example).

    You may notice that what <code>local</code> does wasn't defined. <code>local</code> sets the '''scope''' of a variable. '''Scope''' (or '''visibility''') is a property of variables which defines where (that is in which '''scope blocks''') their name binding is valid (so, if <code>a</code> is equal to 1, where <code>a</code> being equal to 1 is the case). Let's look at an example to make this clearer, and break it down line by line as before:<syntaxhighlight lang="lua" line="1">
    local a = 3

    do
    print(a) --prints out 3
    local x = 4
    local a = 5
    print(x) -- 4
    print(a) -- 5
    end

    print(a) -- 3
    print(x) -- nil
    </syntaxhighlight>
    </syntaxhighlight>

    ===Screen===
    * <code>local a = 3</code> sets <code>a</code> to be equal to 3, as you should know by now.
    The [[Screen]] is a confusing part for beginner programmers, because of all the confusing stuff like UDim2. So, here's an explanation. [[Screen|Screens]] are a very useful item for displaying information, allowing for much more possibilities then just simply configuring [[Sign|signs]]. While [[Sign|signs]] will work for displaying text, it doesn't have nearly as much possibility as [[Screen|screens]]. [[Screen|Screens]] can display multiple elements, and have custom size/position. However, when it comes to creating [[Screen]] elements, it can be confusing because it uses a whole new data type called [https://create.roblox.com/docs/reference/engine/datatypes/UDim2 UDim2]. UDim2 is a data type consisting of 4 values. The order goes XScale, XOffset, YScale YOffset,. ''What the heck does all that mean??'' Well, simply put, Offset is the X or Y size/position of the element in pixels. Scale is the X or Y size/position in screen sizes. ''What do you mean, "screen sizes"???'' 1 scale is equal to the entire size of the screen. 1 XScale is equal to the width of the screen, while 1 YScale is equal to the height of the screen. Scale is very important, as it allows for the ScreenElement to look the same no matter the size of it. In order to make a screen element cover the entire screen, you would put the scale at 1 for both. So what you can do is make the screen size equal to UDim2.new(1, 0, 1, 0). ''Whats the point of putting the zeros? Is there an easier way to do it?'' There is an easier way to do it. instead of using UDim2.new, you can use UDim2.fromScale, which is where you only need to put 2 values instead of 4, UDim2.fromScale(1, 1). Before I continue, if you need further help understanding UDim2, go visit the [https://create.roblox.com/docs/reference/engine/datatypes/UDim2 Creator documentation page]. Now comes the part where I actually explain how to make a new element. So first to create the element, you need to get the screen from the port. <syntaxhighlight lang="lua" line="1">
    ** <code>local</code> sets the scope of the variable to local. This means that the variable's binding is only valid within its scope block or in scope blocks within it's scope block. Imagine scope blocks as the folders on your computer (but not quite). Say you have a home folder and a documents folder, both with some files inside of them. If you're in the home folder, you can only access the files inside of it. You'll only be able to see the files within the documents folder if you go into it. However, unlike with real folders, if you're in the documents folder in this case you'll also be able to see everything within the home folder. If scope still confuses you, just know that you should always define variables by using <code>local (...) = (...)</code>
    local screen = GetPartFromPort(1, "Screen") --Gets the screen
    *** The other option is setting the scope of a variable to global. To set a variable's scope to global, just don't use <code>local</code> before it. This is equivalent to defining a local variable at the top scope (<code>local a = 3</code> in the above example). Local variables should be preferred whenever possible.
    * <code>do .. end</code> creates a new '''scope block'''. <code>do</code> starts it and <code>end</code> ends it.
    * <code>print(a)</code> prints out the value of a. As <code>a</code> already had its value assigned in a higher scope, <code>a</code> is (also) equal to 3 here.
    * <code>local x = 4</code> ...
    * <code>local a = 5</code> sets <code>a</code> to be equal to 5. This is '''<u>NOT</u>''' the same as assigning <code>a</code> a new value (<code>a = 5</code>). This overrides the other <code>a</code> with a new <code>a</code>; equal to 5: not 3, but only in its local scope.
    * <code>print(x)</code> prints out 4 as this is what x was defined as, at least '''in the current scope'''.
    * <code>print(a)</code> now prints out 5, as <code>a</code> was defined to be 5 '''in this scope.'''
    * <code>print(a)</code>, now outside the scope block, prints out 3 because <code>a</code> is only equal to 5 within that one specific scope block. Outside of it, <code>a</code> refers to the original <code>a</code> and is equal to 3: what it is defined to be in the top scope block.
    * <code>print(x)</code> prints out '''nil. nil''' represents no value - not as in 0, but as in the '''complete absence of anything'''. <code>x</code> is equal to nil for the same reason why printing <code>a</code> before this gave 3: <code>x</code> is only defined to have a value within its scope block; as it wasn't defined in any way outside of it, it lacks one.



    Feel free to play around a little with what you've just learned. Learning by doing is the best way to learn. If anything's been left slightly unclear, try going over everything again once more; perhaps slower. Once you feel you're ready, please take the following quiz to check your comprehension: <quiz display="simple">
    {Which of the following defines <code>a</code> to be equal to the number 4; in the local scope?
    |type="()"}
    - a = 4
    || This defines <code>a</code> globally - not locally (or reassigns a to some other value).
    - do a = 4 end
    || This defines <code>a</code> globally (not locally), and within a scope block.
    + local a = 4
    - local a = "4"
    || This defines <code>a</code> locally, but as "4" (a string), not 4 (a number).

    {Defining variables in the local scope is always preferred
    |type="()"}
    + TRUE
    || Yup! Always defining variables in the local scope is less memory intensive and makes you less prone to mistakes
    - FALSE
    || Always defining variables in the local scope is less memory intensive and makes you less prone to mistakes

    {What will the following code print out? <syntaxhighlight lang="lua" line="1">
    local hello = "Hello world!"
    print(hello)

    </syntaxhighlight>
    </syntaxhighlight>
    |type="()" coef="2"}
    Next we would need to clear any elements that are already on the screen using screen:ClearElements().
    - hello
    <syntaxhighlight lang="lua" line="1">
    || <code>hello</code> is a variable, so what's actually being fed into the print function is its value - "Hello world"
    local screen = GetPartFromPort(1, "Screen") --Gets the screen
    + Hello world!
    screen:ClearElements() --clears the screen of any previous elements
    - "Hello world!"
    || "Hello world" is indeed what is fed into the print function, but not what is printed out
    - 'hello'
    || <code>hello</code> is a variable, so what's actually being fed into the print function is its value - "Hello world"

    {Consider the following code: <syntaxhighlight lang="lua" line="1">
    local b = 2
    local p = 3

    do
    b = 5
    print(p)
    end

    print(b)
    </syntaxhighlight>
    </syntaxhighlight>
    The code will print out:
    Now, to create the element using screen:CreateElement().
    |type="()" coef="2"}
    <syntaxhighlight lang="lua" line="1">
    - 5, then 2
    local screen = GetPartFromPort(1, "Screen") --Gets the screen
    || You seem to have mixed up the variables.
    screen:ClearElements() --clears the screen of any previous elements
    - 2, then 3
    screen:CreateElement("classname", {properties}) -- creates an element with the given name and properties
    || You seem to have mixed up the variables.
    </syntaxhighlight>
    + 3, then 5
    Now, we must add the Classname of element we want to create. I will use TextLabel.
    - 3, then 2
    <syntaxhighlight lang="lua" line="1">
    || Scope isn't relevant here as it's just reassigning the value of a variable - and b is defined in the top scope. To have the code print this out, <code>b = 5</code> would have to be replaced with <code>local b = 5</code> (because when we have that local at the beginning - <b>scope becomes relevant</b>)
    local screen = GetPartFromPort(1, "Screen") --Gets the screen

    screen:ClearElements() --clears the screen of any previous elements
    { Complete the missing lines:<syntaxhighlight lang="lua" line="1">
    screen:CreateElement("TextLabel", {}) -- creates an element with the given name and properties
    local c = 32
    </syntaxhighlight>
    local s = c
    Now, we need to add a few properties.

    <syntaxhighlight lang="lua" line="1">
    do
    local screen = GetPartFromPort(1, "Screen") --Gets the screen
    c = 54
    screen:ClearElements() --clears the screen of any previous elements
    do
    screen:CreateElement("TextLabel", { -- creates an element with the given name and properties
    ...
    Text = "Hi!", --Sets the text to Hi!
    ...
    TextScaled = true -- Automatically scales the text to fit the screen
    ...
    })
    print(s)
    </syntaxhighlight>
    end
    Now, lets use what we learned above, and use UDim2.fromScale to make the size and position.
    end
    <syntaxhighlight lang="lua" line="1">
    local screen = GetPartFromPort(1, "Screen") --Gets the screen
    screen:ClearElements() --clears the screen of any previous elements
    screen:CreateElement("TextLabel", { -- creates an element with the given name and properties
    Text = "Hi!", --Sets the text to Hi!
    TextScaled = true, -- Automatically scales the text to fit the screen
    Size = UDim2.fromScale(1, 1), --Makes the size cover the whole screen
    Position = UDim2.fromScale(0, 0) --sets the position
    })
    </syntaxhighlight>
    Congrats! You made your first [[Screen]] element. A few more notes are:
    *Position is the position of the element in the top left corner
    *when doing scale for position, the top is y=0, the bottom is y=1, the left is x=0, the right is x=1. This confuses some people because positive y is actually down, not up.
    ===Modem===
    <!--If someone knows anything about the post and get requests stuff, PLEASE put it down below-->
    The [[Modem]] allows you to send messages across the entire universe! You could even create a makeshift internet of sorts with it! This being said, it seems like a scary and confusing prospect for new programmers. But the reality is, that it is very simple. There are two main things you need to know to make a messaging system or something like that. First is the SendMessage method. This is very simple. It sends a message across the universe. All you need to put in the method's parameters is the message you with to send, and the [[Modem]] ID you wish to send it on. Here is an example:
    <syntaxhighlight lang="lua" line="1">
    local modem = GetPartFromPort(1, "Modem")--gets the modem object
    modem:SendMessage("Hello WoS", 1) --sends the message "Hello WoS" on the Modem
    </syntaxhighlight>
    ''Well you can send messages, but how do you receive?''
    You receive messages using an event. If you are unfamiliar with events, please read the tutorial above about events. The event name is MessageSent. It fires when a message is received from a modem with the same ID. It only provides a singular parameter, and that is the data that was sent. Here is an example of a modem that picks up messages and writes it to a sign.
    <syntaxhighlight lang="lua" line="1">
    local modem = GetPartFromPort(1, "Modem")--gets the modem object
    local sign = GetPartFromPort(2, "Sign")--gets the sign object
    modem:Connect("MessageSent", function(message)
    sign:Configure({SignText=message})--write the message to a sign
    end)
    </syntaxhighlight>
    </syntaxhighlight>
    If the output of the code was '''32''', then '''54''', then '''24'''.
    There you go! You have just made a simple messaging system. You can expand on this by using [[Keyboard|Keyboards]] to send messages, or use screens to make a nice looking UI.


    |type="{}" coef="4"}
    Another method is the RealPostRequest, it enables you to send post requests to real websites such as google. Here's an example:
    First missing line: { print(s) }
    Second missing line: { print(c)|s=24| s = 24|local s=24|local s = 24 }
    Third missing line: { s=24| s = 24|local s=24|local s = 24|print(c) }
    </quiz>


    - types
    <syntaxhighlight lang="lua" start="1">
    local Modem = GetPartFromPort(1,"Modem")
    local Sign = GetPartFromPort(1,"Sign")


    - numerical operators, numerical operators on variables
    local Payload = JSONEncode({"Data",1,2,3})


    - logical operators, scope
    local Data, Success = Modem:RealPostRequest("http://CustomLinkHere.com",Payload,false,nil,{["Content-Type"]="application/json"})
    if Success then
    Sign:Configure({SignText=Payload})
    end
    </syntaxhighlight>Sadly, the RealGetRequest does not work. So you have to use the post requests.


    - tables, dictionaries
    If you want to use the RealPostRequest for sending data to your computer then you will have to use third party resources. (i.e. website hosting)

    - loops - basic

    - strings - basic operations

    - more operators, operator shenanigans

    - functions (basic. just an introduction;)


    - tasks should be included for each of these. these tasks should be quizzed (use the quiz extension).

    === Computational thinking ===
    - problems, and how they are broken down into programmable steps. just a lot of problems. practice makes perfect

    - small project at the end

    === Coding revisited ===
    - strings 2

    - basic OOP

    - functions/methods 2 (stuff like recursion goes here)

    - more complex collections (stacks, queues, etc. - with implementation details/a preprogrammed script available for these)

    - built in functions (if possible in any way this should be introduced bit by bit through earlier sections)

    - coroutines

    - error handling


    - quizzes after every smaller chunk. more than for learning to code as this is tougher.

    === The Microcontroller ===
    - parts

    - built in microcontroller functions

    - JSON and modems; web requests

    - add a quick little quiz and small project at the end

    === Programming at last ===
    - everything put together and tested with practical projects

    - thorough explanations and solutions should be given for each project. throw in some software engineering stuff here as well.

    === Afterword ===
    - buh bye

    == Parts ==


    == Resources ==
    == Resources ==


    * There is currently one player-made wiki, [https://github.com/iimurpyh/pilot-lua/wiki murpyh's]
    * [https://github.com/iimurpyh/pilot-lua/wiki iiMurpyh's pilot.lua wiki] - Documents all the special objects and functions that microcontrollers can use.
    * Some information on parts can be found at [https://wos.mawesome4ever.com mawesome's part list site], though some information is inaccurate or not displayed there
    * [https://wos.mawesome4ever.com/ Mawesome4ever's part list] | Note: May not show all information associated with a part.
    ** [[Module:PartJSON]] - Extracted JSON used for the above website. Displays everything, but doesn't provide you with a nice GUI
    *[https://create.roblox.com/docs/ Roblox creator documentation] contains a load of info on rbx.lua. If you are unfamiliar with lua, or coding in general, it is highly recommended to learn rbx.lua first.


    * https://create.roblox.com/docs/ - Roblox's documentation for rbx.lua.
    ==Programming Examples ==

    * [https://www.lua.org/manual/5.1/manual.html Lua 5.1 Reference Manual] - Provides a tutorial to get started with plain lua, as well as its built-in functions.

    == Examples ==
    [[File:FlappyBirdGif.gif|thumb|A flappy bird arcade machine, made by iiMurp|302x302px|alt=|center]]
    [[Category:Tutorials]]
    [[Category:Tutorials]]
    [[Category:Mechanics]]
    [[Category:Mechanics]]

    Latest revision as of 13:10, 27 June 2024

    Waste Of Space features a fully fleshed out programming system, allowing players to program Microcontrollers using a sandboxed subset of luau (which is itself a superset of lua) called Pilot.lua. Programming allows players to easily and efficiently implement complex logic and automation into their builds by writing code.


    This article serves as an introduction to programming in-game. It provides a handy yet detailed tutorial to get you started, a list of commonplace and useful programming-related parts to consider, some useful resources to help you with programming successfully, and at the end; a few inspiring examples. The talk page of this article hosts a community board to share useful and unique projects/code.

    Tutorial[edit | hide all | hide | edit source]

    Foreword[edit | hide | edit source]

    Microcontrollers are perhaps one of the most powerful tools waste of space provides you with. Knowing how to use them is paramount if you want to implement any kind of advanced automation or autonomy into your builds. This is not to say they are only for drones and factories, however. Programming expands your already large range of possibilities to a nearly boundless one.

    This tutorial will provide you with a brief guide on programming and coding in-game. Namely; programming and coding are not the same, though they are often confused as such. Coding is just writing instructions to the computer (code), while programming is the engineering of software. A programmer creates algorithms and solves problems, and then codes them to create a fully-fledged software solution.

    Please do not feel intimidated by this, as if it something out of reach to you. Though serious programming is not everyone's cup of tea, you do not need to be an AAA++ software engineer with 15 years of experience to code up your little idea. Everyone needs to start somewhere, and Waste of Space is hardly a source of difficult problems. Perhaps, if after reading this tutorial you find out that you like programming, you may even become one of those pros one day. Even in the worst case though, you will have learned an increasingly relevant skill and will have developed your logical thinking. If you haven't already gotten the gist, this guide is aimed at newcomers to programming.

    If you aren't sure whether or not to commit to learning programming, perhaps a well-known example (it's on the game's thumbnail!) of programming in waste of space can tip you over to either side.

    A video of the space arcade by iiMurpyh

    Learning to code[edit | hide | edit source]

    Getting started[edit | hide | edit source]

    While you may be tempted to start writing code right away you'll need to set up an environment for this first. This is what's called a development environment.

    As you'll just be writing some basic luau (a dialect of lua) throughout this tutorial, this will consist of just a text editor (and something to run your code with). A text editor can be as simple as just a notepad program so you have somewhere to jot down your code, or can be more complex and specialised for writing code. These types of text editors (code editors) often offer useful features such as automatic code completion and syntax highlighting (it colour-codes smaller bits of code, conveying their meaning or data type). A few suggestions for a code editor are listed below, complete with pros, cons, images, and links.

    • (the list)


    Once you've set up a text editor, there's one more thing to do before you can start coding: setting up a runtime environment. As lua is a scripting language - a programming language in which the instructions to the computer are stored as source code (the code as you wrote it, in textual format) - it must be translated to the computer in real time because computers can only understand binary (0s and 1s). This is what a runtime environment is for (in this case); it allows for the execution of scripts (source code) by translating them to machine code (instructions understandable to the computer) on the go.

    In this case, you'll need something that can run luau code. This guide recommends that you use Roblox Studio for these purposes. Using Studio to test your code isn't exactly the best, but studio is approachable for a beginner such as yourself. Besides, there aren't really any other options anyways. Later on, you'll switch from using Studio to testing code on Microcontrollers in-game.


    To set up Studio for testing your code, do the following:

    • Install Roblox Studio if necessary.
      • Go to https://create.roblox.com/
      • Click the 'Studio' button in the left side menu (under 'Quick links': at the bottom of the list). Alternatively, if you are not logged in, click the 'Start creating' button.
      • Click the 'Download' button
      • Install Studio by running the newly downloaded file
    • Open Roblox studio and under the 'New' tab click on the 'Baseplate' template
    • Open the file tab (Top left) and save this new experience (click 'Save to Roblox')
    • Close all of the windows except the 'Output' window (if present) and the 'Explorer' window.
      • If you don't have an output window, click the 'View' tab at the top of your screen and then click the 'Output' button to turn the window on
    • Resize the output window to be a bit bigger than by default if you have the screen space for it.
    • In the Explorer, hover over the 'ServerScriptService' and click the plus (+) icon beside it. Then, add a script to it (a regular script: make sure it's not a LocalScript or ModuleScript).


    If you've done everything correctly, you should now be in the built-in script editor. You should see the following:

    print("Hello world!")
    

    Go ahead and run this by clicking play at the top of your screen. You'll do this from now anytime you need to run your code. Unless you've chosen the built-in studio editor as your text editor of choice, you'll have to copy and paste the code you write into this script. Make sure to first select all of the text and only then paste your code so as to replace the existing contents.

    Once everything's loaded, you should see the following in the output window:

    Hello world!
    

    This means everything's working! You're now ready to start coding. If this isn't the case, double check you followed all of the instructions to the letter.

    What just ran is the print function - one of the simplest functions there is. You'll learn more about what a function is later, but for now know that it's basically a black box that does something with whatever you put between its parentheses - which are like the function's mouth into which you feed it values. In this case, the value you're feeding it is some text - a string (again, you'll learn more about these later; for now remember the name and that you create one by putting some text in between quotation marks, e.g. "text"). What the print function does is that it prints out (displays in the output) the text you gave it. In this case - Hello world!


    When you started reading your language for the first time, you needed to learn in what order to read the words before you. Code is read from left to right, line by line.

    The code before you currently only occupies a single line. Copy it, press enter, then paste it.

    You should now see the following two lines of code:

    print("Hello world!")
    print("Hello world!")
    


    Next, modify the code on the second line so it prints out Hi World!:

    print("Hello world!")
    print("Hi world!")
    

    Run this code. The output should be Hello World! and Hi World!; one after the other.

    This should give you a good idea of how code flows if you haven't already figured it out.

    You're now ready to move on onto the first real lesson: variables.

    Variables, scope[edit | hide | edit source]

    Say you want to store some information for future use; let's say that your friend later needs it so they can do something and you can't tell them it directly. Assume that you decide to write that information on a slip of paper.

    Now imagine that you also have an almost limitless number of really small boxes at your disposal. This is the computer's memory in this analogy.

    You can't just place your slip of paper anywhere as it'd get lost, so you decide to place your slip of paper into the nearest currently unused box.

    But how can your friend know which of those boxes to check for the slip of paper?

    The solution is to also label the box into which you place the slip of paper with a name specific to it: the entire box including its label is what's called a variable: a symbolic name (what you labeled the box with) associated with a storage location (the actual box itself).

    The information inside the box is the value of the variable. This value can be whatever, and can change with time.

    It's key to note that the box in this analogy is opaque. You can only know what's inside the box if you open it.


    Let's see how that translates into code; it turns out it's really simple.

    Delete any code you have in the script you're using to test your code, then add the following:

    local x = 3
    print(x) --prints out 3
    

    Let's break this down line by line:

    • local x = 3 defines some variable x to be equal to 3
      • x is the name of the variable
      • = assigns the value of the variable to be whatever is on the other side of it
      • 3 is the value you're assigning to the variable. In this case, it is a number.
    • print(x) prints the value of the variable
    • --prints out 3 is a comment - an annotation to source code. It's always at the end of a line and is created by using two dashes (-). It is ignored when running the code.


    Try playing around a bit with this code by changing the value of the variable: perhaps by changing it to another number, or perhaps to a string ("Hello world!", for example).

    You may notice that what local does wasn't defined. local sets the scope of a variable. Scope (or visibility) is a property of variables which defines where (that is in which scope blocks) their name binding is valid (so, if a is equal to 1, where a being equal to 1 is the case). Let's look at an example to make this clearer, and break it down line by line as before:

    local a = 3
    
    do
     print(a) --prints out 3
     local x = 4
     local a = 5
     print(x) -- 4
     print(a) -- 5
    end
    
    print(a) -- 3
    print(x) -- nil
    
    • local a = 3 sets a to be equal to 3, as you should know by now.
      • local sets the scope of the variable to local. This means that the variable's binding is only valid within its scope block or in scope blocks within it's scope block. Imagine scope blocks as the folders on your computer (but not quite). Say you have a home folder and a documents folder, both with some files inside of them. If you're in the home folder, you can only access the files inside of it. You'll only be able to see the files within the documents folder if you go into it. However, unlike with real folders, if you're in the documents folder in this case you'll also be able to see everything within the home folder. If scope still confuses you, just know that you should always define variables by using local (...) = (...)
        • The other option is setting the scope of a variable to global. To set a variable's scope to global, just don't use local before it. This is equivalent to defining a local variable at the top scope (local a = 3 in the above example). Local variables should be preferred whenever possible.
    • do .. end creates a new scope block. do starts it and end ends it.
    • print(a) prints out the value of a. As a already had its value assigned in a higher scope, a is (also) equal to 3 here.
    • local x = 4 ...
    • local a = 5 sets a to be equal to 5. This is NOT the same as assigning a a new value (a = 5). This overrides the other a with a new a; equal to 5: not 3, but only in its local scope.
    • print(x) prints out 4 as this is what x was defined as, at least in the current scope.
    • print(a) now prints out 5, as a was defined to be 5 in this scope.
    • print(a), now outside the scope block, prints out 3 because a is only equal to 5 within that one specific scope block. Outside of it, a refers to the original a and is equal to 3: what it is defined to be in the top scope block.
    • print(x) prints out nil. nil represents no value - not as in 0, but as in the complete absence of anything. x is equal to nil for the same reason why printing a before this gave 3: x is only defined to have a value within its scope block; as it wasn't defined in any way outside of it, it lacks one.


    Feel free to play around a little with what you've just learned. Learning by doing is the best way to learn. If anything's been left slightly unclear, try going over everything again once more; perhaps slower. Once you feel you're ready, please take the following quiz to check your comprehension:

    1 Which of the following defines a to be equal to the number 4; in the local scope?

    a = 4
    do a = 4 end
    local a = 4
    local a = "4"

    2 Defining variables in the local scope is always preferred

    TRUE
    FALSE

    3

    What will the following code print out?
    local hello = "Hello world!"
    print(hello)
    

    hello
    Hello world!
    "Hello world!"
    'hello'

    4

    Consider the following code:
    local b = 2
    local p = 3
    
    do
      b = 5
      print(p)
    end
    
    print(b)
    

    The code will print out:

    5, then 2
    2, then 3
    3, then 5
    3, then 2

    5

    Complete the missing lines:
    local c = 32
    local s = c
    
    do
      c = 54
      do
        ...
        ...
        ...
        print(s)
      end
    end
    

    If the output of the code was 32, then 54, then 24.

    First missing line:

    Second missing line:

    Third missing line:


    - types

    - numerical operators, numerical operators on variables

    - logical operators, scope

    - tables, dictionaries

    - loops - basic

    - strings - basic operations

    - more operators, operator shenanigans

    - functions (basic. just an introduction;)


    - tasks should be included for each of these. these tasks should be quizzed (use the quiz extension).

    Computational thinking[edit | hide | edit source]

    - problems, and how they are broken down into programmable steps. just a lot of problems. practice makes perfect

    - small project at the end

    Coding revisited[edit | hide | edit source]

    - strings 2

    - basic OOP

    - functions/methods 2 (stuff like recursion goes here)

    - more complex collections (stacks, queues, etc. - with implementation details/a preprogrammed script available for these)

    - built in functions (if possible in any way this should be introduced bit by bit through earlier sections)

    - coroutines

    - error handling


    - quizzes after every smaller chunk. more than for learning to code as this is tougher.

    The Microcontroller[edit | hide | edit source]

    - parts

    - built in microcontroller functions

    - JSON and modems; web requests

    - add a quick little quiz and small project at the end

    Programming at last[edit | hide | edit source]

    - everything put together and tested with practical projects

    - thorough explanations and solutions should be given for each project. throw in some software engineering stuff here as well.

    Afterword[edit | hide | edit source]

    - buh bye

    Parts[edit | hide | edit source]

    Resources[edit | hide | edit source]

    Examples[edit | hide | edit source]

    A flappy bird arcade machine, made by iiMurp
    Cookies help us deliver our services. By using our services, you agree to our use of cookies.

    Recent changes

  • Axenori • 1 day ago
  • Voivsone • 1 day ago
  • Axenori • 2 days ago
  • Axenori • 2 days ago
  • Cookies help us deliver our services. By using our services, you agree to our use of cookies.