Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

Is my Lua Table changing values on me?

Asked by
Validark 1580 Snack Break Moderation Voter
8 years ago

I was working on a script to be able to call a module to create a Model (like a building or something) that is saved as a table in the Module.

local module = {}

function _Create(data) --Creates an object from a Table. Originally by Merely
    local obj
    if type(data[1]) == "string" then --first value in the table is always ClassName
        obj = Instance.new(data[1])
    else --Not ever used for my purposes (I believe)
        obj = data[1]
    end
    for k, v in pairs(data) do
        if k ~= 1 then --First Value is the ClassName
            if type(k) == "number" then --The Create functions don't have a named index
                v.Parent = obj --Whatever the function creates has a parent of obj
            else
                obj[k] = v --obj["Material"] = "Neon"
            end
        end
    end
    return obj
end

function module:Create(object) --What you can call the module with
    _Create(object)
end

module.Model1 = {"Model",
    Parent = game.Workspace,
    Name = "Model1",
        _Create({
            "Part",
            Name = "Brick1",
            Position = Vector3.new(0,0,0),
            Anchored = true,
            CanCollide = true,
            BottomSurface = "Smooth",
            TopSurface = "Smooth",
            BrickColor = BrickColor.new("Lime green"),
            Material = "Neon"}),

        _Create({
            "Part",
            Name = "Brick2",
            Anchored = true,
            CanCollide = true,
            BottomSurface = "Smooth",
            Position = Vector3.new(10,10,10),
            TopSurface = "Smooth",
            BrickColor = BrickColor.new("Earth green"),
            Material = "Neon"
              })
}

return module

I then call it in a different test script with:

local Module = require(game:GetService("ServerScriptService").CreatorModule)

local M1 = Module:Create(Module.Model1)
wait(1)
local M2 = Module:Create(Module.Model1)
wait(1)
local M3 = Module:Create(Module.Model1)

What happens is, the script creates the first Model (a Model in the Workspace with two parts named Brick1 and Brick2 inside). Then it waits 1 second, then creates another Model, but without the parts inside it. Then waits and creates another model (correctly named), but without parts inside it again.

I believe the problem has something to do with this part of the script:

if type(k) == "number" then --The Create functions don't have a named index
    v.Parent = obj --Whatever the function creates has a parent of obj

Anything you can think of that might be the problem is greatly appreciated.

1 answer

Log in to vote
2
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
8 years ago

The way this module is set up doesn't make any sense:

module:Create doesn't return any object.

That means the feature of creating children is wasted in _Create, since only the module definition can take advantage of it.

You should instead make it return a value. At the same time, you shouldn't construct children using _Create at all -- you should use the same table format that you're using, and let _Create take care of that.

There's no real reason at all to make module:Create and _Create be different.

That might look something like this:

function module:Create(description)
    local instance = Instance.new(description[1])
    for i = 2, #description do
        local child = module:Create(description[i])
        child.Parent = instance
    end
    for key, value in pairs(description) do
        if type(key) == "string" then
            instance[key] = value
        end
    end
    return instance
end

Using it would then look like this:

templateModel = {
    "Model";
    { "Part";
        Name = "Brick1",
        Anchored = true,
        -- etc
    },
    { "Part",
        Name = "Brick2",
        Anchored = true,
        -- etc
    },
    Name = "MyModel",
}

local m1 = module:Create(templateModel)
wait(1)
local m2 = module:Create(templateModel)
wait(2)
local m3 = module:Create(templateModel)

This template can be safely reused because nothing about it is actually used -- all information is copied.

0
It makes me laugh that I stared at this code that was complex-looking to me and you rewrote the function and it's like reading normal English almost. One question though, if I had put a return value on "module:Create," would it have worked the same (just with unnecessary amounts of work)? Validark 1580 — 8y
0
It would have made more sense to return from `module:Create`, but you still wouldn't have been able to make a template that has children -- because you'd refer to the *same* object that was returned, and what you really want is a new object (with the same properties) each time BlueTaslem 18071 — 8y
Ad

Answer this question