IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Créer des jeux avec Go : 3 mois sans LLM contre 3 jours avec LLM ! par Mariano Gappa

Le , par Mariano Gappa

0PARTAGES

3  0 
Créer des jeux avec Go : 3 mois sans LLM contre 3 jours avec LLM ! par Mariano Gappa


Introduction

Après 15 ans en tant qu'ingénieur logiciel, je me suis rendu compte que je n'avais jamais réellement créé et publié de jeu.

Ayant grandi en Argentine 🇦🇷 où je jouais aux cartes avec mes amis, j'ai décidé d'en choisir un parmi ceux-là. Je me suis posé la question suivante :


Truco : 3 mois sans LLM

Le 18 juin 2024, j'ai commencé à créer Truco pendant mon temps libre. En tant que développeur backend Go de longue date, le backend était une évidence. Le défi résidait dans l'interface utilisateur et l'hébergement à long terme sans serveur payant.


C'était avant les LLM, donc chaque détail devait être réglé à la main. Il m'a fallu environ 3 mois d'essais et d'erreurs pour le mettre au point.

Je n'avais jamais prévu de faire de la publicité ou de monétiser le jeu ; je voulais juste le terminer et peut-être donner à quelqu'un la joie de rejouer au jeu de son enfance. Un an plus tard, sans aucun effort supplémentaire de ma part, les gens y jouent toujours !


Si vous souhaitez le découvrir, voici quelques liens :

Truco (jouer au jeu)

Backend en Go

Frontend en React (ne me jugez pas 🤷*♂️ c'est le mieux que je puisse faire avec une heure de connaissances en React)

« Escoba » : 3 jours avec les LLM

Un an plus tard, lors d'une visite à ma famille en Argentine, j'ai appris à mon neveu à jouer à Escoba, le deuxième jeu de cartes le plus populaire du pays (malgré ce qu'affirme ChatGPT).


Les LLM étant désormais courants, je me suis demandé à quel point la création d'un jeu pouvait être plus rapide. J'ai donc décidé de le tester.

J'ai cloné le backend de Truco et j'ai donné à Claude une longue instruction générative expliquant les règles d'Escoba et lui demandant de refactoriser le code pour l'implémenter. À ma grande surprise, cela a fonctionné presque parfaitement dès la première tentative 😱. Pendant un instant, je me suis dit : adieu, mon travail 😰.


Le seul bug que j'ai trouvé était qu'il utilisait incorrectement la fonction append à un endroit et modifiait les actions. À part cela, je n'ai ajouté que quelques fonctionnalités supplémentaires (comme un meilleur bot).

Le frontend était une autre histoire ; il m'a fallu quelques jours pour le mettre au point. Le véritable défi n'était probablement pas seulement le LLM, mais aussi mes propres compétences en React, combinées à la configuration inhabituelle consistant à laisser une fonction WASM black-box gérer l'état du jeu. Le débogage en JavaScript n'a pas non plus facilité les choses.

Si vous souhaitez le découvrir, voici quelques liens :

Escoba (jouer au jeu)

Backend en Go

Frontend en React

Étape par étape : comment créer votre propre jeu

Je suppose que vous êtes venu ici pour voir s'il n'est pas trop difficile de vous y essayer vous-même ! Je vais donc vous donner les bases minimalistes pour créer votre propre jeu avec cette pile.

J'ai écrit un ensemble minimaliste de dépôts pour le jeu Tic-Tac-Toe afin que vous puissiez les forker pour commencer :

https://github.com/marianogappa/tictactoe-backend, https://github.com/marianogappa/tictactoe-frontend

Vous pouvez le consulter ici :

https://marianogappa.github.io/tictactoe-frontend/


Côté backend

Un backend au tour par tour est simple à décrire :

  • Initialisez une structure GameState (par exemple, configuration initiale du plateau, liste d'actions vide).
  • Implémentez CalculatePossibleActions, afin que les clients sachent ce qui est valide.
  • Ajoutez RunAction pour modifier le GameState.
  • S'il y a un bot, écrivez une fonction pour choisir une action à partir de l'état actuel.

C'est tout !

Remarque : oubliez les parties entre humains, à moins que vous ne soyez prêt à payer pour ce serveur.

Côté front-end

Je ne suis pas un expert en front-end, mais les tâches sont simples :

  • Appelez le backend pour créer un nouveau GameState.
  • Affichez-le dans l'interface utilisateur.
  • Laissez le joueur choisir une action parmi les options valides.
  • Appelez le backend pour appliquer l'action.
  • Déclenchez l'action du bot lorsque c'est son tour.

C'est tout !

Interopérabilité côté backend

Pour transcompiler le backend en WASM, vous pouvez compiler avec :

Code GO : Sélectionner tout
GOARCH=wasm GOOS=js go build -o main.wasm main.go


Mais cela produit des binaires énormes (ce qui est lent sur mobile). Utilisez TinyGo pour des binaires plus petits.

Avant de compiler, vous avez besoin d'un point d'entrée différent pour les fonctions que vous allez mettre à la disposition du frontend. Créez un fichier main.go différent qui exporte les fonctions dont vous avez besoin, et protégez-le via des drapeaux de compilation :

Code GO : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//go:build tinygo 
// +build tinygo 
  
package main 
  
[...] 
  
func main() { 
	js.Global().Set("trucoNew", js.FuncOf(trucoNew)) 
	js.Global().Set("trucoRunAction", js.FuncOf(trucoRunAction)) 
	js.Global().Set("trucoBotRunAction", js.FuncOf(trucoBotRunAction)) 
	select {} 
} 
  
var ( 
	state *truco.GameState // "Global variable" for the GameState 
	bot   truco.Bot 
)


N'oubliez pas de bloquer à la fin de main() avec select {} pour empêcher le programme de se fermer immédiatement.

Interopérabilité des données backend

GameState est généralement une structure libre que vous définissez dans Go. WASM ne peut pas sérialiser/désérialiser directement les structures. L'astuce consiste à tout passer en JSON. Après avoir fouillé dans la documentation TinyGo, voici la formule :

Code GO : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func trucoRunAction(this js.Value, p []js.Value) interface{} { // Always this signature 
	// Read the input JSON 
    jsonBytes := make([]byte, p[0].Length())  
	js.CopyBytesToGo(jsonBytes, p[0]) 
  
	// 1. Decode the input JSON to your struct 
    // 2. Run your Go code, return an output struct 
	// 3. Encode the output struct to JSON 
	newBytes := _runAction(jsonBytes) 
  
	// Return the output JSON 
	buffer := js.Global().Get("Uint8Array").New(len(newBytes)) 
	js.CopyBytesToJS(buffer, newBytes) 
	return buffer 
}


Interopérabilité côté frontend

Enfin, appelez les fonctions backend depuis le frontend et [suivez le GameState dans une variable globale]((https://github.com/marianogappa/truc...meState.js#L19) :

Code GO : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
function jsRunAction(data) { 
    const encoder = new TextEncoder(); 
    const encodedData = encoder.encode(JSON.stringify(data)); 
    const result = trucoRunAction(encodedData); 
    const json = new TextDecoder().decode(result); 
    return JSON.parse(json); 
} 
  
let gameState = jsNewGame(); 
  
// Note that RunAction doesn't take a GameState. 
// WASM is the source of truth; your frontend can't mutate it. 
gameState = jsRunAction(action);


Chaque fois que vous modifiez le backend, vous devez le recompiler en WASM et remplacer l'ancien fichier dans le frontend. J'ai ajouté ceci dans le Makefile :

Code : Sélectionner tout
1
2
3
4
5
6
7
 
compile_library: 
	cd $(GOPATH)/src/github.com/marianogappa/escoba && \ 
	TINYGOROOT=/usr/local/Cellar/tinygo/0.38.0 tinygo build -o main.wasm -target wasm main_wasm.go && \ 
	mv main.wasm $(CURDIR)/public/wasm/wasm.wasm && \ 
	cp /usr/local/Cellar/tinygo/0.38.0/targets/wasm_exec.js $(CURDIR)/public/wasm/wasm_exec.js && \ 
	cd -


Notez que je copie également wasm_exec.js. C'est une condition requise pour exécuter le code WASM. L'autre condition requise est d'ajouter la balise script à la tête (HEAD) du fichier HTML :

Code GO : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  
    <script src="wasm/wasm_exec.js"></script> 
	<script> 
        const go = new Go(); // Defined in wasm_exec.js 
        const WASM_URL = 'wasm/wasm.wasm'; 
  
        var wasm; 
        let wasmReady = false; 
  
        if ('instantiateStreaming' in WebAssembly) { 
            WebAssembly.instantiateStreaming(fetch(WASM_URL), go.importObject).then(function (obj) { 
                wasm = obj.instance; 
                go.run(wasm); 
                wasmReady = true; 
            }) 
        } else { 
            fetch(WASM_URL).then(resp => 
                resp.arrayBuffer() 
            ).then(bytes => 
                WebAssembly.instantiate(bytes, go.importObject).then(function (obj) { 
                    wasm = obj.instance; 
                    go.run(wasm); 
                    wasmReady = true; 
                }) 
            ) 
        } 
    </script>


Dépannage

Le fichier WASM ne se charge pas

Cela fonctionne automatiquement dans Github Pages, mais localement, vous devez servir les fichiers via HTTP. Vous pouvez utiliser http-server pour cela :

Code : Sélectionner tout
npx http-server ./public -p 8080


Rendez-vous ensuite sur [c]http://localhost:8080[/c dans votre navigateur.

Conclusion

J'ai pris beaucoup de plaisir à créer ces jeux et j'espère que vous trouverez intéressant de voir comment ils fonctionnent. J'espère également que cela vous sera utile pour créer vos propres jeux ! Si vous avez des questions, n'hésitez pas à me contacter.


Source : "Making Games in Go: 3 Months Without LLMs vs 3 Days With LLMs!"

Et vous ?

Pensez-vous que cette méthode est crédible ou pertinente ?
Quel est votre avis sur le sujet ?

Voir aussi :

Le langage Go souffle ses 15 bougies et atteint sa position la plus haute sur l'indice Tiobe. Google annonce que le nombre d'utilisateurs de Go a plus que triplé au cours des cinq dernières années

Comment j'utilise les LLM en tant qu'ingénieur logiciel, par sean goedecke

Le jour où j'ai appris à l'IA à comprendre le code comme un développeur senior, par Namanyay Goel
Vous avez lu gratuitement 1 050 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.

Une erreur dans cette actualité ? Signalez-nous-la !