General structure in this - good or bad?

recently started using Rojo, so Copilot can help me with a lot of complicated issues. but it kind of struggles with its organization (if that isn’t a problem for you then GO AWAY :enraged_face:).

i want to know this is readable to the normal eye at all. if you want any additional context then just let me know!

---------------------------------
-- variables
---------------------------------

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage:FindFirstChild("events")
;

---------------------------------
-- events
---------------------------------

local scoreEvent = Events:FindFirstChild("boardChange")
local currentScores = {}
setmetatable(currentScores, {__index = function(t, k) return rawget(t, k, 0) or 0 end})
-- if theres no team, try getting its value. otherwise return 0

local connections = {}
local values = script.Parent.Runtime.Values

local function updateBoard(updateNumber:number)
    if updateNumber == 1 then
        local homeScore = values:FindFirstChild("HomeScore").Value
        local awayScore = values:FindFirstChild("AwayScore").Value
        
        table.insert(currentScores, 1, homeScore.Value.Changed:Connect(function()
            currentScores["Home"] = homeScore.Value
        end))
        
        table.insert(currentScores, 1, awayScore.Value.Changed:Connect(function()
             currentScores["Away"] = awayScore.Value
        end))
        
        if currentScores["Home"] ~= homeScore.Value or currentScores["Away"] ~= awayScore.Value then 
            -- if scores arent the same, tell client to update
            scoreEvent:FireAllClients(currentScores)
        end
    end
end

keep in mind a lot of the stuff might just not work or has some logical errors like the setmetatable(), but i just wanna know if the structure is solid since some of the scripts have the same structure.

1 Like

from a brief glance your code seems fine; if your ever confused on naming stuff you could def read the “best practices” section in the variables documentation. imo my only changes would be switching how you sort your variables at the top

commenting ex

so instead of comments like

---------------------------------
-- variables
---------------------------------

i prefer to do:

-- Variables -- 
-- code here

-- Events --
-- code here

i’d also move the setmetatable line down/simplify your commenting; keep your variables seperated from where your actual code starts, though this is my personal preference

my version
-- Services --
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage:FindFirstChild("events")

-- Events --
local scoreEvent = Events:FindFirstChild("boardChange")
local currentScores = {}

-- Values --
local connections = {}
local values = script.Parent.Runtime.Values


-- set up current scores --
setmetatable(currentScores, {__index = function(t, k) return rawget(t, k, 0) or 0 end})

-- update scoreboard --
local function updateBoard(updateNumber:number)
	if updateNumber == 1 then
		local homeScore = values:FindFirstChild("HomeScore").Value
		local awayScore = values:FindFirstChild("AwayScore").Value

		table.insert(currentScores, 1, homeScore.Value.Changed:Connect(function()
			currentScores["Home"] = homeScore.Value
		end))

		table.insert(currentScores, 1, awayScore.Value.Changed:Connect(function()
			currentScores["Away"] = awayScore.Value
		end))

		if currentScores["Home"] ~= homeScore.Value or currentScores["Away"] ~= awayScore.Value then 
			-- if scores arent the same, tell client to update
			scoreEvent:FireAllClients(currentScores)
		end
	end
end

just note that theres def different ways of doing this, so some people may or may not agree, but this is simply my take on what you’ve written so far

2 Likes

Roughly, this is pretty similar to how a lot of my own code is structured. Generally divided into sections, and with pretty big comments to provide some delineation. “Variables”, “Events”, “Module”, “Initialization”, “Connections”, etc.

Oh, don’t worry.
There is a problem in pretty much everything wrong with this code

  1. You added bloatware named metatables
  2. You use table.insert for a static size; just use 2 variables to grab a reference. LOL, LMAO, even.
  3. You use Value instances in big 2025…

the code looks fine, ignore everyone the guy saying “bloatware metatable” because from the looks of it this won’t be called every 1 miliescond so the performance hit really isn’t that bad. it’s also a neat little idea, not many people even know that metatables can do that and they just end up manually checking every time its indexed. the only thing I’d change is the value approach, you can just use attributes since they are like really cheap to lookup and you dont have to do .Value every time

speaking of values,

you can see the issues, you set awayScore equal to the actual value, then try to run.Value on it. gets annoying to keep track of

2 Likes

Sorry, you can’t dismiss anything without providing facts that are simply illogical.

It’s bad.
Any attempt to justify something hurtful is bad and illogical
It’s straight-up evil normalizing something hurtful since it will very quickly reach its extreme form, and also it adds more indirections for literally no gain. You do bad for the sake of bad; it’s evil by definition.

In that case?
No, you don’t.
Indirection for the sake of indirection instead keep data on the script’s stack since it’s literally static.
You don’t know what you are talking about.

The way you make it out makes it seem like the code will crash and blow up because they use metatables.

I want you to bring me explicit proof on the major performance hit (noticeable) of using metatables in a way like this, as I have clearly seen you like to think you are some ‘engine tinkerer’ based off what I have seen from past posts. I understand micro optimization is a good skill, but this isn’t micro optimization it’s just being insufferable and maybe, perhaps, just perchance, you making up for something.

Shaving off nanoseconds is not what luau is made for - you are working in a sandboxed game engine, and these are things I presume you understand. If you want extreme high performance I’m not saying don’t go for it, but you shouldn’t be so blunt and dismissive of someone (without trying to help) because you are fixated on what is wrong with the engine and how ‘unoptimized’ it is

1 Like

If you make a prompt for ChatGPT, at least ask him to explain buzzwords.
Your reply is clearly made by ChatGPT carelessly about meaning.
You went super defensive and started attacking me rather than attempting to prove a point.
Even though you literally can’t prove a point because it goes against logic, it’s the equivalent of doublespeak from 1984.


How exactly does it contradict the optimization mindset?
The fact that the code is being interpreted does not justify refusal to optimize.

TL;DR:

  1. You questioning my skills without proving anything except “i felt like you don’t know anything”;
  2. You have contradiction in the message:
  1. ???

All of this aside, none of your points actually address the simple fact that metatables add overhead for no gain here. That’s the whole debate.

Do you see WHY hes using it? Also, I wrote my previous message myself but idk why you think its ai lol.

The whole idea is about organization, and overhead, oh nooo an extra 4 planck times per call alongside 0.2kb attached to the table. Do you even realize this? If he didn’t attach it to __index to return 0 if it was nil, he’d need to do it verbose every time he wanted to fetch it. (Though the code is skeptical)

Also, do you even know what indirection is? The example the guy showed isn’t indirection, firstly because the table acts the same, secondly because it only treats as a fallback: which again, let’s say he wanted that functionality to return a default score value without using metatables. That would mean more if not x then x = y end every time he’d potentially update the code.

And also, don’t skirt around the question: where is your proof of how bad metatables are?

1 Like

See you prove my point, you know nothing about how hardware operates

Here’s a quiz,

  1. Define indirection
  2. Show me the cost penalty of an __index call
  3. Explain your answer

I’ll see tomorrow if it is worth my time to respond. Thanks!:grin:

1 Like

I’m not taking quizzes from someone who thinks 0.2 KB exists.

1 Like

i dont see how removing a clearly necessary functionality which prevents it from becoming incredibly hard to read would make this bloatware. if you could provide any source to shave off a millisecond off of a board scoring system then i would be happy to change my code, otherwise i’ll keep it the same for now :smiley: i will definitely change the value instance though i admit that was a bad way of doing this

Benchmark it.
My own benchmark says that __index lookup consumes x2 time of a regular lookup.

That’s not what the word necessary means.

i dont get why you shoved the definition of “necessary” to a native english speaker but thanks for letting me know that i used it correctly. the lack of thought in that is quite astounding but you are probably not a native english speaker.

moving off of that, i’m actually not going to listen to you and not change my code because it is literally just a simple setmetatable to keep track of scores, but you provide a link for anti-abstraction. sorry to burst your bubble but this one line doesn’t automatically ruin the entire script. also, i’m not going to make micro optimizations to code which doesn’t even run half the time. machines don’t like indecision, and my main focus wasn’t performance.

what do both of us really get from arguing from this? i think that we should just settle our differences and you should put some more thought in your responses next time.

No stress man. If you’re happy optimizing for comfort instead of performance, that’s your speed. I’ll keep optimizing for results.

1 Like
  1. The fact you need a calculator to divide a number by 5 is kind of sad.
  2. KB is an ambiguous term. KiB always refers to 1024 bytes, whereas KB can mean both. The JEDEC Memory Standards use the term kilobyte to refer to 1024 bytes, while the IEC uses it to refer to 1000 bytes instead.
  1. That was for visualization purposes.
  2. In real-world systems, KB is almost always treated as 1024 bytes; the 1000-byte definition is artifact that mostly exists to confuse users, not reflect practice.
    I really hate consumerization of technical terms.
1 Like

“Kilo-” as a prefix to indicate multiplying by 1000 goes back to 1795.
“Kilo-” as a prefix to indicate multiplying by 1024 was used because it’s “close enough”.
Why would 1000 be confusing when most people are used to kilo meaning 1000. And no yarik, even in real-world systems it’s inconsistent. That’s why when you buy a 500GB hard drive, it will only show up as ~465GB on Windows.
Ether way, this is standardized.
https://ipfs.io/ipfs/bafk2bzacebjcrx4wxse6zdwrbcnlvdwekww7ohck4wd3q4yqimkfxixllimt6
https://en.wikipedia.org/wiki/IEEE_1541
https://en.wikipedia.org/wiki/Kilo-
https://en.wikipedia.org/wiki/Kilobyte

I’m sorry but everyone with a surface level technology expertise knows yarik is right

2 Likes