256 lines
16 KiB
Markdown
256 lines
16 KiB
Markdown
# Blocodex natif — connaissances, matière et stocks
|
||
|
||
Ticket META-01, branche `codex/blocodex-natif`, cible Minecraft **26.3-pre-2**.
|
||
Le Blocodex appartient au mod Sanctuary. Il est disponible sans appareil,
|
||
recette ni déblocage. La mémoire personnelle, le recensement du terrain et
|
||
celui des stocks forment un socle commun aux futures palettes de structures,
|
||
règles d’expansion et règles du shop. Les relevés datés ajoutent la temporalité
|
||
nécessaire à une future lecture de l’histoire économique du serveur.
|
||
|
||
## Contrat des informations
|
||
|
||
La mémoire est personnelle : une identité de joueur (UUID), dans une sauvegarde
|
||
de serveur, partagée entre ses dimensions. Les indicateurs sont indépendants.
|
||
|
||
| Information | Sens |
|
||
| --- | --- |
|
||
| Inconnu | Aucune observation, possession, pose ni statistique de minage ou de jet. C'est un état calculé, pas une étape enregistrée. |
|
||
| Vu | Le premier bloc rencontré par le regard du joueur, à au plus 32 blocs, observé côté serveur tous les 5 ticks. Les obstacles arrêtent le rayon ; les chunks absents ne sont pas chargés. Ce relevé ne couvre pas chaque pixel du champ de vision. |
|
||
| Miné | Compteur vanilla `mined` du bloc. Ses règles sont conservées : notamment pas de minage créatif, ni de minage sans l'outil requis. |
|
||
| Déjà possédé | Le bloc, sous forme d'item, a été présent dans l'inventaire personnel ou sur le curseur d'un menu. Les statistiques vanilla de ramassage et de jet prouvent aussi une possession passée. |
|
||
| Jeté | Compteur vanilla `dropped` de l'item du bloc. Il compte les unités volontairement jetées, pas les objets éjectés à la mort ni le butin produit par le bloc cassé. |
|
||
| Posé | Nombre de placements réussis par le joueur avec un item de bloc, y compris en créatif. Une tentative refusée, une interaction ou un placement par commande ne compte pas. |
|
||
| En inventaire | Quantité actuellement dans l'inventaire personnel, équipement et curseur compris. Les coffres ouverts, ender chests et contenus imbriqués des boîtes ne sont pas inclus. |
|
||
|
||
Les blocs sont identifiés par leur identifiant de registre ; les propriétés
|
||
d'état (orientation, humidité, etc.) ne créent pas une nouvelle fiche. Deux
|
||
identifiants restent distincts : une torche murale peut être vue et posée tandis
|
||
que l'item possédé correspond à la torche debout. Les noms des blocs inconnus
|
||
restent consultables, comme un catalogue ; cette version ne décide pas d'une
|
||
politique de secrets ou de verrouillage des recettes.
|
||
|
||
L'inventaire est observé chaque tick serveur, après les transactions de menus
|
||
et avant la consommation d'un item placé. Les statistiques de ramassage/jet
|
||
complètent ce relevé. Une mutation d'inventaire entièrement réalisée entre ces
|
||
points par un autre mod ne peut pas être reconstruite après coup.
|
||
Les spectateurs ne découvrent pas de blocs par le regard.
|
||
|
||
## Persistance et arrivée dans une sauvegarde antérieure
|
||
|
||
Contrat additif v1 : fichiers `data/sanctuary-blocodex/<uuid>.json`, enveloppe
|
||
avec `schema: 1` et UUID, puis observations, possessions et poses par identifiant.
|
||
Les statistiques vanilla restent dans leurs propres fichiers et sont seulement
|
||
lues. Aucune conversion du terrain, des paramètres de génération, des chunks,
|
||
du journal d'expansion ou des statistiques existantes n'est effectuée.
|
||
|
||
Sans fichier Blocodex, les observations et poses commencent vides. Le minage,
|
||
le jet et les preuves de possession sont disponibles depuis les statistiques
|
||
vanilla déjà présentes. On n'invente pas les observations ni les poses passées
|
||
à partir de `used`, qui compte aussi d'autres usages.
|
||
|
||
Les changements sont sauvegardés tous les 600 ticks, lors de la sauvegarde du
|
||
serveur, à la déconnexion et à l'arrêt. Un crash peut perdre les dernières
|
||
observations ou poses non sauvegardées. Un fichier invalide ou d'une version
|
||
inconnue désactive la mémoire concernée et n'est jamais remplacé silencieusement.
|
||
Les identifiants de mods absents sont conservés sur disque. Les anciennes
|
||
versions de Sanctuary ignorent ce répertoire additionnel ; les poses réalisées
|
||
pendant un retour à une ancienne version ne peuvent pas être récupérées.
|
||
|
||
## Réutilisation
|
||
|
||
`BlockKnowledgeService.knowledge(player, block)` et `snapshot(player)` renvoient
|
||
des valeurs immuables calculées côté serveur. Le service expose aussi sa santé ;
|
||
un consommateur doit refuser une condition de progression si la mémoire est
|
||
indisponible, plutôt que d'interpréter une panne comme une découverte vierge.
|
||
`BlockKnowledgeEvents.CHANGED` permet de réagir aux observations, possessions,
|
||
poses et changements de statistiques. Les écouteurs s'exécutent sur le thread
|
||
serveur ; ils ne constituent pas un journal transactionnel de récompenses.
|
||
|
||
Cette livraison ne verrouille aucune recette et n'accorde aucune récompense.
|
||
Palettes disponibles, recherches, progression et structures pourront ensuite
|
||
définir leurs propres conditions en utilisant cette API commune.
|
||
|
||
### Palettes de structures
|
||
|
||
`BlockKnowledgeService.palette(player, condition, tag)` croise les connaissances
|
||
du joueur avec une famille de matériaux. Les critères `BlockKnowledgeFacet`
|
||
sont combinables avec `and` et `or` : vus **ou** déjà possédés, minés **et**
|
||
actuellement portés, etc. Le résultat immuable garde les identifiants triés et
|
||
les quantités réellement portées.
|
||
|
||
```java
|
||
var candidates = BlockKnowledgeService.palette(player,
|
||
BlockKnowledgeFacet.SEEN.or(BlockKnowledgeFacet.POSSESSED),
|
||
BlockKnowledgeService.NATURAL_STRUCTURE_MATERIALS);
|
||
```
|
||
|
||
Le tag `sanctuary:structure_palette/natural` fournit une première famille de
|
||
pierres, terres, bois, feuilles et autres matériaux naturels, modifiable par
|
||
datapack. D'autres tags pourront définir des palettes minérales, végétales ou
|
||
propres à un biome. Le choix des couleurs, les contraintes physiques des blocs,
|
||
les quantités nécessaires et la construction de la structure appartiendront au
|
||
moteur de structures : une sélection de palette ne réserve aucun stock et ne
|
||
place aucun bloc.
|
||
|
||
## Recensement du terrain chargé
|
||
|
||
`TerrainCensus.snapshot(server)` expose une distribution des blocs par dimension ;
|
||
`TerrainCensus.chunkSnapshot(level, pos)` fournit le détail d’un chunk déjà
|
||
chargé. Ces lectures se font sur le thread serveur et renvoient des valeurs
|
||
immuables. Elles parcourent les chunks `FULL` déjà accessibles, sans charger
|
||
de chunk absent ni attendre la fin d’une génération.
|
||
|
||
Le comptage utilise les palettes des sections de 16 × 16 × 16 blocs. Il regroupe
|
||
les orientations et autres propriétés sous l’identifiant du bloc. Les blocs
|
||
d’air sont exclus ; l’eau et la lave conservent leurs identifiants de blocs.
|
||
Le budget est de **16 sections non vides par tick serveur**, partagé entre les
|
||
dimensions et les demandes du même tick. Une section entièrement vide est
|
||
reconnue par ses métadonnées, sans parcourir sa palette.
|
||
|
||
Le relevé est progressif. Une section modifiée est retirée des totaux dès que
|
||
sa révision change, puis remise dans la file de comptage. Les sections et
|
||
chunks déchargés sortent du relevé. Un consommateur dispose, par dimension ou
|
||
chunk, du nombre de sections chargées et comptées, du tick de capture, du tick
|
||
du dernier comptage effectué et de l’âge de la plus ancienne attente.
|
||
`complete()` et `coverage()` décrivent la couverture **des zones chargées**.
|
||
Une couverture de 100 % ne signifie jamais que toute la sauvegarde a été lue.
|
||
|
||
Pendant un rattrapage, zéro bloc compté ne prouve donc pas l’absence de ce bloc.
|
||
Les futures règles d’expansion devront fixer leur couverture minimale et leur
|
||
zone d’étude avant de prendre une décision. Les résultats en mémoire sont
|
||
reconstruits après redémarrage ; ce service n’écrit pas dans les chunks et ne
|
||
modifie pas leur génération.
|
||
|
||
## Recensement des stocks présents
|
||
|
||
`StockCensus.snapshot(server)` photographie les objets accessibles au tick de
|
||
la demande, sur le thread serveur. Le parcours des slots et des entités chargées
|
||
est effectué à la demande ; aucun abonnement ne le relance à chaque tick.
|
||
Les quantités sont des unités d’items, tous
|
||
types confondus : un lingot, un outil ou une graine sont comptés même s’ils ne
|
||
correspondent pas à un bloc. Les composants, l’usure et les enchantements ne
|
||
créent pas de nouveaux identifiants de stock dans cette version.
|
||
|
||
| Catégorie | Couverture |
|
||
| --- | --- |
|
||
| `playerItems` | Joueurs connectés : inventaire personnel, équipement et curseur du menu. Le contenu du menu ouvert n’est pas additionné. |
|
||
| `blockContainerItems` | Entités de blocs déjà instanciées dans les chunks chargés, qui exposent l’interface `Container` : coffres, hoppers, fours, pots décorés, etc. Chaque moitié d’un double coffre est comptée une fois. |
|
||
| `entityContainerItems` | Entités chargées qui exposent `Container`, notamment les wagonnets et bateaux à coffre. |
|
||
| `groundItems` | Quantités des `ItemEntity` chargées et encore présentes au sol. |
|
||
|
||
Le relevé ne déballe **aucune table de butin**. Tout conteneur dont la table
|
||
reste à résoudre est ignoré avant la lecture de ses slots ; son existence
|
||
augmente `pendingLootContainers`. Les entités de blocs encore stockées sous
|
||
forme de NBT et non instanciées sont également laissées intactes, avec leur
|
||
nombre dans `pendingBlockEntities`. Leur contenu n’est pas remplacé par une
|
||
estimation.
|
||
|
||
La couverture exclut les joueurs hors ligne, les chunks et entités déchargés,
|
||
les ender chests, le contenu imbriqué des shulker boxes et bundles, les grilles
|
||
de fabrication en cours dans l’inventaire ou l’établi (`menuInputsIncluded()`
|
||
est faux), les inventaires et équipements des créatures. Le résultat de
|
||
fabrication affiché avant validation ne constitue pas un stock supplémentaire.
|
||
Elle exclut aussi les objets internes
|
||
des entités de blocs qui n’exposent pas `Container`, comme les aliments d’un feu
|
||
de camp ou le livre d’un pupitre. Une shulker box portée compte comme un item ;
|
||
une shulker box posée et chargée expose son conteneur. Les exclusions figurent
|
||
dans le contrat de couverture ; `partial()` reste vrai.
|
||
|
||
Ce relevé indique où se trouvent les unités observées. Il ne les réserve pas,
|
||
ne les transfère pas et n’évalue pas leur prix. Ajouter le terrain aux stocks
|
||
ne donne pas une quantité immédiatement vendable : une roche dans un chunk
|
||
reste différente d’un item dans un coffre.
|
||
|
||
## Consultation et futurs consommateurs communs
|
||
|
||
`WorldCensusService.capture(server)` rassemble les deux relevés pour une même
|
||
lecture côté serveur. Le consommateur réutilise cet instantané pendant son
|
||
calcul et conserve ses informations de couverture. Le shop et les expansions
|
||
pourront ainsi consulter la même base, avec leurs propres règles de fraîcheur,
|
||
de portée géographique, de prix, de consommation et de réservation.
|
||
|
||
Les diagnostics suivants sont réservés aux opérateurs :
|
||
|
||
```text
|
||
/sanctuary census
|
||
/sanctuary census block minecraft:stone
|
||
/sanctuary census item minecraft:gold_ingot
|
||
```
|
||
|
||
Le résumé présente la couverture du terrain par dimension, les quatre catégories
|
||
de stocks et les conteneurs au butin encore indéterminé. Le Blocodex personnel
|
||
accessible par **B** conserve les données du joueur ; ces diagnostics ne diffusent
|
||
pas les inventaires agrégés aux autres joueurs.
|
||
|
||
## Relevés datés — portée de l’alpha.23
|
||
|
||
La collecte regroupe les activités observées par **jour civil UTC**, pour
|
||
l’ensemble du serveur, sans attribution à un UUID ou à une dimension :
|
||
|
||
| Action | Registre et unité |
|
||
| --- | --- |
|
||
| `mined` | `block` : nombre de blocs minés, selon les règles des statistiques vanilla. |
|
||
| `placed` | `block` : placements réussis par le joueur, créatif inclus et spectateurs exclus. |
|
||
| `picked_up` | `item` : unités ramassées observées par les statistiques vanilla. |
|
||
| `dropped` | `item` : unités volontairement jetées observées par les statistiques vanilla. |
|
||
| `crafted` | `item` : unités fabriquées créditées au joueur par les statistiques vanilla. |
|
||
|
||
Chaque combinaison conserve son action, son registre, son identifiant et une
|
||
quantité entière sur 64 bits, saturée à la valeur maximale en cas de dépassement.
|
||
Un compteur de minage n’est pas transformé en nombre d’items produits. Les actions
|
||
antérieures à l’installation ne sont pas réparties artificiellement entre des
|
||
dates à partir des statistiques cumulées de Minecraft.
|
||
|
||
`MaterialActivityHistory.snapshot(server, day)` expose un instantané immuable
|
||
avec le jour, les compteurs, `recorded` et `unsaved`. Un jour sans données
|
||
enregistrées demeure inconnu ; il ne constitue pas un historique d’activité nulle.
|
||
Les opérateurs peuvent consulter `/sanctuary history` ou préciser une date avec
|
||
`/sanctuary history 2026-09-10`. La commande affiche au plus les 16 lignes aux
|
||
quantités les plus élevées et indique combien ont été omises ; l’API conserve
|
||
l’ensemble des compteurs du jour.
|
||
|
||
La persistance additionnelle utilise `data/sanctuary-activity/YYYY-MM-DD.json`,
|
||
avec un schéma 1 et des dates UTC. Elle est séparée de la mémoire personnelle
|
||
et des chunks. Les écritures ont lieu tous les **600 ticks**, à la sauvegarde
|
||
et à l’arrêt du serveur, ainsi qu’au changement de jour observé par le service.
|
||
Un crash peut perdre les derniers relevés non sauvegardés, soit normalement
|
||
jusqu’à 30 secondes de jeu à 20 ticks par seconde. Le fichier conserve les
|
||
identifiants de mods absents ; il refuse les schémas inconnus, doublons,
|
||
compteurs invalides et changements externes. Une erreur arrête la collecte et
|
||
rend le service indisponible jusqu’à réparation puis redémarrage, en conservant
|
||
le fichier en cause. Les limites sont de 100 000 tuples et 16 Mio par jour.
|
||
|
||
Ces relevés permettent de distinguer des périodes d’activité. Ils ne conservent
|
||
pas d’historique des instantanés de stocks, ne couvrent pas la fabrication automatique des
|
||
machines et n’établissent ni consommation, ni perte, ni destination des objets.
|
||
Ils ne retracent pas chaque transfert entre coffres ou chaque changement de propriétaire, et
|
||
ne constituent pas un journal transactionnel d’achats, de récompenses ou de
|
||
réservations. Le **ballast**, ses unités, ses conversions et sa traduction en
|
||
géologie restent à concevoir dans le [cahier de cosmologie](cosmologie.md).
|
||
Aucun objet n’est consommé et aucune Backroom n’est générée par ces mesures.
|
||
|
||
## Référence WSMC retrouvée
|
||
|
||
La recherche locale a retrouvé une partie du travail précédent dans
|
||
`/Users/koka/Documents/sanctuary/Gameplay/blocodex` :
|
||
`ClientVoxelProjectBuilder` convertit des apparences de blocs et d’items en
|
||
volumes/couches de blocs ; `BlocodexStudioPalettes` sélectionne des matériaux
|
||
opaques appris. Le projet conserve aussi un instantané WSMC de 1 881 entrées
|
||
(1 168 blocs, 490 items, 223 mobs), issu de Minecraft 1.21.11.
|
||
|
||
Cette référence reste historique. La nouvelle API fournit la connaissance et
|
||
les candidats de palette ; la traduction de modèles d’entités en structures
|
||
(visage de creeper, squelette géant, etc.) reste un chantier distinct. Aucun
|
||
générateur d’entités ni import de ce snapshot ancien n’est ajouté au registre
|
||
de Minecraft 26.3 par le socle méta.
|
||
|
||
## Validation
|
||
|
||
Validation locale du 10 septembre 2026 : `./gradlew check build assemblePack`
|
||
passe, avec **24 GameTests natifs réussis**. Le client graphique vérifie les
|
||
widgets et les messages réels dans un nouveau monde intégré, avec B sans droit
|
||
opérateur, observation serveur et possession conservée après retrait du stock.
|
||
Les tests de stockage passent. Les [preuves et limites](testing-alpha23.md)
|
||
détaillent le protocole, l’artefact et son empreinte. Alpha.23 assemblée localement ;
|
||
publication du MRpack et mise à jour du canal demandées, en préparation.
|