You will need two mechanisms:
- First, you will need to be able to transmit the entire world state to a user. You don't want to do this regularly, but you will need it to transmit "initial" world states to users as they join the game or potentially at the very beginning of the game.
- Second, you will need to be able to transmit packets to all connected clients that notify them of state changes (deltas). Something of the form "change tile (1, 2) to state 3."
You mention this "text file" that you save the state into after every change; that seems unnecessary. Unless your levels are massive you should keep the entire state in-memory at all times, and share it with the renderer. Disk is one of the slowest forms of memory so having to hit it twice per frame on average is undesirable.
Since your game is running in a P2P context there is no central authority to validate the moves or resolve races (two players clicking the same tile at the "same time"). To help alleviate this, especially if your game is real-time and not turn-based, you can synchronize each player to a known good clock when the game starts, and have players transmit the timestamp on that clock with each move, which can be used to resolve races. This can also be done with a sequencing number, or consider an approach where every client gets a vote on the correct state of the game and that majority vote wins (this is sometimes useful in cheat detection as well).
Note that you may need to buffer some moves in memory on all clients to account for the possibility that other clients can "replace" locally-made moves.
scuttlebuttJavaScript library uses a gossip-based system to replicate data in real time. Its source code might be a good read. For a less realtimey, more databasey approach, check out Distributed Hash Tables like as Chord or Kademlia. \$\endgroup\$