Tutorial:Creating A Furniture Placement System

''This post was originally written by on Scripting Helpers. The original tutorial can be found here.''

One of the most common requests I get for blog post topics are for a decoration placement system that saves. I’ve shied away from this topic in the past as there is no singular “correct” way to do it. That being said, I think it's a good exercise for all game devs to go through and will potentially place a role in a future blog post I plan to write.

In addition to change things up, I’ll also take the time to explain and use Object Oriented Programming (OOP) as it’s not only my own preferred style, but also something Roblox uses for their core scripts.

Alright, let's get into it!

Object Oriented Programming
OOP is all about writing classes which in this context is a very fancy synonym for the word “blueprint”. We can then use these blueprints to create objects that have certain properties and methods.

If some of these words sound familiar to you, well, that’s because they are. The objects that you interact with such as s, s, s, and so forth are by design of the OOP paradigm. These objects have properties and methods that when combined define how they interact with our game.

Properties are used to define “characteristics” of an object. For example, a Part has a property called Size which as its name suggests defines how large or small the object is. In turn these properties often play a role in the behaviour and actions associated with said object which is defined by methods. For instance, the method :GetMass returns the mass of the part which among other things varies with size. Thus, we can see an example of a clear connection here between methods and properties.

Now that we have some of the terminology down and an example I’d like to further discuss the distinction between classes and objects. A class defines the properties and methods that an object will have. For example, we know all parts are going to have a position property, so we define it in our class. The actual value of the position property will vary between individual objects, but the overarching concept of a part we know will have a property called Position with a Vector3 as its value. In a similar sense when writing the methods of our class we may not know the literal values for each property, but since we know that those values will exist, we can treat them almost like function parameters.

The difference between OOP and a more functional approach for the same task can be seen in the code sample below.

Ignoring that fact that the method is built-in and thus didn’t have to be defined, the only difference was that in the functional approach we had to plug in the part’s properties as arguments manually. In the method’s case we didn’t have to plug in any arguments because Lua knew we were calling a method on a specific object and thus could grab the properties needed directly from it. A method is just the name we give to functions that are applied to a specific object. An example of what this might look like would be this:

You might note that the above code is referencing something called self and understandably this seems like it’s coming out of thin air. In Lua, when you call a method the first argument passed is ALWAYS the object the method was called on. When defining a method with the syntax form  the parameter that will represent the object is forcibly given the name self and shouldn’t be defined in the brackets like any other extra parameters. So, if I ran  then the argument that would replace self would be somePart.

As a side note, either due to personal preference or a familiarity with other languages that use another keyword other than self such as this, some programmers may wonder if there’s a way to use a different parameter name. This is possible, and the equivalent code would be the following:

It would be my personal recommendation however that you do not do this as it can be confusing to others from a readability perspective.

Alright, so how do we write a class? The last piece of the puzzle is something called a constructor. A constructor creates an object from the class and returns it back to us with a set of filled in properties. A very common constructor that I think (?) all of the built-in classes have is .new but other examples might be Vector3.FromNormalId or CFrame.Angles. A class can have multiple constructors and they can be named just about anything. Sometimes when we write these constructors, they have parameters that help us fill in properties and other times they don’t. It’s completely up to you as the programmer and dependent on what the class if for.

Let’s look at how the staff at Roblox might write a constructor in Lua and we’ll break down the parts from there. Here’s an example of how one might copy the Vector3 class constructor.

To some of you this might already make perfect sense and to some of you it may not. The key difference between those who understand and those who do not should be familiarity with metatables. This is a big topic in of itself, but luckily, we only really need to understand one aspect of the __index metamethod to understand this code.

The best “dumbed down” explanation I’ve heard of meta-tables is “events, but for tables” and this is particularly applicable to the __index metamethod. The __index metamethod is “fired” when an non-existing key in a the table is indexed meaning read, not written. Now typically metamethods will "fire" a function and the __index metamethod can also work in this way. However, if instead of setting a function to the __index metamethod you set another table then when the __index metamethod is “fired” it treats the process as such:


 * Table was indexed with key => Does the key correspond with a nil value in the table?
 * Yes => Does the key correspond with a non-nil value in the table in the __index metamethod?
 * Yes => Return that value
 * No => Return nil

This is quite useful to us at it allows us to set default values to keys and not have to constantly redefine and repeat ourselves when making copies. In the case of the above code we use this such that self, the table we return from our constructor, will have access to all the constructors and methods we attach to the Vector3 table.

Say we add the following method to the above code then create an object and run the method on it: The process is treated as such: Thus the :Magnitude method is called on v which has actual values for properties x, y, and z and as such we get the corresponding result.
 * v was indexed with Magnitude key => Does the key correspond to a nil value in v?
 * Yes => Does the key correspond with a non-nil value in Vector3?
 * Yes => Return that value (the magnitude method)

There’s a lot more to be said about OOP and what I have explained has barely scratched the surface. Some other languages force you to use OOP and have a much richer set of features compared to Lua. If you want to further explore OOP in Lua I recommend you read the following post on the devforums.

All that being said, the question I still have not answered is “Why use OOP?”. My answer: I personally enjoy it as it forces me to organize my code in a modular and reusable way that can be combined together for a variety of complex tasks. That being said there's positives and negatives for everything so use what works for you.