Perché i giochi sembrano ricaricare l'intero livello quando si riavvia un livello?


47

I dati sono davvero così modificati durante il gioco?

Suppongo che la pausa prolungata tra il riavvio di un livello sia il ricaricamento dell'intero livello. Ma mi sembra che un sistema ben implementato dovrebbe essere in grado di "eseguire il ping" all'inizio del livello.

È più evidente sulle console, ma non è impercettibile sui giochi per PC.


8
La risposta dipende molto dal gioco, dagli sviluppatori, dalle loro abitudini ed esperienze e da molti altri fattori. L'unica risposta corretta a livello generale sarebbe: a volte viene modificata molto, a volte no, a volte le cose vengono trasmesse in streaming e quindi l'inizio non è più in memoria, e a volte i giochi fanno già "ping" all'inizio del livello, e giochi che a volte non hanno buoni motivi per cui non possono farlo e a volte è solo perché non è implementato abbastanza bene.
Christian,

4
In generale, è molto più semplice ricaricare il livello (che mette tutto al suo stato iniziale) piuttosto che annullare tutto ciò che il giocatore ha fatto. Questo è il caso della mia esperienza comunque.
Benjamin Danger Johnson,

La domanda non è in bianco e nero. Quanto stato viene ricaricato? Molti giochi ricaricano interi set di texture senza una buona ragione. Certo, passare dal livello 5 al livello 6 può significare caricare nuove trame, ma ciò non significa che dovresti farlo ogni volta che (ri) inizi il livello 6.
MSalters

@MSalters Riguarderà principalmente lo stato del gioco piuttosto che le risorse, potrebbe non essere necessario ricaricare un texesh di uso comune, ma più il nemico che hai già ucciso - l'oggetto per cui deve essere distrutto e ricaricato nel suo stato iniziale (anche se la sua trama è ancora ben conservata nella memoria.)
Tom 'Blue' Piddock,

Penso che qualcuno abbia giocato a Wing Commander III su un sistema legacy.
Erik Reppen,

Risposte:


54

Bene, ora - che domanda semplice ma interessante da affrontare.

Quando si ricarica un livello ci sono così tanti fattori che devono essere presi in considerazione che la risposta può andare in molti modi.

Se il tuo stato di livello contiene un ampio elenco di risorse, può essere più pratico iniziare da una tabula rasa quando si ricarica un livello di nuovo in uno stato di salvataggio / missione in quanto mantiene lo stato accurato del livello al momento della ricarica ma non richiede molto di elaborazione. Tuttavia, è più efficiente reimpostare le risorse da sole se ce ne sono solo alcune da prendere in considerazione, assicurandosi di poter riavviare rapidamente l'azione su questi livelli più piccoli. Quest'ultimo è particolarmente vero quando non hai bisogno di preservare nulla nella scena o non è influenzato dalle tue scelte nel gioco - se non avessi bisogno di cadaveri per essere preservati dalla tua prima corsa attraverso un villaggio non lo farebbero è necessario ricaricare al ritorno attraverso quel livello, risparmiando così il tempo del processore e risparmiando / tempo di accesso allo stato della missione.

Un buon esempio a cui pensare sarebbe uno sparatutto in prima persona che utilizzava decalcomanie di distruzione del terreno / proiettile che avevano uno stato persistente durante quel playthrough ma che non sarebbero rimasti se avessi riavviato quel checkpoint o livello .

Se dovessi riavvolgere il livello invece di distruggerlo e ricaricarlo, dovresti rintracciare ogni stato modificato. Se facessi un buco nel muro con un razzo genereresti colpi di terreno dai pezzi che cadono dal muro, il modello del muro cambierebbe per produrre il buco e avresti effetti particellari che sono stati generati per renderlo carino . Per ripulirlo ripristinandolo in uno stato "riavviabile" dovresti:

  • Rimuovi eventuali gib generati dinamicamente per quel muro (ma non rimuoverli dallo stato che hai caricato)
  • Rimuovere l'effetto particella per la polvere dal foro del proiettile
  • Sostituisci / ripara il muro per eliminare i buchi che hai creato
  • Ripristina le munizioni del giocatore
  • Eccetera...

Con così tante risorse da tracciare per il riavvolgimento di un livello, spesso è meno intensivo per il processore semplicemente distruggere l'intero livello e ricaricare nuovamente tutte le risorse nei loro stati predefiniti o specifici della missione. Dover ripristinare oggetti specifici comporta la ricerca di un elenco degli oggetti nella scena e quindi l'accesso alle loro proprietà per ripristinarli. Invece di riparare quel foro di proiettile nel muro ripulendolo, non è necessario confermare alcuna azione di pulizia, basta eliminare l'intero livello dalla memoria e ricaricarlo da zero.

Ciò significa che ricaricare un livello viene donato da un oggetto di stato (un file di gioco di salvataggio o uno script di missione) e non necessita di calcoli dinamici. Per le console ciò è aggravato dai tempi di caricamento dei dischi. Aiuta anche i giochi per PC in quanto può tenere conto dei computer che non avranno il potere di processare per rendere accettabili i tempi di caricamento.

Quindi, per livelli di contenuto di grandi dimensioni: caricamento di un singolo stato anziché calcolo e "riavvolgimento" di uno:

  • È meno intensivo per il processore
  • È più efficiente su macchine di livello inferiore
  • Abilita uno script di missione e il file di salvataggio da utilizzare nello stesso modo (potenzialmente utilizzare lo stesso sistema di caricamento per caricare uno stato di salvataggio o uno stato di checkpoint della missione quando si riavvia il livello)
  • Significa che hai meno lavoro come sviluppatore per reimpostare un livello - È molto più facile programmare un ricaricamento completo dai dati della sessione piuttosto che tenere traccia e riavvolgere. Questo è probabilmente il punto più influente

Tuttavia, come contro esempio, un gioco di combattimento (un grande esempio di vita reale come Street Fighter 4) potrebbe non essere necessario ricaricare tutte quelle risorse per riavviare un livello. I 2 giocatori, lo stato dell'ambiente per il livello e i timer di livello semplice sono per lo più statici e non dinamici (la salute dei giocatori rigenererà sempre al 100% ogni round, i timer si resetteranno a 90 secondi e il livello non avrà fori di proiettile [o lo fa!] ) e quindi ripristinare il livello è una questione di riportare i combattenti in piena salute e riportare l'ambiente nelle sue posizioni originali (come gli spettatori in alcuni livelli).

Quindi, per un gioco di combattimento quando si effettua una rivincita (non andando di round in round) è necessario:

  • Ripristina Salute ed energia al massimo o ai valori predefiniti (sempre gli stessi per personaggio)
  • Ripristina timer
  • Ripristina le posizioni iniziali del personaggio
  • Ripristina Terrain allo stato predefinito (nessun foro di proiettile da riparare o ricaricare!)

E questo è essenzialmente l'intero elenco, il che significa che un ripristino rapido dello stato anziché un ricaricamento a livello completo è più fattibile. Ciò può anche essere mostrato dal tempo di caricamento quando inizi la partita inizialmente. Ci vuole molto tempo per caricare tutti i modelli di personaggi e di livello, ma solo pochi tick del processore per ripristinare le posizioni iniziali del personaggio tra le partite con un modello già caricato.

È importante notare che questo è anche un requisito più richiesto per i giochi di combattimento poiché i loro giocatori tendono a voler tornare all'azione incredibilmente rapidamente poiché le partite possono durare solo un minuto - sottolineando che questa risposta dipende molto dal gioco e genere. Gli FPS richiedono risorse più dinamiche mentre i combattenti richiedono un'azione rapida e ripetibile.

Spero che questo abbia fatto luce sulla tua domanda.


7
Ottima risposta ... il lato cinico di me metterebbe il tuo: "meno lavoro per i punti degli sviluppatori in cima alla lista ... ma forse è l'implementazione del motore che potrebbe essere migliore.
Mesh,

3
Inoltre, per quanto riguarda il recupero dei bug? Un NPC non si muove a causa di un bug nel sistema fisico, una perdita di memoria, ecc. Anche se il gioco è stato testato a fondo, queste cose accadono ancora e deve esserci un modo per ripristinare il gioco in uno stato noto e funzionante.
Sulthan,

9
Meno lavoro è un obiettivo invidiabile da raggiungere, non un argomento di vergogna. Potresti trascorrere una settimana per costruire un sistema di riavvolgimento e un mese per eliminare tutti i bug, oppure ricaricare e accedere ad altre funzionalità =)
Patrick Hughes,

1
Penso che il costo sia l'argomento più importante qui. A meno che il ricaricamento di un livello non avvenga molto e diventi un grosso fastidio per l'utente, non vi è alcun incentivo a scrivere codice ottimizzato per velocizzare il ricaricamento. Costa solo meno riutilizzare il codice per un carico normale.
orlp

1
+1 Voglio solo chiarire che ricaricare un livello e caricare un livello - se la ricarica butta via tutto e inizia con un nuovo carico - non richiede la scrittura di un nuovo codice per raggiungere l'obiettivo del gioco. Un sistema di riavvolgimento è una serie completamente nuova di codice non banale e, poiché dipende da uno stato variabile, è estremamente difficile eseguire il debug. Esempio: "Correzione bug: il riavvio di un livello dopo aver fatto cadere un elmetto sopra una bomba dopo che un missile esplode in 200 pixel d'acqua non causa più un incidente sul desktop." In breve, dovresti avere davvero un buon motivo per preoccuparti.
BrianH,

14

Per chiarire le risposte esistenti contro la tua domanda sulle console: non hanno memoria sufficiente per archiviare sia lo stato iniziale che lo stato corrente per giochi complessi più grandi.

Un gioco potrebbe memorizzare il livello e lo stato iniziale separatamente in modo che solo lo stato possa essere ripristinato, e questo è molto probabilmente ciò che fanno molti giochi. Anche lo streaming sarà solo un po 'più lento di se fosse stato tenuto in memoria, però.

La "migliore" console attuale ha solo 512 MB di memoria condivisa tra dati e grafica della CPU. Questo è piccolo. Uno degli attuali mal di testa dello sviluppo della console sta cercando di adattarsi ai giochi che soddisfano i livelli di qualità odierni con una quantità così piccola di memoria. Il conteggio dei chilobyte può diventare importante, specialmente vicino alla data di spedizione. La memorizzazione di una copia dello stato iniziale di un livello è una quantità di dati che potrebbe essere eseguita senza, consentendo di utilizzare più memoria per cose che rendono il gioco più interessante durante il gioco piuttosto che semplicemente ricaricare il livello più velocemente.

Idealmente, il giocatore trascorre più tempo a giocare che a morire e a ricominciare, quindi ha più senso ottimizzare una migliore esperienza durante il gioco.

Le cose potrebbero cambiare drasticamente con le console di nuova generazione e i loro 8 GB di memoria. Oppure potrebbero rimanere gli stessi, con modelli e materiali semplicemente a risoluzione più elevata e un gran numero di oggetti di gioco attivi. Il tempo lo dirà. Dato che i giochi per PC di solito prendono di mira macchine con 2 GB di RAM e 512 MB di VRAM (sebbene molti ridimensionino a valori molto più grandi), gli 8 GB delle nuove console sono piuttosto lussuosi per quanto riguarda le linee di base minime. Probabilmente vedremo una transizione a giochi che richiedono una CPU / OS a 64 bit e 4-8 GB di RAM con 1-2 GB di VRAM negli anni a venire. La memorizzazione di più stati in memoria per un'istantanea rapida dovrebbe essere molto più semplice.


+1 Informazioni fantastiche e un'ottima spiegazione del perché le console sono notevolmente più lente nel ricaricare.
Tom 'Blue' Piddock,

7

Non sono d'accordo con gran parte della risposta di Blue, non credo ci sia un caso tecnico per non ripristinare i livelli - di certo non ne ho mai incontrato uno. Il caricamento del livello è quasi sempre più lento del ripristino del livello, in effetti trovo difficile concepire un'occasione in cui non lo sarebbe. Nella maggior parte dei casi i giochi potrebbero offrire un caricamento di livello istantaneo efficace se gli sviluppatori lo scegliessero.

La vera risposta è, come suggerito, più facile e veloce. Il caricamento ripetuto di livelli è qualcosa che un gioco richiede comunque, quindi riproporlo in un riavvio di livello è relativamente semplice. Il ripristino richiede nuovi percorsi complessi con un grande potenziale per nuovi bug e perdite di memoria e richiede un investimento decente di tempo per gli sviluppatori. In alcuni casi può anche spingere i limiti di memoria. Dal momento che i giochi vengono raramente sviluppati con un eccesso di tempo per gli sviluppatori, elementi come il ripristino del livello hanno una deplorevole tendenza a cadere lungo la strada, in particolare se l'architettura del gioco non è la migliore costruita in primo luogo.

Mentre suppongo che si possa trovare una situazione in cui il "riavvolgimento" era necessario per il ripristino, in effetti la maggior parte dei giochi deve solo memorizzare lo stato originale, fornire un mezzo efficace per ripristinare completamente quello stato per gli oggetti conservati e un mezzo per contrassegnare gli oggetti su abbandonare al ripristino. Anche le informazioni sullo stato del gioco devono essere archiviate e ripristinabili. Questo tipo di informazioni è in genere relativamente leggero nella memoria rispetto ai requisiti per un intero livello, quindi ciò elimina la necessità di un caricamento lento e costoso dei dati dal disco (inclusi elementi di grandi dimensioni come trame e modelli) e lo sostituisce per un rapido, in -memory pass della scena.


3
Potresti voler dare un'occhiata alla risposta di Sean per un esempio di un caso tecnico in cui potresti voler ricaricare un livello per "ripristinarlo"
SpartanDonut,

2

Per consentire livelli di gioco di livello elevato o uniforme, anche con memoria limitata (la memoria è sempre troppo piccola, la domanda è se si raggiunge prima il limite nella RAM o sulla scheda grafica) esiste un'altra strategia:

Tieni in memoria solo la parte del livello di cui il giocatore ha bisogno al momento o di cui avrà bisogno in pochi secondi. Modelli, trame, campioni sonori, ... che probabilmente non sono più necessari vengono rimossi dalla memoria.

Dungeon Siege mi viene in mente (gli sviluppatori una volta hanno affermato che la gestione della memoria ha richiesto più potenza di elaborazione rispetto al gioco reale), la maggior parte dei MMORPG lo fa, gli sparatutto con un ambiente aperto devono farlo, ... In questi casi, l'inizio del il livello (o anche un punto di rigenerazione 30 secondi fa) potrebbe non essere più (completamente) in memoria.

Spesso una nuova ricarica è il modo più semplice, il più economico e forse il più veloce.

Modifica: ecco un documento sui meccanismi di caricamento di Dungeon Siege: The Continuous World of Dungeon Siege


Bene, non ho pensato a livelli continui o continui. Ciò richiederebbe un sistema di caricamento di livello completamente diverso.
Tom 'Blue' Piddock,

2

Con le eccellenti risposte di Sean e Blue in merito alle limitazioni della piattaforma fisica e alle decisioni pro-contro, ho intenzione di espandere un commento in un approccio diverso:

Perché dovresti probabilmente ricaricare completamente il livello

Quindi hai la tua chiamata loadLevel () che funziona perfettamente, yay! Trasmetti in streaming un file di informazioni di livello e attraversi la costruzione del mondo in base a esso, creando oggetti e caricando trame e suoni mentre procedi. Quindi, quando tutto è finito - o fatto "abbastanza" per far iniziare la riproduzione, chiami startPlay () e il tuo mondo viene rivelato e la tua musica inizia a suonare.

Ora quando hai finito con il livello, o esci dal menu o esci dal gioco, chiami unloadLevel () per liberare tutte le risorse e la memoria a cui ti sei aggrappato per consentire un'esperienza fluida.

Ora, cosa succede quando si desidera aggiungere una funzione "Livello di riavvio"? Bene...

unloadLevel(currentLevel);
loadLevel(currentLevel);
startPlay();

E il gioco è fatto! Nessun nuovo codice, solo poche semplici funzioni al massimo, e hai già scritto e fatto il debug di tutto ciò, quindi ora la tua nuova brillante funzione di riavvio è cancellata dal tuo elenco e probabilmente non verrà mai più incontrata - codice senza instradamento, non arrugginito è il tipo migliore! Sposta il codice in una funzione restartCurrentLevel () e puoi ripiegarlo e non guardarlo mai più - forse dopo esserti assicurato che ci sia un livello da riavviare, ovviamente :)

Ma poi ti chiedi se questo non è uno spreco, scaricando cose che stai per ricaricare comunque. Bene, se i tuoi livelli e risorse sono piccoli, il massimo che devi guadagnare è qualche secondo di tempo di caricamento ogni volta che "Riavvia" viene chiamato anche su sistemi lenti (e forse smartphone più vecchi), quindi chi se ne frega? "Ottimizzazione precoce", hai cose migliori da fare con il tuo tempo.

Ah, ma ora i tuoi livelli stanno crescendo e le tue trame stanno diventando più dettagliate e la colonna sonora è stata strappata a 512kbps con canali separati per ogni voce e livello musicale (sembrava una buona idea al momento, anche se non ricordi il perché. ..) e qualcosa sul "ray voxel dipendente dallo stato che segue le matrici di trasformate multidimensionali di Fourier" che pensi sia completamente inventato e non una cosa reale, e il caricamento del livello in realtà impiega un po 'di tempo ora e sta iniziando a infastidirti. Hai anche provato con persone reali e in realtà mostrano un disgusto per i tempi di attesa in quanto è peggio di giochi simili (non ti aspetti che una capitale MMORPG con 100 giocatori si carichi completamente in <2 secondi, vero?), ed è un problema.

Quindi come si ottimizza? Beh, se il livello re -loading è un problema, allora non è a livello di carico di un problema? Se pensi che si stia ricaricando, perché mai le persone ricaricano il tuo livello molto più spesso di quanto non caricino il livello? Sembra un problema di gioco, non un problema di ingegneria del codice. Chi pensa che sia divertente ricaricare un livello ancora e ancora e ancora, e desidera solo che sia più veloce invece che completamente evitabile ?

Risolvi prima il vero problema!

Ma supponiamo che il tuo gioco sia progettato in modo da dover ricominciare almeno occasionalmente e il tempo di caricamento è abbastanza lungo che va bene farlo una volta e assolutamente inevitabile, ma non devi farlo di nuovo. Che tipo di gioco è questo, comunque? Sembra un po 'uno strano problema ... forse un gioco simile ad un portale ad alta risoluzione in cui si presume che tu abbia sbagliato più volte il puzzle?

Prima di tutto, devi capire che questo non sarà banale. Dovrai scrivere un codice completamente nuovo, non testato, ed è "dipendente dallo stato" in modo da non sapere nemmeno cosa verrà o non verrà riutilizzato tra i giochi di livello. Ci sono elementi casuali, spawn, trame variabili (i tuoi scheletri a volte indossano solo armature?) O altri elementi mutevoli nel tuo livello? Ci sono cose che variano con il giocatore, come un abito o un modello personalizzato o colori / porte / trappole?

Farai confronti, e molti di loro. Stai andando in loop attraverso gli elementi di livello, confrontando ciò che sarà necessario rispetto a ciò che è caricato in questo momento (cosa fai con le cose che sono state caricate per l'ultimo livello ma non per questo? Rilasciali o resisti per prevenire un futuro caricare?). Se questo è davvero un grosso problema per il tuo gioco, probabilmente vorrai cambiare il codice di caricamento / scaricamento per vedere se qualcosa è già caricato prima di caricarlo (rendendo il codice multiuso ma introducendo potenzialmente nuovi bug a funzionalità e funzioni precedentemente funzionanti che rilascino con cura risorse che non saranno in uso nel prossimo futuro). Sospiro.

Indipendentemente da ciò che fai, anche se il tuo gioco è semplice, ti imbatterai in bug oscuri che si basano sul livello / stato del giocatore quando viene riavviato un livello che non ti capita di caricare il livello la prima volta. Quindi puoi scrivere aggiornamenti di gioco con testo come:

"Far cadere un elmetto su una bomba su una tessera che aveva un missile esplodere vicino ad essa che era anche entro 200 pixel d'acqua non corromperà più i dati di gioco o causerà il crash del gioco."

La vera ragione per cui la maggior parte dei giochi non dà fastidio

Hai mai notato che la maggior parte delle persone semplicemente dipinge o muro a secco sui loro muri esistenti invece di spogliarsi su uno strato di base, o stendere il tappeto proprio sopra i pavimenti in legno invece di tirarli su?

Il semplice fatto è che è tutto più lavoro per una ricompensa minima. La pittura sopra le pareti esistenti funziona bene per la maggior parte del tempo e il valore di strappare i pavimenti in legno è spesso minimo o inesistente.

Lo stesso vale per i software, dai giochi alle presentazioni multimediali in Power Point: se tutto ciò che fai è radere qualche secondo fuori da una schermata di caricamento, le persone trascorrono l'1% del loro tempo a guardare, quindi è meglio essere incredibilmente banali da fare o stai ottenendo un rendimento molto scarso sul tempo investito.

E quindi la maggior parte dei giochi non dà fastidio, e ho difficoltà a pensare a molti giochi in cui il caricamento di schermate ha reso meno utile un gioco altrimenti buono, tranne alcuni esempi estremi; gli esempi estremi sono quelli in cui l'ottimizzazione per un caricamento di livello più veloce ha senso, e questa è una piccola frazione di giochi che arriva al pubblico, e probabilmente anche una piccola parte di giochi che nessuno vede mai perché non vengono mai rilasciati.


0

Perché è più difficile sviluppare il comportamento opposto che consiste nel mantenere in memoria i dati di gioco statici (come trame, informazioni geologiche, mob non interessati) e ricaricare solo i dati dinamici (come posizione del giocatore, statistiche del giocatore, stato delle missioni, inventario) .

Dato che costa più tempo e denaro, gli sviluppatori di giochi generalmente non lo fanno.


Ciò non copre le situazioni in cui deve verificarsi il contrario a causa del genere di gioco o delle esigenze individuali. Come Prince of Persia che ha bisogno di registrare lo stato del gioco per usare una particolare meccanica di gioco e gli esempi di gioco di combattimento che ho dato che devono essere in grado di ricaricare singoli stati oggetto / livello / personaggio al fine di resettare a metà strada attraverso una partita per iniziare il turno successivo o riavvia la partita per iniziare la partita successiva. Questi sono necessari per soddisfare le esigenze del gioco a portata di mano ed è quindi necessario che gli sviluppatori di giochi spendano più tempo e denaro.
Tom 'Blue' Piddock,

Se si verifica il contrario in un gioco specifico, la domanda precedente non è valida per quel gioco. Perché il tempo di caricamento sarà veloce nel gioco in cui si verifica il contrario. Ho appena risposto alla domanda per la situazione a cui si applica (ovvero i giochi che caricano l'intero livello da zero)
Xtro

Se si verifica il contrario in cui la premessa della domanda avrebbe potuto accadere, vale sempre la pena annotarlo e perché. Perdere informazioni o tralasciare i dettagli del motivo per cui una situazione o una soluzione è diventata non è mai vantaggioso. Dire che non c'è bisogno di dettagli è un po 'controintuitivo in quanto non ci sarebbe in primo luogo una domanda se la persona non cercasse i dettagli. Se sei in grado di fornire maggiori dettagli, cerca sempre di farlo in quanto aiuta gli altri a conoscere meglio l'argomento nel suo insieme e a prendere ciò di cui ha bisogno il deatil.
Tom 'Blue' Piddock,

quindi, la tua reazione è per la mia prima linea di risposta che riguarda "nessun bisogno di dettagli" giusto? se rimuovo quella linea, porteresti indietro di -1 punto?
Xtro,

Stranamente, sì. Non scoraggiare mai i dettagli in cui è possibile fornirli e generalmente troverai che le tue risposte ottengono un apprezzamento molto maggiore.
Tom 'Blue' Piddock,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.