Darkwood Blog Blog
  • Articles
  • Veille
  • Releases
  • Créateurs
fr
  • de
  • en
Connexion
  • Blog
  • Articles
  • Veille
  • Releases
  • Créateurs

♟️ De Jev à Darkwaar : la création d'un jeu axé sur les décisions et l'incertitude

le 27 septembre 2026

Connectez-vous pour réagir à cet article

🚀 1

Jev est le premier modèle System One de TypeSafe. Vous lui envoyez un état et un ensemble de questions typées. Il renvoie des réponses typées, accompagnées de probabilités lorsque la question comporte plusieurs emplacements. Il n'y a pas de paragraphe à analyser.

Un modèle linguistique génératif se charge de l’autre tâche : il complète le texte. Vous décidez ensuite si ce texte correspond à un nom de service, un score ou un refus. Le contrat de Jev réside dans la décision elle-même : les réponses autorisées sont celles que vous avez répertoriées, et la réponse est l’une de ces réponses accompagnée d’une distribution.

Cette semaine, je n’ai pas intégré Jev à Darkwood Flow. Je me suis servi de l’étude de cette API pour créer un petit jeu sur l’instant qui précède un commit : en sais-je assez ?

Trois types de questions

L’appel HTTP est POST https://api.typesafe.ai/v1/systemone. Le corps de la requête est constitué d’un nom de modèle (jev-latest est l’alias que j’ai utilisé dans l’étude), d’un état et d’une carte de questions. La documentation officielle, consultée pour les besoins de l’étude le 21 septembre 2026, décrit trois types de questions.

Choix. Laquelle de ces options ? La réponse contient un choix, des probabilités et un niveau de confiance. Les probabilités correspondent à une distribution sur les critères que vous avez fournis.

Note. Où se situe-t-elle sur cette grille d’évaluation ordonnée ? La réponse contient une note, une légende qui reprend la grille d’évaluation, des probabilités et un niveau de confiance. Le score correspond à une position sur l’échelle ; il peut donc se situer entre deux étiquettes.

Noul. Cette affirmation est-elle vraie ? La réponse comporte un champ « noul », une valeur flottante comprise entre 0 et 1. Ce champ correspond au degré de soutien du modèle à l’égard de l’affirmation. Il ne s’agit pas d’une valeur booléenne, et la réponse « noul » documentée ne comporte pas de champ de confiance distinct. Les champs « choix » et « score » en comportent un.

Une requête évalue chaque question par rapport au même état. La documentation décrit ces questions comme indépendantes : une question ultérieure nécessitant une réponse antérieure constitue une deuxième requête. Je n’ai pas mesuré cette latence ici. La requête non authentifiée de l’étude sur l’API en production, sans clé, a renvoyé un code HTTP 403 et une erreur authentication_error. La variable TYPESAFE_API_KEY était vide ; cet article ne rapporte donc pas de chiffres de confiance, de taux de concordance ni de temps de réponse en production.

Les probabilités ne constituent pas une garantie

La confiance, qu’elle porte sur un choix ou un score, est un chiffre qui permet de prendre des décisions. Dans le code d’application, la structure utile est classique :

si la confiance est élevée et que le choix concerne la facturation → acheminer
si la confiance est faible, ou si le noul est proche de 0,5 → escalader

Cette branche correspond à une règle. Ce n’est pas une preuve. Une confiance élevée peut tout de même correspondre à un service erroné, car ce chiffre décrit l’intensité du pic de la distribution, et non si la réalité y correspond. Une valeur noul de 0,99 constitue un fort soutien à l’affirmation. Il s’agit néanmoins d’un nombre à virgule flottante que vous avez choisi de traiter comme un « oui ».

L’étude a conservé ces champs intacts lors du passage par l’ObjectResult de Symfony AI. Elle ne les a pas réduits à une valeur booléenne au sein du client du modèle. Une faible confiance est une réponse valable. Ce n’est pas une exception.

Cette même étude dispose d’un pont Platform local sous /Users/math/Sites/tests/ai, avec le package symfony/ai-jev-platform et la capacité INPUT_TEXT uniquement. Ce pont relève de la recherche locale. Il n’a pas été soumis, fusionné ni publié dans le cadre du travail de cette semaine. Symfony AI ne dispose toujours pas de capacité principale nommée « decision », « choice » ou « noul ». OUTPUT_STRUCTURED désigne le chemin d’accès au schéma JSON de Symfony pour un modèle génératif. La structure de Jev correspond aux questions contenues dans la requête. Il s’agit de mécanismes différents, et le pont ne prétend pas le contraire.

D’une distribution à une règle de casse-tête

Darkwaar15 — Signal n’appelle pas Jev. Il n’y a ni clé API, ni requête réseau, ni réponse échantillonnée. Les trois noms correspondent aux trois opérations effectuées par le joueur :

  • NOUL demande si les marques éclairées sont paires.
  • CHOICE demande quel motif de la liste correspond aux marques. Une marque éclairée vaut 1, une marque sombre vaut 0.
  • SCORE demande quelle bande correspond à la somme des barres : « bas » correspond à 0–1, « moyen » à 2–3, « haut » à 4 et plus.

Certains puits sont fermés au départ. Un carré compte pour l’opération en cours. Un losange représente du bruit et ne modifie jamais la réponse. L’ouverture d’un puits révèle une valeur qui a été fixée lors de la création du niveau.

La confiance dans le jeu correspond à un regroupement des réponses restantes, et non à une probabilité calibrée :

confiance = 1 lorsqu’une réponse est encore possible
confiance = 1 - (possible - 1) / (univers - 1) dans le cas contraire

L’univers est égal à 2 pour un « noul », au nombre de motifs pour un « choix », et à 3 pour un « score ». Le seuil de chaque niveau est de 0,70. Une réponse restante correspond à une confiance de 1, ce qui permet de franchir le seuil. Deux réponses restantes sur trois correspondent à 0,50, ce qui ne le permet pas. Le joueur peut tout de même appuyer sur « commit ». En dessous du seuil, la console répond « Signal insuffisant » et ne révèle pas la lecture. Au niveau du seuil ou au-dessus, une sortie erronée affiche la mesure et compte comme un échec. Trois échecs réinitialisent le niveau.

Voilà la traduction. La confiance de Jev peut refuser d’agir. L’énigme fait de ce refus la règle, et fait des puits cachés la raison pour laquelle la réponse n’est pas encore unique. Le niveau 7 est le cas le plus clair : deux barres suffisent pour que la somme reste élevée même si une troisième barre est encore fermée, car la hauteur fantôme de cette barre ne peut pas sortir de la bande. Ouvrir le losange ne change rien. La validation intéressante est celle que l’on effectue avant que tous les puits ne soient ouverts.

Les solutions sont des données, vérifiées par un script Godot sans interface graphique qui rejoue les sondes scriptées pour les huit niveaux, puis fait évoluer la scène réelle à travers une validation erronée, un rejet à faible confiance, un échec affichant la lecture, un redémarrage et une réussite. Les deux vérifications ont affiché « pass » avant l’exportation HTML5.

La console

Le jeu se trouve dans le monorepo Darkwaar sous le nom 2026-09-27-01M3H4X9806QZ6Z7D85F, identifiant hérité darkwaar15. Godot 4.6, fenêtre d’affichage en mode portrait 648×1152, une scène Control. Trois scripts assurent le fonctionnement :

  • rules.gd contient les huit niveaux et la règle de confiance. Il n’effectue aucun rendu.
  • signal_view.gd dessine les puits, les connecteurs et la jauge de confiance. Le repère sur la jauge correspond à la porte.
  • main.gd constitue la boucle de validation : sondage, sélection, validation, échec, redémarrage et dernier écran.

L’entrée, l’évaluation et la sortie sont empilées sur le canevas en mode portrait. Les puits fermés conservent leur forme, ce qui permet de voir un losange avant d’y gaspiller une sonde. L’indicateur est cyan sous la porte et orange dès que la réponse est unique. La souris et le toucher permettent tous deux d’interagir avec les puits et les boutons.

Niveau 1, un puits ouvert, la confiance est déjà à la porte

Niveau 5, un choix encore partagé entre deux motifs, confiance à 0,50

Niveau 3, ouvrir un carreau laisse la confiance à 0

L’exportation Web correspond à la même scène. La commande bin/build-game darkwaar15 --validate --zip a compressé les fichiers main.gdc, rules.gdc et signal_view.gdc. bin/smoke-web-build darkwaar15 a chargé le canevas en 648×1152, a détecté une image non vide et n’a signalé aucune erreur fatale de page. Un clic sur « Commit » dans la version navigateur a affiché « Choisissez une sortie » alors que rien n’était sélectionné, ce qui indique que la boucle HTML5 prend en charge les entrées.

Publication

Le jeu est disponible sur itch.io à l’adresse darkwoodcom.itch.io/darkwaar15. Le canal HTML5 correspond à la version décrite dans cet article. J’ai demandé cette URL et j’ai obtenu un code HTTP 200.

L'article sur Darkwaar est disponible à l'adresse darkwaar.com/blog/2026-09-27-darkwaar15. Il a renvoyé un code d'état HTTP 200, et la page contient la notice d'utilisation, les trois captures d'écran et le lien vers itch.

Flow reste un pipeline

L'étude initiale se demandait si Jev avait sa place au sein de Flow. La réponse fournie par le code, inchangé cette semaine, est que Flow dispose déjà d'un emplacement dédié à la prise de décision. Un « job » est de type JobInterface : une entrée, une valeur de retour. Le paquet est un Ip. Remplacer un « job » de règle par un « job » Jev modifie le contenu du paquet. Cela ne change ni le pilote, ni la stratégie IP, ni le graphe d’étapes.

Je n’ai pas ajouté Decision<T>, Choice<T> ni un JevDriver à darkwood/flow. Je n’ai pas exécuté de test d’intégration Flow, et je n’en ai pas publié. Une réponse à faible niveau de confiance resterait un résultat de tâche normal. L’escalade resterait le PHP de la tâche suivante. Ce travail est reporté. Les livrables de cette semaine sont la recherche, le pont Platform local qui n’a pas été soumis, et Darkwaar15.

Objectif de l’expérience

Une procédure de décision est un état, un ensemble fermé de réponses et une règle déterminant quand on est autorisé à agir. Jev est une version à distance des deux premiers éléments, à laquelle s’ajoute une distribution. Darkwaar15 conserve l’ensemble fermé et remplace la distribution par un fait visible par le joueur : le nombre de réponses que les puits fermés peuvent encore atteindre. La porte constitue la troisième partie, et c’est celle qui relève de l’application.

La console refusera un bouton correct en cas d’activation prématurée. C’est cette propriété que je souhaitais ressentir. Une quantité suffisante d’informations constitue un état du casse-tête, de la même manière qu’une confiance suffisante constitue un état du programme, et aucun de ces deux chiffres ne garantit que la validation était correcte.

Connectez-vous pour réagir à cet article

🚀 1

Site

  • Plan du Site
  • Contact
  • Mentions légales

Network

  • Hello
  • Blog
  • Apps
  • Photos

Social

Darkwood 2026, tous droits réservés