Quale architettura è adatta per i matchmaking dei giocatori?

1

Il sistema dovrebbe abbinare i giocatori alle sale giochi. Quando la stanza è pronta, si sposta su un server di gioco.

  1. Ogni richiesta di inizio del gioco può avere un elenco di server di gioco preferiti e
  2. specifica esattamente la modalità di gioco (deathmatch, 5vs5, ...);
  3. una modalità di gioco può avere impostazioni di conteggio del giocatore min / max e timer (ad esempio, attende 30 secondi per 10 giocatori o per 5 giocatori dopo 60 secondi);
  4. c'è una modalità "amici deathmatch" - i giocatori vengono abbinati ai loro amici.

Penso a diversi approcci.

  1. Avere un elenco di tutte le richieste corrispondenti e iterarlo ogni volta che viene aggiunto un nuovo elemento o quando un elemento segnala un timeout. Ma potrebbero esserci troppi utenti in attesa (soprattutto a causa della modalità "amici deathmatch") per iterare l'intera lista.

  2. O hai una lista di stanze. Nuove richieste possono essere abbinate a qualsiasi stanza esistente o crearne una nuova.

    a) il sistema può mantenere un utente simultaneamente in più stanze (per funzioni come i server di gioco preferiti e la modalità "amici deathmatch") e rimuoverlo da tutte le stanze quando inizia una delle sue stanze;

    b) o è meglio determinare esattamente una stanza per l'utente preliminare?

Penso di aver bisogno di avere ciascuna opzione corrispondente come una classe separata e quindi combinarli per evitare Dictionary<Dictionary<.., List<... nightmare ma Im ancora non sono sicuro di come farlo esattamente.

Ora sto cercando di implementare 2-a in questo modo:

Rendo tutte le sale corrispondenti da

public abstract class MatchingRoomBase
{
    /// <summary>
    /// Performs matching and returns Room if completed, otherwise register the request in the internal list
    /// </summary>
    /// <returns>Completed room with game mode, users, teams and bots specified</returns>
    [CanBeNull]
    public abstract Room RegisterAndTryMatch(MatchingRequest request);

    /// <summary>
    /// Removes the request from the internal list
    /// </summary>
    public abstract void TryUnregister(MatchingRequest request);


    /// <summary>
    /// Creates a clone of internal room structure but without any requests registered
    /// </summary>
    /// <remarks>This is usable for friends deathmatch mode when each friend can dynamically create a matching room (with its correct structure)</remarks>
    public abstract MatchingRoomBase CloneEmpty();
}

Quindi posso avere stanze intermedie come decoratori (per esempio GameModeDecorator dovrebbe inoltrare le chiamate solo per richieste specifiche di modalità di gioco) e nodi "multi stanza" (per esempio ServerSplitNode dovrebbe chiamare RegisterAndTryMatch su ciascuna stanza nella lista interna [dei server preferiti richiesti] fino a quando non viene restituito un risultato non nullo). Un utente può essere aggiunto a più stanze simultaneamente, ma quando viene trovato il sistema deve richiamare TryUnregister per rimuoverlo dall'intera gerarchia.

Ma dove vanno i timer? Dovrei avere un ulteriore metodo Update su MatchingRoomBase che "finalizza" tutte le sale scadute? [Preferirei evitare gli eventi qui perché portano a frequenti aggiunte / rimozione dinamiche degli abbonamenti (con CloneEmpty ) che possono influire sulle prestazioni.] Ma cosa succede se un utente viene registrato in due stanze ed entrambi timeout allo stesso passaggio di aggiornamento?

O quale approccio può essere usato?

    
posta Vlad 23.03.2015 - 23:37
fonte

0 risposte

Leggi altre domande sui tag