How to make this?

I am making a tycoon system but i have problem

I have 3 type button (gamepass, normal(tycoon), upgrade)

But I don’t know “How do I classify them?”

So like get button script

for _ , Button in game:GetService("CollectionService"):GetTagged("Button") do
	print(Button)
end

Should I do this in gamepassbutton?
Like

for _ , GamepassButton in game:GetService("CollectionService"):GetTagged("GamepassButton ") do
	print(GamepassButton)
end

What if I’m going to call a lot of specifics in just 1 button?

What should I do in this situation

for _ , Button in game:GetService("CollectionService"):GetTagged("Button") do
	if Button:GetAttribute("IsSpecific") then
            print("Specific")
            specifics()
    else
            print("is not spesific")
    end
end

I think this is the answer but I guess there is a more effective method.

I hope so.

I think you should separate them with their tags.

4 Likes

I used a lot of if else statements in the past but now I know faster way

local CollServ = game:GetService("CollectionService")
local Buttons = {
    SpecifiedButton = function(button)
        print("Specific")
        specifics()
    end,
    Button = function(button)
        print("is not spesific")
    end,
    GamePass = function(button)
        --code
        --like
        --button.Touched:Connect
    end,
    Upgrade = function(button)
        --code
    end,
}

local Tags = {"Button", "SpecifiedButton", "GamePass", "Upgrade"}
for tag, function in pairs(Tags) do
	for i,v in ipairs(CollServ:GetTagged(tag)) do
		function(button)
	end
end
2 Likes

so I can use wşth modulescript

require(script:FindFirstChild(object:GetAttribute("Class")))
2 Likes

I think, yes.

SpecifiedButton = function(button) --by button I mean this object so you can change "button" in this script to "object"
        print("Specific")
      --require(script:FindFirstChild(button:GetAttribute("Class")))
        specifics()
    end,

but use ‘button’ instead of ‘object’ in code

There are also composition and Inheritance as suggestions. How to be with them?

1 Like

Are they only for specified button or they are different class?

1 Like

I want to make it as editable and beautiful as possible, and I think Composition is a good example, even though it’s not exactly in Lua.

1 Like

You made an error.

 for _ , Button in pairs(game:GetService("CollectionService"):GetTagged("Button")) do
     print(Button)
 end

Do this for all of them you have to use pairs() for all of them or it will not read them correctly.

1 Like

Why?. Pairs() is not necessary.

2 Likes

What is the composition? Like children of button or dropper model
With my script you have full access to object(button):
object:GetAttribute()
object.Parent
object:FindFirstChild():Destroy()

like this.

2 Likes

For what purpose do you need this. The most valuable thing for developer is not only knowledge how to script, but how to make logic. Tell me logic of your buttons system.

I never did tycoons but my logic is:

There are 3 types of buttons: Buy, GamePass, Upgrade.

Buy button has 1 tag “Buy” and 4 attributes:
Model: string (for example: FirstDropper)
Price: int (for example: 150)
Product: int (how much money the block it produces, gives. For example: 10)
Rate: int (how much block it drops per second. For example: 2 )

With the help of Collection service I register when button is touched then if it’s “Buy” button it removes “Price” attribute from your balance and it searches Replicated Storage for the model by name given by attribute “Model”, then it make dropper drop product which gives you attribute “Product” amount of money when destroyed, with rate loop that waits “Rate” attribute/1. You can add attribute for product model and everything like that.

This was only “Buy” button, writing or imagining essays like that helps you make a plan. Properly made plan is worth more than 100 attempts

If I will be realistic, there is more than 50 ways to do it.
Logic decides what you will do
I went to sleep. See ya tomorrow

Yes, but maybe another button type may come later, I need an infrastructure to support all of them.

Hmmmm, then learn how to use modules. Because composition you showed was in module. That’s my advice. Also, fun fact, module scripts saved me from existential crisis

Yes, but the button and the car script are not in the same category, there are more specific events in the button.

This message is to make the conversation stand out.

1 Like

Then tell me the these events. I can’t do if I don’t know what to do. Code can always be changed. Better to prepare first version or write your plan than waiting someone to do it for you. It’s not hard to code, it is problem with your idea. For example: Yandere Simulator(actual game not on roblox) was fully made on if else statements. Yes, many users pc couldn’t even run it, mid ones always had lags, only really strong pcs were able to handle this game, BUT he did it, code was trash, idea was good and guess what? Game became popular.
Edit: https://youtu.be/SfrSxiql9wA this is link to my statechanger module test.
It was showed in my topic “Customizable Keybinds”. Use some app or notebook to write your plan(idea). I saw a little recommendation about usefulness of making plans and app called Obsidian. It was year ago but I remembered it(quote “Learn from others experience”)
For example:
My whole game plan: (if I zoom there it will spoil game details)

My StateChanger module that I mentioned. I will giveaway this soon so I can spoil it


Structured plans are better than keeping ideas in your head

So doing it in a class doesn’t seem right to me. Because we set rough rules. But I want to be able to call specific codes easily and beautifully.

I tried different method.

Tycoon script–>

local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local ServerServices = ServerStorage.src.Services
local Button = require(ServerServices.Button)

local ClientLibraries = ReplicatedStorage.src.Libraries
local Promise = require(ClientLibraries.Promise)
local Observer = require(ClientLibraries.Observers)
local Maid = require(ClientLibraries.maid)

local Tags = {"Button"}

local module = {}

local TycoonMethods = {}

TycoonObserver = function(TycoonFolder: Model)
	assert(TycoonFolder, "Tycoon not be nil")
	assert(TycoonFolder:IsA("Folder"), "Tycoon must be folder")
	
	local self = setmetatable({}, TycoonMethods)
	
	self.Player = nil
	self.Items = {}
	self.Id = 1
	
	self.Maid = Maid.new()
	
	
	
	local ObserverFunctions = {
		ButtonObserver = function(ButtonModel)
			local ButtonClass, callback = Button.new(ButtonModel, self)
			self.Items[ButtonClass.Id] = ButtonClass
			return callback
		end,
	}
	


	for _ , Tag in Tags do
		local ObserverFunction = ObserverFunctions[Tag.."Observer"]
		self.Maid:GiveTask(Observer.observeTag(Tag, ObserverFunction, {TycoonFolder}))
	end
	
	self.Maid:GiveTask(function()
		print(self)
		print("Tycoon destroyed")
	end)
	
	return function()
		self.Maid:DoCleaning()
	end
end

Observer.observeTag("Tycoon", TycoonObserver, {workspace.Tycoons})

return module

Button script →

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local ClientLibraries = ReplicatedStorage.src.Libraries
local Promise = require(ClientLibraries.Promise)
local Observer = require(ClientLibraries.Observers)
local Maid = require(ClientLibraries.maid)

local Constructors = {}

local ButtonClassMethods = {}
ButtonClassMethods.__index = ButtonClassMethods

Constructors.new = function (Button, tycoon)
	
	local Button = assert(Button, "Button not be nil")
	assert(typeof(Button) == "Instance", "Buttonn must be Instance")
	assert(Button:IsA("Model"), "Button must be Model")
	local Hitbox = assert(Button.Hitbox, "Hit box isn't found")
	assert(typeof(Hitbox) == "Instance", "Hitbox must be Instance")
	assert(Hitbox:IsA("BasePart"), "Hitbox must be basepart")

	local self = setmetatable({}, ButtonClassMethods)
	
	self.Id = 123123
	self.Instance = Button
	self.Maid = Maid.new()

	local IsCooldown = true

	local CheckReject = function(...: string?)
		IsCooldown = false
		if ... then
			warn(...)
		end
	end
	
	self.Maid:GiveTask(Hitbox.Touched:Connect(function(Hit: BasePart)
		if IsCooldown then
			return
		end
		
		IsCooldown = true
		
		local Player = Players:GetPlayerFromCharacter(Hit.Parent)

		if not Player then
			return CheckReject()
		end

		local Character = Player.Character

		if tycoon.Player ~= Player then
			return CheckReject("Tycoon is not", Player, tycoon.Player)
		end
		
		local ButtonPrice = Button:GetAttribute("Price")
		
		if Player.Stats.Cash.Value < ButtonPrice then
			task.wait(1)
			IsCooldown = false
			return
		end
		
		Player.Stats.Cash.Value -= ButtonPrice
		
	end))
	
	self.Maid:GiveTask(function()
		print("Button destroyed")
	end)

	return self, function()
		self.Maid:DoCleaning()
	end
end

return Constructors