Assigning Custom Values to Instances

The purpose I want to use the metatables for is dynamic map generation, I’m creating parts, and assigning parts (generations). If it is still confusing, I am trying to create a Data Structure or Data “Tree” of values. If you are familiar with linked list or binary trees, it is similar to that.
image
The parts are only connected to one or two other data(s) (With the exception of the first Generation of parts.).

What I am doing currently is saving those parts to a table;

local structs = {part1, part2, part3, etc...} -- Structures

then setting the “Generation” of those parts as they are created.

local structs = {part1, part2, part3, etc...} -- Structures
local structsmt = {"GenerationA", "GenerationB", "GenerationC", etc...}
setmetatable(structs, structsmt)

After the generation is saved, the parts will only be allowed to flow in certain directions. I want to grasp the generation name from a metatable, and if the generation name meets the requirements, proceed to establish a connection.


This is a copy of what I have told @starmaq who has given a lovely community tutorial on how metatables work. He explained to me that metatables might not be the way to go for my purpose. If metatables aren’t the right way, what is?

This topic seems to have a promising answer, but I would like some clairification on how it works and how I can turn it into something for me to use.


Keep in mind I’m trying to keep the lines of code as minimal as possible.

Anything Helps!

2 Likes

I think this is a little different than what you are trying, but could you not just do something like

local structs = {part1 = "GenerationA", part2 = "GenerationB"}

if structs[part1] == "GenerationA" then
    --
end

Your example is highly abstract, so expect highly abstract answers to your problem. I’ve got a CS degree and I can’t figure out what you’re trying to create or how. If you’re adding state, behavior or identity to some Roblox object, you probably should use an object-oriented pattern here. Consider this class:

local Node = {}
Node.__index = Node

function Node.new(part)
    local self = setmetatable({
        part = part;
        children = {};
        -- Add other properties of nodes here, for example:
        --visited = false;
        --edgeCount = 0;
    }, Node)
    return Node
end

function Node:addChild(node)
     self.children[node] = true
end

(Disclaimer: you probably want to add a destructor function to this class, which properly tears down the object)

I wrote a multi-part, easy to follow tutorial for object-oriented programming on my website. If you’re comfortable with the idea of a metatable, then this is probably something you’ll benefit from.

Whatever you end up picking, I suggest code-golfing the complexity down, rather than code-golfing your line count down :slight_smile:

2 Likes

I’m not sure what you’re trying to do but you could just nestle metatables within metatables like this:

local node = {}
local node_mt = {}

local function ClearNodesBelow(node)
	node._Instance:Destroy()
	for index, child in pairs(node._Children) do
		child._Instance:Destroy()
		ClearNodesBelow(child)
	end
	node._Children = nil
end

node_mt.__index = function(t, index)
	if t._Instance then
		if typeof(t._Instance[index]) == "function" then
			if index == "Destroy" then
				return function()
					t._Instance:Destroy()
					ClearNodesBelow(t)
				end
			end
			return function(...)
				local args = {...}
				return t._Instance:(unpack(args))
			end
		end
	end
	if not table.find(node._Children, index) then
		return t._Instance and t._Instance[index] or "No instance assigned"
	end
	return node._Children[index]
end

function node.new(part)
	local meta = setmetatable(node, node_mt)
	meta._Instance = part
	meta._Children = {}
	return meta
end

function node:AddNode(childNode)
	table.insert(self._Children, childNode)
	return self._Children
end

function node:GetNodes()
	return self._Children
end

function node:Destroy()
	t._Instance:Destroy()
	ClearNodesBelow(t)
end

-- Usage

local partRoot = Instance.new("part")

local root = node.new(partRoot)

-- Making new nodes

local part1 = Instance.new("part") do
	part1.Name = "Part1"
end

part1 = node.new(part1)

root:AddNode(part1)
1 Like

I’ll give it a try, most likely tomorrow as I am beginning to get quite tired. Yes I agree it is an abstract example, but it’s the closest thing I can relate to what I want to achieve.

Thank you!

1 Like

I like your solution as well, but as I said in the last reply, I’m getting tired. I’ll be sure to try both of them!