Best way to have turn based minigame (server to client)

This is what I have, but I get errors of remote event being exhausted. I would have loved to have used InvokeClient, but that’s basically useless considering exploiters could easily abuse it. I’m also not sure if I can combine these into 1 event cleanly. I don’t like to have 1 event do everything though, and prefer to have an event for each thing.

while BoardGame.InProgress do
	local PlacingPlayer = BoardGame["Seat" .. BoardGame.Turn]
	local WaitingPlayer = BoardGame["Seat" .. (BoardGame.Turn == 1 and 2 or 1)]
	
	if PlacingPlayer and WaitingPlayer then
		MinigameEvents.Connect4.PlacePiece:FireClient(PlacingPlayer) -- Get player to place piece
		MinigameEvents.Connect4.Wait:FireClient(WaitingPlayer) -- Tell player they have to wait
	end
	
	wait()
end

They’d have 30 seconds to make a move too, so if there’s a way to use InvokeClient and apply like a 30 second timer, and if nothings return in that time give them a default move or something

You could accomplish a turn based system by having a RemoteEvent, lets call it TurnEvent. The server would enter some loop which would call the event with an argument of the Player who’s turn it is. After each call (from server), use some timer which waits for a certain amount of time, or until it receives an event back from a client (you would need to ensure the player who fired the event is the player the current turn is waiting for). To do this you could have some setup like:

function doRounds()
   for round = 1, 30 do
      for _, player in ipairs(playerList) do
         TurnEvent:FireAllClients(player)
         local gotResult = nil
         local slept = 0
         local listenEvent = TurnEvent.OnClientEvent:connect(function(caller, result)
            if caller == player then
               gotResult = result
            end
         end)
         for s = 1, 30 do
            wait(1)
            if gotResult then break end
         end
         --Might want to add something to indicate the turn was skipped
         if listenEvent then
            listenEvent:disconnect()
         end
      end
   end
end