(Potresti voler conoscere il termine "rattoppare le scimmie" o "pugni d'anatra" se non altro per l'immagine mentale umoristica.)
A parte questo: se il tuo obiettivo è ridurre il tempo di iterazione per i cambiamenti di "comportamento", prova alcuni approcci che ti portano la maggior parte del percorso lì, e combinali bene per consentire più di questo in futuro.
(Questo uscirà un po 'tangente, ma prometto che tornerà!)
- Inizia con i dati e inizia in piccolo: ricarica ai limiti ("livelli" o simili), quindi procedi fino all'utilizzo della funzionalità del sistema operativo per ricevere notifiche di modifica dei file o semplicemente sondare regolarmente.
- (Per i punti bonus e i tempi di caricamento inferiori (di nuovo, diminuendo il tempo di iterazione) esaminare la cottura dei dati .)
- Gli script sono dati e consentono di iterare il comportamento. Se usi un linguaggio di scripting, ora hai le notifiche / capacità di ricaricare quegli script, interpretati o compilati. Puoi anche collegare il tuo interprete a una console di gioco, a un socket di rete o simili per una maggiore flessibilità di runtime.
- Anche il codice può essere un dato : il tuo compilatore può supportare overlay , librerie condivise, DLL o simili. Quindi ora puoi scegliere un momento "sicuro" per scaricare e ricaricare un overlay o DLL, sia manuale che automatico. Le altre risposte vanno nel dettaglio qui. Si noti che alcune varianti di questo possono interferire con la vecificazione della firma crittografica, il bit NX (no-execute) o meccanismi di sicurezza simili.
- Prendi in considerazione un sistema di salvataggio / caricamento approfondito e con versione . Se riesci a salvare e ripristinare il tuo stato in modo robusto anche di fronte alle modifiche del codice, puoi arrestare il gioco e riavviarlo con una nuova logica esattamente nello stesso punto. Più facile a dirsi che a farsi, ma è fattibile, ed è notevolmente più facile e portatile della ricerca della memoria per cambiare le istruzioni.
- A seconda della struttura e del determinismo del tuo gioco potresti essere in grado di effettuare registrazioni e riproduzioni . Se quella registrazione è appena finita "comandi di gioco" (ad esempio un gioco di carte), puoi modificare tutto il codice di rendering che desideri e riprodurre la registrazione per vedere le tue modifiche. Per alcuni giochi questo è "facile" come la registrazione di alcuni parametri iniziali (ad esempio un seme casuale) e quindi le azioni dell'utente. Per alcuni è molto più complicato.
- Fare sforzi per ridurre i tempi di compilazione . In combinazione con i summenzionati sistemi di salvataggio / caricamento o registrazione / riproduzione, o anche con sovrapposizioni o DLL, ciò può ridurre i tempi di risposta più di ogni altra cosa.
Molti di questi punti sono utili anche se non riesci a ricaricare dati o codice.
Aneddoti di supporto:
Su un PC RTS di grandi dimensioni (un team di circa 120 persone, principalmente C ++), esisteva un sistema di salvataggio dello stato incredibilmente profondo, utilizzato per almeno tre scopi:
- Un salvataggio "superficiale" non è stato inviato al disco ma a un motore CRC per garantire che i giochi multiplayer rimanessero in simulazione blocco-passo un CRC ogni 10-30 fotogrammi; questo ha assicurato che nessuno stava imbrogliando e ha catturato bug desincronici pochi fotogrammi dopo
- Se e quando si verificava un bug di desincronizzazione multiplayer, veniva eseguito un salvataggio molto approfondito in ogni fotogramma e di nuovo inviato al motore CRC, ma questa volta il motore CRC generava molti CRC, ciascuno per piccoli lotti di byte. In questo modo, potrebbe dirti esattamente quale porzione di stato aveva iniziato a divergere nell'ultimo fotogramma. Abbiamo riscontrato una brutta differenza di "modalità predefinita in virgola mobile" tra i processori AMD e Intel.
- Un normale salvataggio in profondità potrebbe non salvare, ad esempio, il fotogramma esatto dell'animazione riprodotta dalla tua unità, ma otterrebbe la posizione, la salute, ecc. Di tutte le tue unità, consentendoti di salvare e riprendere in qualsiasi momento durante il gioco.
Da allora ho usato la registrazione / riproduzione deterministica su un gioco di carte C ++ e Lua per il DS. Abbiamo collegato l'API progettata per l'IA (lato C ++) e registrato tutte le azioni dell'utente e dell'IA. Abbiamo utilizzato questa funzionalità nel gioco (per fornire un replay al giocatore), ma anche per diagnosticare i problemi: quando si verificava un arresto anomalo o un comportamento strano, tutto ciò che dovevamo fare era recuperare il file di salvataggio e riprodurlo in una build di debug.
Da allora ho anche usato overlay più di un paio di volte e l'abbiamo combinato con il nostro sistema "spider automatico di questa directory e carica nuovi contenuti sul palmare". Tutto ciò che dovremmo fare è lasciare il filmato / livello / qualunque cosa e rientrare, e non solo i nuovi dati (sprite, layout di livello, ecc.) Verrebbero caricati, ma anche qualsiasi nuovo codice nella sovrapposizione. Sfortunatamente, i palmari più recenti stanno diventando molto più difficili a causa della protezione dalla copia e dei meccanismi anti-hacking che trattano il codice in modo speciale. Lo facciamo ancora per gli script lua.
Ultimo ma non meno importante: puoi (e io, in varie circostanze specifiche molto piccole) fare un po 'di punzonatura con le anatre eseguendo direttamente l'applicazione di patch sui codici operativi. Funziona meglio se sei su una piattaforma e un compilatore fissi, e poiché è quasi impossibile da mantenere, molto soggetto a bug e limitato in ciò che puoi realizzare rapidamente, lo uso principalmente solo per reindirizzare il codice durante il debug. Si fa insegnare un inferno di molto sulla tua set di istruzioni in fretta, però.