"tables cannot be cyclic"

log (from the compiled version):
error: tables cannot be cyclic - Client - ui_debug:11
error: tables cannot be cyclic - Client - ui_debug:11
codebase: https://github.com/msfyre/rpg_game/tree/battle-manager script:
src/client/UI/ui_debug
src/client/UI/ui_debug
GitHub
GitHub - msfyre/rpg_game at battle-manager
Contribute to msfyre/rpg_game development by creating an account on GitHub.
Solution:
stupid fix (it worked somehow): ```typescript export class BattleData // prev code here...
Jump to solution
8 Replies
Tesmi
Tesmi2mo ago
1 in remotes you can't send instances of classes this is an error, because references to metatables will not be passed and you will have a typing violation (you can fix this on the client if you manually restore the metatable). 2 if inside the table being passed there is a reference to itself, then this is exactly what will cause this error, because the serializer tries to serialize data infinitely
Tester
Tester2mo ago
Yeah, tesmi is right I think. And what kind of class do you pass through remote event? If it's smth like c# data class, it's prob better to replace with interface
Moonstone Fyre
Moonstone FyreOP2mo ago
custom ts class
Tester
Tester2mo ago
Can you show?
Moonstone Fyre
Moonstone FyreOP2mo ago
export class BattleData
{
public ID: string

public Players: Player[] = []
public Enemies: EnemyData[] = []

public TurnQueue: TurnData[] = []

public constructor(EncounterData: EncounterData)
{
this.ID = tostring(math.floor(999 * math.random()))
this.Enemies = EncounterData.EnemyList
}

public AddPlayer(Player: Player)
{
print(`Adding ${Player}`)

this.Players.push(Player)

print(this)

RemoteFuncs.BattleFuncs.InitializationFuncs.ReplicateBattlefield.InvokeClient(Player, this)
}
}
export class BattleData
{
public ID: string

public Players: Player[] = []
public Enemies: EnemyData[] = []

public TurnQueue: TurnData[] = []

public constructor(EncounterData: EncounterData)
{
this.ID = tostring(math.floor(999 * math.random()))
this.Enemies = EncounterData.EnemyList
}

public AddPlayer(Player: Player)
{
print(`Adding ${Player}`)

this.Players.push(Player)

print(this)

RemoteFuncs.BattleFuncs.InitializationFuncs.ReplicateBattlefield.InvokeClient(Player, this)
}
}
the print is only there for debugging
Tester
Tester2mo ago
^ And to remove any finality from it Or Just to create interface on top that holds data from class and pass it So you have class DataType{ ToRaw(): RawDataType static FromRaw(RawDataType): DataType } Where raw data type is just interface with no functions Apparently you have 1 million ways to go about this :3c There are proper ones like ones above And ugly but quick
const raw_data = {...this}


const data = setmetatable(raw_data, DataTypeClass)
const raw_data = {...this}


const data = setmetatable(raw_data, DataTypeClass)
Moonstone Fyre
Moonstone FyreOP2mo ago
so apparently encoding the class to a json works (sorta)
Solution
Moonstone Fyre
Moonstone Fyre2mo ago
stupid fix (it worked somehow):
export class BattleData
// prev code here
const toReplicate = {
Players: this.Players,
Enemies: this.Enemies
}

RemoteFuncs.BattleFuncs.InitializationFuncs.ReplicateBattlefield.InvokeClient(Player, toReplicate)
export class BattleData
// prev code here
const toReplicate = {
Players: this.Players,
Enemies: this.Enemies
}

RemoteFuncs.BattleFuncs.InitializationFuncs.ReplicateBattlefield.InvokeClient(Player, toReplicate)

Did you find this page helpful?