Skip to content

Latest commit

 

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NOVA

CI Licence: MIT Tas: 47/48 Ko Plateforme: NumWorks PC: pygame

Un rogue-lite spatial, en deux éditions :

  • Calculatrice NumWorks — Python pur, tient dans les 32 Ko de tas de la machine, 25 images par seconde.
  • PC (pygame) — le même jeu, sans la camisole mémoire : carte de secteur dessinée, 12 améliorations, 3 difficultés, événements, particules, son chiptune synthétisé, et un affichage qui s'adapte à n'importe quelle résolution du 1366×768 à l'ultrawide 21:9.

NOVA sur PC

L'édition PC. La version calculatrice est plus bas.

Édition PC

Windows : double-clic sur pc/play.cmd · Linux/macOS : ./pc/play.sh

Le script installe tout (pygame-ce, numpy) dans un environnement isolé et lance le jeu. pc/build_exe.cmd en fait un .exe autonome avec icône.

Carte de secteur Boss
La carte de secteur à embranchements Un des cinq boss

Déplacement 8 directions, tir automatique, coop 2 joueurs (clavier et/ou manette), cinq boss aux mécaniques distinctes — murs à un seul trou, spirales, peignes de rayons, escortes, modules destructibles et canons sur les murs de l'arène. Le bestiaire grandit jusqu'au bout, un nouveau type par secteur, et les trois derniers reprennent chacun une mécanique de boss sur un vaisseau que tu peux abattre : un rayon, des anneaux, et dans le Vide un chasseur qui esquive en dash dès que tu te places sous lui. Les motifs sont denses mais jamais aléatoires : ils sont faits pour être lus, et chaque boss ménage une fenêtre où tout se tait, le temps de riposter. La carte, elle, est un vrai choix — un atelier de réparation n'est proposé que dans 54 % des secteurs, sur une seule branche, jamais avant le boss. Zoom toujours entier, arène de taille fixe quelle que soit la résolution, et 20 effets sonores synthétisés au démarrage (aucun fichier audio) — à écouter. Échap met en pause. Le tir étant automatique, M fait le tour de trois réglages — tout, canon coupé, silence — parce que vouloir se passer du canon n'est pas vouloir se passer du son. Tout est dans pc/README.md.

Édition NumWorks

Écran-titre

Tu pilotes un vaisseau à deux touches, tir automatique. Tu choisis ta route, tu récupères des cristaux, tu améliores ton vaisseau chez le marchand, tu affrontes un boss — cinq secteurs, puis le Vide, qui n'a pas de fin.

Combat Boss
Combat — tir auto, deux touches Boss — il descend sur toi
Choix Marchand
Choix de saut — trois routes Marchand — chaque ligne dit ce qu'elle fait

(Rendu de l'émulateur headless : les textes apparaissent en blocs parce que le stub ne dessine pas les glyphes. Sur la calculatrice, ce sont de vraies lettres.)

Installation

Le jeu est en 5 scripts. Ce n'est pas un caprice : MicroPython compile un module d'un seul bloc et garde tout son arbre syntaxique en mémoire, donc c'est le plus gros module qui fixe le pic — pas le total. Découpé, le jeu passe ; d'un seul tenant, il déclenche MemoryError avant même de démarrer.

Sur https://my.numworks.com/python, crée ces cinq scripts et colle le contenu du fichier correspondant dans dist/ :

Script à créer Contenu à coller
novad.py dist/novad.py
novae.py dist/novae.py
novaf.py dist/novaf.py
novag.py dist/novag.py
nova.py dist/nova.py

Puis envoie-les sur la calculatrice et lance nova (les quatre autres se chargent tout seuls). Détails et dépannage : docs/INSTALL.md.

Contrôles

Joueur 1 Joueur 2 (coop)
Se déplacer ← → 4 6
Tirer automatique automatique
Overdrive (bombe) EXE (ou OK en solo) EXE (partagé)

Le tir est automatique et le vaisseau ne bouge qu'horizontalement : deux touches par joueur. C'est une contrainte matérielle, pas une simplification — le clavier NumWorks est une matrice 9×6 sans diodes, donc trois touches dont deux partagent une ligne et deux une colonne font apparaître une quatrième touche fantôme. Le mapping ci-dessus est le résultat : aucune combinaison atteignable ne peut créer de fantôme, et tests/test_controls.py le vérifie à chaque exécution.

RETOUR n'est jamais lue : Epsilon peut interrompre le script dessus.

Le jeu

  • Trois routes par saut : patrouille, patrouille d'élite, marchand ou atelier de réparation. Sept nœuds par secteur, puis le boss.
  • 8 améliorations, 3 niveaux chacune. Chaque ligne du marchand affiche ce qu'elle fait et son prix, qui augmente de moitié à chaque niveau.
  • 5 types d'ennemis aux comportements distincts, plus un boss par secteur dont les points de vie s'ajustent à ta puissance de feu réelle.
  • Coop 2 joueurs sur la même calculatrice, coque et score partagés.
  • Le Vide : après les cinq secteurs, ça continue sans limite, pour le score.

Mesuré sur des parties simulées : 7 minutes de combat pur par partie, soit douze à quinze minutes une fois comptés les menus. Le design complet et ce que le matériel a imposé : docs/GAME_DESIGN.md.

Performances

La NumWorks donne à Python 32 Ko de tas, avec une API graphique sans sprite, sans blit et sans double tampon. NOVA n'efface jamais l'écran : chaque objet mobile s'efface à son ancienne position et se redessine à la nouvelle.

Mesuré par tests/test_combat.py sur de vraies parties :

Scénario Appels/frame (moy.) Pic Pixels repeints/frame
Secteur 1, première patrouille 42 52 902
Secteur 3, en profondeur 48 65 1 072
Secteur 5, élite 54 79 1 734
Secteur 5, coop 2 joueurs 59 82 1 835
Secteur 5, armement maximal 69 92 1 740

Budget : à 25 fps une image dure 40 ms, et Epsilon encaisse environ 6 000 appels kandinsky par seconde, soit ~240 appels par image. Le pire cas mesuré en utilise 92 — il reste 2,6× de marge. Côté pixels, une image repeint 1,3 % à 2,6 % de l'écran au lieu des 71 040 pixels qu'un effacement complet coûterait.

Mémoire : tools/memcheck.py fait tourner le vrai interpréteur MicroPython 1.17 — la version qu'embarque Epsilon — et cherche par dichotomie le plus petit tas capable de charger le jeu. Résultat actuel : 47 Ko sur un build 64 bits, dont les pointeurs sont deux fois plus larges que ceux de la calculatrice.

Les techniques employées et pourquoi elles comptent : docs/OPTIMIZATION.md.

Développement

python3 tools/build.py       # src/ -> dist/ (-54 %)
python3 tests/run_all.py     # suite complète, sur la source ET le build livré
python3 tests/test_balance.py  # simule des parties, mesure l'équilibrage
tools/mp/build.sh            # compile MicroPython 1.17 (une fois)
python3 tools/memcheck.py    # mesure le tas réellement nécessaire
python3 tools/screenshot.py  # régénère docs/img/

src/ est la source lisible et commentée. dist/ est ce qu'on colle dans la calculatrice — généré, jamais édité à la main.

Le projet embarque un émulateur headless (tools/emu/) qui réimplémente kandinsky et ion sans écran ni SDL, en comptant les appels de dessin. C'est lui qui permet de faire tourner de vraies parties en intégration continue et de prouver que le build minifié fonctionne : tests/run_all.py exécute la suite entière deux fois, sur la source puis sur dist/.

Test Ce qu'il empêche
test_controls Un mapping clavier qui produit des touches fantômes
test_termination Un combat qui ne finit jamais — sur calculatrice, il n'y a pas d'échappatoire
test_endless Un plantage d'index au secteur 30 du Vide
test_combat Une image qui dépasse le budget de dessin
test_balance Une courbe de difficulté plate ou injouable
tools/memcheck.py Le MemoryError au lancement

Licence

MIT — voir LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages