My first attempt to use OOP

I would like to know if is a good habit place PlayerAdded and PlayerRemoving inside the module I do know that if I dont do require will not run the code below

---| Services |---
local Players = game:GetService('Players')

local PlayerData = {}
PlayerData.Players = {}

---| TYPE CHECK DONT TOUCH |---
type player_settings = {
	Chance:number,
	Character:string,
	Skin:string
}

type player_methods = {
	__index: player_methods,
}

export type player_data = typeof(setmetatable({} :: player_settings, {} :: player_methods))
---| ^ TYPE CHECK, DON'T TOUCH ^ |---


function PlayerData.new() : player_data
	local self = setmetatable({}, {__index = PlayerData})
	self.Chance = 0
	
	self.Character = 'Test'
	self.Skin = 'Default'
	return self
end

---| Execute |---
Players.PlayerAdded:Connect(function(Player)
	PlayerData.Players[Player.UserId] = PlayerData.new()
end)

Players.PlayerRemoving:Connect(function(Player)
	PlayerData.Players[Player.UserId] = nil
end)

return PlayerData

you could do

export type player_data = typeof(PlayerData.new(table.unpack(...)))

for typechecking instead of manually defining types for player settings and methods

as PlayerData.New already returns the object you wanted to create a type for
aswell

  • types can be defined anywhere in the script so you can place them above or below the constructor function

  • module scripts are used to return a table or function that you can access with any script
    so its better practice to put those events in the script thats requiring the module instead of the module itself
    and just have .new() take in a player’s userid and insert the object into the table using the userid

1 Like

How does this line works

export type player_data = typeof(PlayerData.new(table.unpack(...)))

it gives me a error type (does not stop the whole module working btw)

local PlayerData = {}
PlayerData.Players = {}

export type player_data = typeof(table.unpack(PlayerData))

function PlayerData.new(UserId: number) : player_data
	local self = setmetatable({}, {__index = PlayerData})
	self.Chance = 0
	
	self.Character = 'Test'
	self.Skin = 'Default'
	
	PlayerData.Players[UserId] = self
	return self
end



return PlayerData

So this is now the update given

Wait Maybe I figured out
is it this?

export type player_data = typeof(table.unpack(PlayerData))

table.unpack() turns … into a tuple that you insert into the function and typeof turns the returned table into a type

maybe check if the function is returning a table

that + maybe try using a different variable name since self is a keyword that refers to function’s table when using :

how did you define the player_data type in the other script where you exported it to

Actually I notice I din’t really needed a type check
But thank you very much tho

This is how my code now ended

local PlayerData = require('../Modules/Classes/PlayerData')
local Round = require('../Modules/Main/Round')

---| Services |---
local Players = game:GetService('Players')

---| Functions |---

local function PlayerAdded(Player:Player)
	PlayerData.new(Player.UserId)
end

local function PlayerRemoving(Player:Player)
	PlayerData.Players[Player.UserId] = nil
end

---| Execute |---
Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(PlayerRemoving)

kk, it looks like it should work

typechecks are only needed for intellisense so maybe if you do smth like this in outside the module script

local test : player_data

type player_data = PlayerData.player_data

when you type test and add a . there should be options for characters, skins etc.

if it doesn’t work then it shouldn’t really affect the script since typechecking is mostly optional

1 Like

Seems theres a lot more I need to learn on type checking :sweat_smile:

1 Like