Review my bad card manager code

The code is server sided. What the code does is manage cards, but the code is messy. There’s a lot of implementation to be desired.

The card system works similarly to Slay The Spire, with the Hand, Deck, DrawPile and Discard Pile.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local BridgeNet2 = require(ReplicatedStorage.Modules.BridgeNet2)

local CardModule = require(script.Cards)

local KeyboardInput = BridgeNet2.ReferenceBridge("Keyboard")
local CreateVisual = BridgeNet2.ReferenceBridge("CreateVisual")
local PlayCard = BridgeNet2.ReferenceBridge("PlayCard")

local CardManager = {}
CardManager.__index = CardManager

function CardManager.New(player : Player, playerData)
	local self = setmetatable({}, CardManager)

	self.Owner = player
	self.PlayerData = playerData

	self.Deck = self.PlayerData.Deck
	self.Hand = self.PlayerData.Hand
	self.DrawPile = self.PlayerData.DrawPile
	self.DiscardPile = self.PlayerData.DiscardPile

	self.CanRedraw = true
	self.RedrawTime = 3

	return self	
end

function CardManager:Init()
        --table.insert spam.
	for _ = 1, 5 do
		table.insert(self.Deck, CardModule.New("Strike", "Attack"))

	end

	for _ = 1, 3 do
		table.insert(self.Deck, CardModule.New("Block", "Skill"))
	end

	table.insert(self.Deck, CardModule.New("Fireball", "Attack"))
	table.insert(self.Deck, CardModule.New("Quick Draw", "Skill"))
	table.insert(self.Deck, CardModule.New("Roll", "Skill"))
	table.insert(self.Deck, CardModule.New("Heal", "Skill"))
	table.insert(self.Deck, CardModule.New("Freeze", "Skill"))
	table.insert(self.Deck, CardModule.New("Arcane Missile", "Attack"))

	for _, v in pairs(self.Deck) do
		table.insert(self.DiscardPile, v)
	end

	for _ = 1, #self.DiscardPile do
		local random = math.random(1, #self.DiscardPile)
		table.insert(self.DrawPile, self.DiscardPile[random])
		table.remove(self.DiscardPile, random)
	end

	self:DrawCards(3)

	PlayCard:Connect(function(player, i)
		if player ~= self.Owner then return end
		self:PlayCard(i)
	end)

	KeyboardInput:Connect(function(player)
		if player ~= self.Owner then return end
		self:DrawCards(3)
	end)
end

function CardManager:PlayCard(i)
	local card = self.Hand[i]

	local cardCost = card.Cost

	if self.PlayerData.Energy < cardCost then return end
	self.PlayerData.Energy -= cardCost

	table.insert(self.DiscardPile, card)
	table.remove(self.Hand, i)

	self.PlayerData.CardPlayed = card.Name
	card:Play(self.Owner, self.PlayerData, self)
end

function CardManager:RemoveCurrentCards()
	CreateVisual:Fire(self.Owner, {self.Hand[1], "RemoveAll"})	

	for _ = 1, #self.Hand do
		table.insert(self.DiscardPile, self.Hand[1])
		table.remove(self.Hand, 1)
	end
end

function CardManager:AddCards(Amount)
	for _ = 1, Amount do
		if (#self.Hand >= 7) then return end

		if #self.DrawPile == 0 then
			for _ = 1, #self.DiscardPile do
				local random = math.random(1, #self.DiscardPile)
				table.insert(self.DrawPile, self.DiscardPile[random])
				table.remove(self.DiscardPile, random)
			end
		end

		local Card = self.DrawPile[1]
		table.insert(self.Hand, Card)

		CreateVisual:Fire(self.Owner, {Card.Name, "Add"})	

		table.remove(self.DrawPile, 1)
	end
end

function CardManager:DrawCards(Amount)
	if not self.CanRedraw then
		return
	end

	self:RemoveCurrentCards()

	for _ = 1, Amount do
		if #self.DrawPile == 0 then
			for _ = 1, #self.DiscardPile do
				local random = math.random(1, #self.DiscardPile)
				table.insert(self.DrawPile, self.DiscardPile[random])
				table.remove(self.DiscardPile, random)
			end
		end

		local Card = self.DrawPile[1]
		table.insert(self.Hand, Card)

		CreateVisual:Fire(self.Owner, {Card.Name, "Add"})	

		table.remove(self.DrawPile, 1)
	end

	self.PlayerData.Energy = self.PlayerData.MaxEnergy

	self.CanRedraw = false
	task.spawn(function()
		task.wait(self.RedrawTime)
		self.CanRedraw = true
	end)	
end

function CardManager:DeadPlayer()
	self:RemoveCurrentCards()
	self.CanRedraw = false

	self.Owner.CharacterAdded:Wait()

	self.CanRedraw = true
end

return CardManager

The referenced Cards Module:

local Card = {}
Card.__index = Card

function Card.New(name: string, cardType: string)
	local self = setmetatable({}, Card)

	self.Name = name
	self.Type = cardType
	self.Cost = require(game:GetService("ReplicatedStorage").CardModules.CardInfo)[self.Name].Cost

	return self	
end

function Card:Play(...)
	local ServerScriptService = game:GetService("ServerScriptService")
	local CardModules = ServerScriptService:FindFirstChild("CardModules")

	local module = require(CardModules:FindFirstChild(self.Type):FindFirstChild(self.Name))
	if module.Init then
		module.Init(...)
	end
end

return Card

1 Like