Sequenza di azioni interrompibili / ripristinabili nel gioco client-server

0

Sto implementando un gioco online a turni, in cui le modifiche allo stato del gioco sono guidate dalle azioni del client inviate al server. Le azioni del client valide vengono generate e convalidate da un metodo values , che accetta lo stato del gioco come argomento e restituisce i possibili valori per tale azione.

Alcune di queste azioni potrebbero portare a uno stato in cui un giocatore è tenuto a eseguire altre azioni come parte di esso, non consentendo tutte le altre azioni che potrebbero altrimenti essere fatte.

Quello che sto cercando di ottenere è la possibilità che queste sequenze vengano interrotte e riprese in qualsiasi momento, come nel caso di un'interruzione del server. Lo stato viene serializzato e memorizzato dopo ogni azione, quindi tutte le informazioni necessarie per riprendere la sequenza devono essere memorizzate in esso.

Due approcci che ho in mente:

  1. Il primo passaggio della sequenza ha impostato una sorta di "flag" nello stato che le azioni successive potrebbero cercare nella funzione values . Questo lo renderebbe un po 'prolisso, perché tutto deve essere dichiarato esplicitamente:

    actionA1 = (state, ...args) => {
        //some code here...
    
        return {
           ...state,
           waitFor: actionA2
        }
    }
    
    actionA2 = {
        handler: (state, ...args) => {
            //actionA2 code here...
            //some more code here...
        },
        values: (state, player) => {
            if(state.waitFor == actionA2)
                //return values for actionA2
            return []
        }
    }
    
  2. Dichiara implicitamente questa sequenza di azioni e fai in modo che il motore di gioco gestisca la ripresa (fondamentalmente eseguendo il numero 1 automaticamente dietro le quinte):

    actionA1 = (state, ...args) => {
        //some code here...
    
        /*
        suspend execution until a valid actionA2 is performed,
        but somehow this can be resumed just from reloading
        the serialized state, meaning that on a server restart
        the code above would not be executed
        */
    
        await actionA2
    
        //some more code here...
    }
    
    actionA2 = {
        handler: (state, ...args) => {
            //actionA2 code here...
        },
        values: (state, player) => {
            /*
            no need to explicitly check any conditions
            as this action can only be performed as part of actionA1
            */
    
            //return values for actionA2
        }
    }
    

Preferisco l'opzione 2, ma non sono sicuro di come andrei a implementarlo in un modo che non sembra "hacky". Forse questa è solo una questione di fiducia: P

Sto cercando un approccio funzionale qui, quindi nessuna modifica di oggetti e tutti gli effetti dipendono esclusivamente dallo stato del gioco. Inoltre, sto sviluppando questo in JavaScript.

    
posta Thiatt 19.06.2018 - 00:32
fonte

0 risposte

Leggi altre domande sui tag