Come giocare offline un gioco sviluppato con Phaser 3

Durante lo sviluppo di un gioco tramite il framework Javascript Phaser 3 ci si può domanda come poter rendere disponibile il proprio progetto anche durante l’assenza di connessione (si pensi a momenti di down del servizio oppure la modalità aerea del proprio dispositivo mobile).

Di seguito quindi la procedura per sfruttare la potenzialità del Service Worker di Javascript per cachare le risorse durante il primo avvio (con connessione attiva) e rendere così disponibili il gioco anche offline.

Prima di iniziare

E’ bene indicare che il Service Worker per poter funzionare in remoto (su uno spazio web) ha bisogno del protocollo HTTPS, mentre in locale non è strettamente necessario.

Creazione del Service Worker

Creare un file service-worker.js e inserirlo nella root del progetto (prerogativa) e includere il codice seguente:

const CACHE_NAME = 'phaser3-game-dynamic-cache-v1';

// Gestisce l'installazione del Service Worker (senza pre-caricamento delle risorse)
self.addEventListener('install', (event) => {
    event.waitUntil(self.skipWaiting()); // Salta subito allo stato "attivo"
});

// Gestisce le richieste e aggiunge in cache eventuali nuove risorse
self.addEventListener('fetch', (event) => {
    event.respondWith(
        caches.match(event.request).then((response) => {
            return response || fetch(event.request).then((networkResponse) => {
                // Aggiungi alla cache solo le risorse che non sono presenti
                return caches.open(CACHE_NAME).then((cache) => {
                    cache.put(event.request, networkResponse.clone());
                    return networkResponse;
                });
            });
        })
    );
});

// Pulizia della cache vecchia in fase di attivazione
self.addEventListener('activate', (event) => {
    event.waitUntil(
        caches.keys().then((cacheNames) => {
            return Promise.all(
                cacheNames.map((cacheName) => {
                    if (cacheName !== CACHE_NAME) {
                        return caches.delete(cacheName);
                    }
                })
            );
        })
    );
});

Avviare il Service Worker

Nella funzione windows.load, prima di inizializzare l’istanza del proprio gioco di Phaser, inserire il codice seguente che verifica il worker e lo istanzia:

   if ('serviceWorker' in navigator) {
        console.log('Service Worker supportato!');
        navigator.serviceWorker.register('service-worker.js')
            .then((registration) => {
                console.log('Service Worker registrato con successo: ' + registration);
            })
            .catch((error) => {
                console.log( 'Registrazione del Service Worker fallita: ' + error);
            });
    } else {
        console.log('Service Worker non supportato dal browser.');
    }

Gestire il Service Worker

E’ possibile verificare la funzionalità del service worker attraverso gli strumenti per sviluppatore del proprio browser desktop, accedendo alla tab Apllication > Service workers e utilizzando le funzione di Offline e Update On Reload.

Invalidare la cache del Service Worker

Durante lo sviluppo di un applicativo gestito dal Service Worker ci si potrebbe scontrare con l’involontario caricamento delle risorse dalla cache e non da files modificati. Questo significa che il servizio sta ancora leggendo dalla cache e non l’ha refreshata.

Un modo per farlo completamente è quello di usare il versioning del nome della cache.
Nell’esempio presente in questo articolo è stato infatti utilizzata la nomenclatura:

const CACHE_NAME = ‘phaser3-game-dynamic-cache-v1’;

Se necessario è quindi possibile cambiare il numero di versione del suffisso finale della stringa (da v1 a v2, v3, etc) in modo che il Service Worker capisca che è stato modificato e dunque reinizializzarà la cache nuovamente.

ALTERNATIVA: Invalidare singolarmente i files

Una alternativa, se si preferisce non cambiare CACHE_NAME è quella di aggiungere aggiungere dei “cache-busting” URL delle risorse caricate. Ad esempio, invece di /main.js, si può aggiornare il file a /main.js?v=2 ogni volta che se ne fa’ una modifica significativa. Questo metodo forza il browser a ricaricare l’asset in quanto riconosce l’URL come differente.

Verificare lo spazio occupato dalla cache del Service Worker

Per verificare quanto spazio è disponibile nel proprio browser web (può variare, anche di molto, tra i diversi browser desktop e mobile) utilizzare la funzione seguente:

if (navigator.storage && navigator.storage.estimate) {
  navigator.storage.estimate().then(({ quota, usage }) => {
    const quotaMB = (quota / (1024 * 1024)).toFixed(2); // Converti da byte a MB
    const usageMB = (usage / (1024 * 1024)).toFixed(2);
    const remainingMB = (quotaMB - usageMB).toFixed(2);

    console.log(`Spazio totale disponibile: ${quotaMB} MB`);
    console.log(`Spazio utilizzato: ${usageMB} MB`);
    console.log(`Spazio rimanente: ${remainingMB} MB`);
  });
}
https://www.desdinova.it
Aiuto aziende e professionisti che hanno bisogno di sviluppare in modo creativo, alternativo ed efficace la loro identità digitale e che desiderano ottenere visibilità e risultati concreti attraverso lo sviluppo di strumenti online dall'elevata innovazione e personalizzazione (3D, Realtà Virtuale, Realtà Aumentata, Advergame, etc)
Daniele Ferla
Aiuto aziende e professionisti che hanno bisogno di sviluppare in modo creativo, alternativo ed efficace la loro identità digitale e che desiderano ottenere visibilità e risultati concreti attraverso lo sviluppo di strumenti online dall'elevata innovazione e personalizzazione (3D, Realtà Virtuale, Realtà Aumentata, Advergame, etc)

Must Read