Il sistema dovrebbe abbinare i giocatori alle sale giochi. Quando la stanza è pronta, si sposta su un server di gioco.
- Ogni richiesta di inizio del gioco può avere un elenco di server di gioco preferiti e
- specifica esattamente la modalità di gioco (deathmatch, 5vs5, ...);
- 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);
- c'è una modalità "amici deathmatch" - i giocatori vengono abbinati ai loro amici.
Penso a diversi approcci.
-
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.
-
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?