nxsand : Une grille GPU pour le sable
nxsand est une simulation de sable sur Switch avec une cible de développement desktop. Les matériaux occupent une grille d’entiers. Des passes mettent cette grille à jour et un parcours de rendu transforme les identifiants en image.
Langages du dépôtC++ 80.07%7
Parts calculées à partir des octets GitHub Linguist.
| Langage | % | Octets |
|---|---|---|
| C++ | 526 697 | |
| GLSL | 65 789 | |
| Python | 29 193 | |
| PowerShell | 21 830 | |
| Makefile | 10 750 | |
| Shell | 2 016 |
1 autres langages
| Just | 0.23% | 1 491 |
Aperçu
Pourquoi il existe
Moteur de simulation de particules et physique cellulaire optimisé sous libnx.
Cas d’usage
Simulation physique interactive sur écran tactile de console.
Démarrage
Ces commandes viennent de la documentation du dépôt. Elles n’ont pas été exécutées pendant cette revue.
dkp-pacman -Q libnx switch-sdl2
dkp-pacman -Syu # pull newer libnx / switch-sdl2 when availabledkp-pacman -S switch-dev switch-sdl2 switch-mesa switch-glm switch-freetype switch-harfbuzzmakemake desktop
./build/NXSand
make test # CPU reference tests, no GPUpacman -S --needed mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-SDL2 mingw-w64-x86_64-freetype mingw-w64-x86_64-angleprojectRéférences du dépôt
Extraits des guides du dépôt, dans leur langue d’origine. Les liens ouvrent la version du code consultée.
Prérequis et premier essai
Install on Switch (players)
README.md
You need a homebrew-ready Switch (setup guide).
- Get NXSand.nro — build it yourself (below), download the latest NXSand-switch zip from GitHub Actions (switch/NXSand.nro inside; optional NXSand.nsp forwarder when CI has SWITCH_PROD_KEYS), or use a release tag (Switch + Linux + Windows portable zips).
- Copy to the SD card: sdmc:/switch/NXSand.nro (unzip the artifact at the card root, or copy switch/NXSand.nro into switch/).
- Launch from the Homebrew Menu. Saves live in sdmc:/switch/nxsand/. Legacy sdmc:/switch/nxengine/ data is migrated on first launch when possible. Full install notes: docs/INSTALL.md.
1. Install devkitPro
README.md
| OS | Install |
|---|---|
| Windows | Download and run the installer from devkitPro installer releases. Use the MSYS2 shortcut it adds (e.g. “devkitPro MSYS2”) so make and dkp-pacman are on your PATH. |
| Linux / macOS | Follow Getting Started on devkitpro.org. |
| Set DEVKITPRO if your environment does not (the installer usually does). |
2. Install Switch libraries
README.md
Installing NXSand on Nintendo Switch
docs/INSTALL.md
Install on Switch
docs/INSTALL.md
- Copy NXSand.nro to sdmc:/switch/NXSand.nro (required).
- Install NXSand.nsp with your CFW tool (Tinfoil, DBI, Goldleaf, etc.).
- Launch NXSand from the Home menu. If the forwarder fails, launch the .nro from the homebrew menu instead. Forwarders need a CFW setup that allows unsigned NSP installs. Keep prod.keys private; never commit them.
Exploitation et dépannage
Troubleshooting
docs/INSTALL.md
- The app file must be sdmc:/switch/NXSand.nro, not inside the save folder.
- Build and deploy: powershell -File scripts\build-native.ps1 → copy dist/switch/NXSand.nro to sdmc:/switch/NXSand.nro. Run powershell -File scripts\verify-nro.ps1 before copying.
- Confirm the deployed NRO: delete sdmc:/switch/nxsand/launch.log, launch once, and check the latest block includes build: switch-sim-log-v11, switch: sim shader=sim.frag, romfs: sim.frag=… sim_rules_body.glsl=…, sim shader path: shaders/sim.frag, switch: default sim backend=fragment, and no preferring compute sim. Recopy from a fresh build-native.ps1 build if you still see sim_switch paths.
- If the app opens then exits, NXSand shows a fatal text screen and writes sdmc:/switch/nxsand/launch.log when possible.
- Why linking felt slow: full sim_rules_body.glsl on Mesa can take many minutes on first play (same shader as desktop). Mesa…
When to update
docs/diagrams/README.md
- sim-pipeline.mmd, sim-margolus-step.mmd: sim/render pass wiring, compute backend, active-tile scissor rules.
- material-reactions.mmd, reaction-lava-water-quench.puml: shaders/sim.frag / sim_common.glsl reaction branches.
- save-load-flow.puml: source/save/save.cpp JSON fields or paths.
- game-scenes.mmd, brush-input-flow.mmd: menu flow, input mapping, PlayRegion.
- core-runtime-classes.puml, source-modules.mmd: new top-level modules or ownership changes.
Documentation source
3 documents lus parmi 3 candidats.
Fonctions et composants 2
- État de simulation
- SimState contient les dimensions, le compteur et les paramètres du pinceau. SimPipeline possède deux textures et framebuffers avec des opérations de peinture, calcul, lecture et chargement. Le stockage alterné conserve la grille précédente pendant le calcul de la suivante.
- Moteur et tests
- Le parcours fragment utilise GL_R8UI; le parcours compute utilise GL_R32UI pour imageStore. Le pipeline expose les tuiles actives et les replis. Le Makefile sépare les tests CPU, les tests GPU et l’application Switch.
Architecture
Les composants et leurs liens restent lisibles en texte. Le diagramme ajoute une vue interactive.
- Commandes de pinceau
- Grille entière des matériaux
- Passe de simulation
- Texture de grille suivante
- Pipeline de rendu
Liens vérifiés dans le dépôt.
Mermaid Diagramme interactif (chargement à l’ouverture)
Vue générale des composants et des échanges vérifiés dans le dépôt.

flowchart LR
subgraph group_runtime["Runtime"]
node_entry["Platform entry<br/>[main.cpp]"]
node_app["App frame loop<br/>[app.cpp]"]
node_game_settings["Game settings<br/>[game_settings.hpp]"]
node_engine_settings["Engine settings"]
end
subgraph group_simulation["Simulation"]
node_sim_state["Simulation state<br/>[sim_state.hpp]"]
node_materials["Materials<br/>[materials.hpp]"]
node_physics["Physics parameters<br/>[physics_params.hpp]"]
node_sim_pipeline["GPU simulation<br/>[sim_pipeline.cpp]"]
node_sim_backend["Simulation backend<br/>[sim_backend.hpp]"]
end
subgraph group_presentation["Presentation"]
node_render["World renderer"]
node_shader_program["Shader programs<br/>[shader_program.cpp]"]
node_font["Font atlas<br/>[font_atlas.cpp]"]
node_audio["Audio<br/>[tone_audio.cpp]"]
end
subgraph group_interaction["Interaction"]
node_input["Input handling<br/>[input.cpp]"]
node_menu["Menus<br/>[menu.cpp]"]
node_layout["UI layout<br/>[layout.hpp]"]
node_theme["UI theme<br/>[theme.hpp]"]
end
subgraph group_persistence["Persistence"]
node_save["World saves<br/>[save.cpp]"]
node_save_paths["Save storage<br/>[save_paths.cpp]"]
node_settings_io["Settings storage<br/>[settings_io.cpp]"]
end
node_player(("Player"))
node_player -->|"launches"| node_entry
node_entry -->|"starts"| node_app
node_app -->|"ticks"| node_sim_pipeline
node_app -->|"renders"| node_render
node_app -->|"reads"| node_input
node_app -->|"coordinates"| node_menu
node_app -->|"requests saves"| node_save
node_app -->|"loads settings"| node_settings_io
node_app -->|"applies settings"| node_engine_settings
node_app -->|"uses settings"| node_game_settings
node_app -->|"holds state"| node_sim_state
node_app -->|"holds parameters"| node_physics
node_sim_pipeline -->|"updates grid"| node_sim_state
node_sim_pipeline -->|"simulates materials"| node_materials
node_sim_pipeline -->|"uses parameters"| node_physics
node_sim_pipeline -->|"selects backend"| node_sim_backend
node_render -->|"uses shaders"| node_shader_program
node_render -->|"draws grid"| node_sim_state
node_render -->|"colors materials"| node_materials
node_menu -->|"edits settings"| node_engine_settings
node_menu -->|"uses text"| node_font
node_menu -->|"draws interface"| node_render
node_layout -->|"uses styles"| node_theme
node_input -->|"maps controls"| node_layout
node_audio -->|"reads preferences"| node_game_settings
node_save -.->|"uses storage"| node_save_paths
node_settings_io -->|"uses storage"| node_save_paths
node_engine_settings -->|"persists preferences"| node_settings_io
class node_entry,node_app,node_game_settings,node_engine_settings toneBlue
class node_sim_state,node_materials,node_physics,node_sim_pipeline,node_sim_backend toneAmber
class node_render,node_shader_program,node_font,node_audio toneMint
class node_input,node_menu,node_layout,node_theme toneRose
class node_save,node_save_paths,node_settings_io,node_player toneIndigoUn bac à sable de particules pour Nintendo Switch, avec des versions bureau pour itérer rapidement. La boucle d’images coordonne la simulation GPU, le rendu, les entrées, les menus, la persistance et les réglages autour d’une grille de matériaux.
- Composants
- 21
- Connexions
- 28
- Liens appuyés par le code ou le README
- 15/28
Version texte du diagramme
- Commandes de pinceau → Grille entière des matériaux
- Grille entière des matériaux → Passe de simulation
- Passe de simulation → Texture de grille suivante
- Texture de grille suivante → Grille entière des matériaux
- Texture de grille suivante → Pipeline de rendu
Suivre un parcours dans le code
Suivez paintDisk vers la modification de grille, puis step vers le moteur choisi. readTexture désigne la grille courante pour le rendu. La sauvegarde doit aussi tenir compte de l’orientation des lignes OpenGL, plutôt que copier une capture.
Types et structure des fichiers
53 types déclarés, dont 12 dans l’aperçu des relations de base.
Diagramme des types
classDiagram
direction TB
class t7ba1fb6b5b9e["SimPassRect"] {
<<struct>>
}
class t658fbe1e623e["SimPipeline"] {
SimPipeline()
init()
shutdown()
clearAll()
}
class tb8626ee066b2["SimState"] {
<<struct>>
}
class tfdb610a7db47["SimCompileAudioGuard"] {
<<struct>>
SimCompileAudioGuard()
}
class ta050db13a10c["App"] {
init()
shutdown()
frame()
setSimGridSize()
}
class tf962c5d4ce57["PerformanceSettings"] {
<<struct>>
}
class tbdcb989e9dca["VisualSettings"] {
<<struct>>
}
class tbb5d68fb65da["ControlSettings"] {
<<struct>>
}
class t480673c07c2c["AudioSettings"] {
<<struct>>
}
class t28451b24c3ad["AccessibilitySettings"] {
<<struct>>
}
class t45aedf66edc0["DebugSettings"] {
<<struct>>
}
class t4b3cad79f762["DisplaySettings"] {
<<struct>>
}
Les bases non résolues restent identifiées; les signatures complètes ne sont pas reconstruites.
Index des types
SimPassRect(struct) ·source/gpu/sim_pipeline.hpp:16SimPipeline(class) ·source/gpu/sim_pipeline.hpp:23Méthodes dans l’aperçu :
SimPipeline, init, shutdown, clearAll.SimState(struct) ·source/sim/sim_state.hpp:34SimCompileAudioGuard(struct) ·source/game/app.cpp:478Méthodes dans l’aperçu :
SimCompileAudioGuard.App(class) ·source/game/app.hpp:33Méthodes dans l’aperçu :
init, shutdown, frame, setSimGridSize.PerformanceSettings(struct) ·source/game/game_settings.hpp:45VisualSettings(struct) ·source/game/game_settings.hpp:56ControlSettings(struct) ·source/game/game_settings.hpp:69AudioSettings(struct) ·source/game/game_settings.hpp:77AccessibilitySettings(struct) ·source/game/game_settings.hpp:86DebugSettings(struct) ·source/game/game_settings.hpp:92DisplaySettings(struct) ·source/game/game_settings.hpp:99
Référence
135 / 135 fichiers admissibles lus (240 dans l’arbre); 0 trop volumineux, 0 échec de lecture et 5 diagnostic de syntaxe.
Ce que couvre l’analyse
Les dossiers connus de dépendances et de compilation, les fichiers d’identifiants et les binaires sont exclus. La collecte couvre les README, les manifestes reconnus et les fichiers source pris en charge.
Les statistiques Linguist couvrent l’ensemble du dépôt et peuvent inclure d’autres langages.
Carte des fichiers
flowchart TD
root["nxsand"]
f0["Makefile"]
root --> f0
f1["source/gpu/sim_pipeline.hpp"]
root --> f1
f2["source/sim/sim_state.hpp"]
root --> f2
f3["README.md"]
root --> f3
f4["scripts/build-desktop-msys.sh"]
root --> f4
f5["scripts/build-desktop-wsl.sh"]
root --> f5
f6["scripts/crop_icon.py"]
root --> f6
f7["scripts/export-nsp.py"]
root --> f7
f8["scripts/generate-audio.py"]
root --> f8
f9["scripts/package-release.py"]
root --> f9
f10["scripts/regenerate-diagrams.py"]
root --> f10
f11["scripts/sync-sim-rules-body.py"]
root --> f11
f12["tests/gpu_test_gl.cpp"]
root --> f12
f13["tests/gpu_test_gl.hpp"]
root --> f13
f14["tests/gpu_unit_main.cpp"]
root --> f14
f15["tests/test_harness.hpp"]
root --> f15