Suppose I want to use blockchain to play chess for money. So, I can register, on the blockchain, a smart contract (a chess game) associated to some amount of ether. If someone wants to join, he or she has to bet the same amount of ether. Whoever wins the game, gets all the ether.
We can implement this smart contract to run on-chain. So, for every piece moved, the player would have to register his decision on the blockchain. This approach would be expensive, because the players would have to pay the transaction fee for every decision they make. And it would be slow, because the game speed would be limited to the speed of the blockchain itself.
To avoid those problems, we could implement this smart contract to run off-chain. Besides the game itself, and the ether, the contract would contain an address to establish a communication (forget about security issues).
The first to play would sign, with his private key, his decision (which chess piece, and its new position) and send it to the other player (not to the blockchain). The second player would sign, with his private key, a "block" that would contain his own decision AND the other decision AND the other signature, and send it to the first player, and so on...
This process would continue until the end of the game. Then, any player could register the final block (containing all the decisions signed) on the blockchain. The contract itself could verify the autenticity and the validity of the decisions (in this case, the moves) and transfer all the ether to the winner.
The problem is: how to deal with desistance?
If a disonest player make a bad move, he can not regret (after send it to the other player), because his decision is signed, but he can just "do nothing" forever. So, he will just ignore the next decision he will receive from the other, and all the ether would be forever blocked for both players. To avoid that, we can implement a timeout.
If the contract has a timeout, another problem emerge: one player (let's call it A) can try to "deceive" the blockchain, pretending that the other player gave up, by refusing to accept the other's decisions. We can solve that by allowing the other player (let's call it B) himself to register his decision directly on the blockchain, even if it is not his turn to play. This way, the contract will able to know that player B is active.
I believe that, this way, both players would have incentives to play honestly.
If player A doesn't want to (or can't) play anymore, B can send the incomplete game to the blockchain and, after a timeout, if A doesn't publish any valid decision, the contract will asumme that A gave up and will transfer all the ether to B.
If player A believe he has no chance of winning, he will have to send a decision anyway, otherwise player B will register on the blockchain the incomplete game, and the time will begin to count, unless A publish a valid decision.
As you can see, I've just proposed a solution. I did that because I don't even know how to properly describe the problem.
So, now that (I hope) the problem is clear, does this solution work? If not, is there another one? Which?
I used chess as example, but it could be Go, Checker, Hash, Poker, or any other decision game.