8 minuti. 43 secondi. Tanto ci ha messo un Samsung Galaxy S24 Ultra a sfornare un dungeon intero in JSON – piani, mob, HP, attacchi – dritto da un LLM on-device.
Pensate al vostro gioiellino tascabile, quel blocco di silicio Snapdragon, che macina 150 token di follia roguelike senza chiamare la nuvola. Niente lag. Niente dati succhiati dalle multinazionali. Solo magia IA locale che alimenta un RPG fatto in Unity. Parliamo di Phi-4-mini, il bestione Microsoft da 3.8B parametri, strizzato nel loop di un gioco Android.
E la ciliegina: funziona sul serio. JSON valido. Nomi mob in coreano inclusi (guasto nel prompt, ma chissenefrega?).
Perché infilare un modello linguistico in un roguelike?
I roguelike vivono di caos procedurale – replay infiniti, casualità brutale. Ma se quel caos diventasse intelligente? Un LLM che sussurra posizione nemici, statistiche boss, persino testi descrittivi, tutto cucito su misura per la vostra run. On-device significa immediato, privato, vostro. Niente chiavi API da implorare.
Questo dev non ha perso tempo. Ha scelto Phi-4-mini perché il drop ONNX di Microsoft è pronto all’uso – 4,9 GB quantizzato, si infila nei 12 GB di RAM come se fosse a casa sua. Modelli più piccoli? Crollano sul formato JSON, vomitano schifezze invece di array.
“[LLM] Generato in 181,4s (150 token max) JSON uscito: [ {“floor”:1,”mob”:”게으른 빵집 아들”,”hp”:50,”atk”:10}, {“floor”:4,”mob”:”elite”,”hp”:100,”atk”:20}, {“floor”:5,”mob”:”boss”,”hp”:200,”atk”:40} ]”
Pum. Output strutturato. Anche se i nomi mob echeggiano quelli del giocatore (sistemalo dopo, amico).
ONNX Runtime? Salvavita multipiattaforma. Binding C# per Unity via package di asus4. Cambi acceleratori – QNN per NPU Snapdragon, NNAPI, CoreML – con una riga di codice. Unity? Paradiso per roguelike 2D, build Android/iOS, C# ovunque. Niente vergogna Python.
Min SDK 31 lo inchioda – Android 12 sblocca le lib vendor per libcdsprpc.so di QNN. Scendi sotto? Bacia l’NPU addio.
Il vostro top di gamma regge un modello 3.8B in un gioco?
Risposta breve: A malapena. Lo Snapdragon 8 Gen 3 dell’S24 Ultra vanta l’NPU Hexagon, 12 GB RAM. Il dev ha spinto il modello da 4,9 GB via adb (94 secondi, una bellezza). L’APK resta snello.
Ma i numeri? Editor Mac (CPU): 246s, 0,45 tok/s. S24 solo CPU: 523s, 0,21 tok/s. QNN HTP? 490s, 0,31 tok/s. Il telefono è 2,1x più lento del Mac. NPU? Boh, piccolo balzo.
I log hanno spiattellato tutto: “Failed in loading stub: dlopen failed: library ‘libcdsprpc.so’ not found.” QNN si registra, ma il backend svanisce. Promesse NPU, consegne CPU.
La mia opinione bella calda – improvvisata, originale: È come l’iPhone del 2007. Le GPU erano giocattoli; la Metal API di Jobs ha sbloccato l’esplosione dei giochi mobile (Angry Birds, Infinity Blade). Gli NPU sono lì ora. Goffi, mezzo cotti, ma date sei mesi agli sviluppatori? I giochi IA on-device passano da gimmick a genere. Immaginate galassie procedurali alla No Man’s Sky, ma per dispositivo, per run, alimentate da LLM. La nuvola? Obsoleta per gli indie.
I build infernali – e le fix che hanno salvato la giornata
Vita da dev: 90% a combattere demoni.
Tokenizer? Niente tiktoken in C# per Phi. Ne ha scritto uno da tokenizer.json – vocabolario da 200k, merge come array (non stringhe, errore mio), hack GPT-2 byte, cache BPE.
KV cache decoding: 32 layer, 8 head, 128 head_size. Prefill prompt, decode token. I tensori si ribellavano – args ctor DenseTensor invertiti.
Path model.onnx? ../../.. diventato ../..
CompressReleaseAssets? 5 GB di StreamingAssets hanno sfondato l’array Java da 2,1 GB. Nuked cache Gradle (15 GB!), modello esiliato fuori Assets. adb push nelle cartelle app.
Font? TMP’s LiberationSans salta il coreano. Convertito AppleSDGothicNeo.ttc – Custom Range: 32-126,44032-55203,12593-12686 (inferno Hangul decimale).
Cast Newtonsoft.Json? JValue a JArray flop – i merge erano array, non stringhe.
Alla fine ha funzionato. JSON dungeon in arrivo.