Before I continue, let me just say one thing: There is no right way to do anything. What works for someone else may not work for you.
Honestly, I don’t do a lot of planning in terms of the structure. Usually I just arbitrarily come up with a structure that is within or close to my comfort zone and just go with that. When my writing my first bits of code is when I come up with the core conventions; things such as variable naming, script and object organisation, etc. It’s kind of intuitive.
But of course it has its problems. For example, sometimes I do need to change the way things work. Often I am designing the game as I script it, so requirements for things change also. However, doing these changes usually doesn’t take too long if you have stuff that is already working, and your biggest enemies are bugs that may take a while to solve. Either way, this can often interrupt the game’s schedule.
But that also has its positives. It usually means I’m flexible as a developer and can redesign my game when I find an issue with its design. I’m not locked into a specific schedule or structure and can adapt. That’s what I like doing, and admittedly I haven’t tried forcing myself into a rigid, well-planned project before.
I don’t actually document my code that much; usually everything is organised and named in such a way that documentation isn’t required for the most part. The only things I need to document are the rare, weird bits of code I need to run to fix some logic-related bug or whatever. This code feel dense and overwhel lack of documentation (lack of whitespace, really) often makes the ‘bigger picture’ of theming but that feeling is quickly subdued when you actually read the code.
Fairly extreme example of my code
local CreateButton = function(ItemId, ItemData, ItemAmount, Order, Container)
local ItemType = ItemData.Type
local ItemButton = ItemTemplate:Clone() do
ItemButton.LayoutOrder = Order
ItemButton.Name = ItemId.."Button"
ItemButton.Parent = Container
local StackLabel = ItemButton.StackLabel
StackLabel.Visible = ItemAmount > 1
StackLabel.Text = "x" ..ItemAmount
local ItemViewport do
local ViewportItem = ItemsModule:Get(ItemId)
ItemViewport = ViewportManager.new(ItemButton.ItemViewport)
ItemViewport:SetItem(ViewportItem, ItemData.ViewportOffset)
end
end
if IsEquipped(ItemId, ItemType) then
SetItemEquippedVisual(ItemButton, true)
end
HoverBindable:Fire("Bind", ItemButton, function()
return {
Text = ItemData.Name.. ((IsEquipped(ItemId, ItemType) and " (EQUIPPED)") or "")
}
end)
local Debounce = false
ItemButton.MouseButton1Click:Connect(function()
if Debounce then return end
Debounce = true
if CanEquip(ItemId, ItemType) then
EquipItem(ItemButton, ItemId, ItemType)
end
Debounce = false
end)
return ItemButton
end
In the example, you can see that I’m somewhat fond of the do
block. They’re pretty useful for organising different parts of your code that require a variable that isn’t needed elsewhere. In this example, StackLabel
and ItemViewport
don’t get used outside of the ItemButton
block, so I stuck em in there. This isn’t actually correct organisation according to my internal book but it still shows off what can be done. The ItemViewport
block is a good example of correct organisation, though, due to it using a variable used nowhere else.
In terms of organisation of your objects, I did things such as
- ServerScriptService
- Players (script)
- Data (module)
- DataStore (module)
- Leaderstats (module)
and
- ReplicatedStorage
- Assets (folder)
- Modules (folder)
Anyway, hopefully this all helped you figure out where you want to go