shamash-core 2026.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. shamash_core-2026.2.0/LICENSE +21 -0
  2. shamash_core-2026.2.0/PKG-INFO +370 -0
  3. shamash_core-2026.2.0/README.md +354 -0
  4. shamash_core-2026.2.0/pyproject.toml +52 -0
  5. shamash_core-2026.2.0/setup.cfg +4 -0
  6. shamash_core-2026.2.0/src/shamash/__init__.py +82 -0
  7. shamash_core-2026.2.0/src/shamash/__main__.py +4 -0
  8. shamash_core-2026.2.0/src/shamash/__version__.py +83 -0
  9. shamash_core-2026.2.0/src/shamash/cli.py +228 -0
  10. shamash_core-2026.2.0/src/shamash/core/__init__.py +39 -0
  11. shamash_core-2026.2.0/src/shamash/core/config.py +118 -0
  12. shamash_core-2026.2.0/src/shamash/core/exceptions/__init__.py +119 -0
  13. shamash_core-2026.2.0/src/shamash/core/exceptions/apperror.py +219 -0
  14. shamash_core-2026.2.0/src/shamash/core/exceptions/calculationerror.py +187 -0
  15. shamash_core-2026.2.0/src/shamash/core/exceptions/spacetimeerror.py +384 -0
  16. shamash_core-2026.2.0/src/shamash/data/default.yml +116 -0
  17. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/atm_composition.md +18 -0
  18. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/atm_molar_mass.md +25 -0
  19. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/atmospheric_density.md +15 -0
  20. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/atmospheric_pressure.md +20 -0
  21. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/description.md +6 -0
  22. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/full_composition.md +7 -0
  23. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/name.md +8 -0
  24. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/nitrogen.md +17 -0
  25. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/parent_moon_or_planet.md +11 -0
  26. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/sky_color.md +35 -0
  27. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/sound_speed.md +14 -0
  28. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/specific_gas_constant.md +13 -0
  29. shamash_core-2026.2.0/src/shamash/docs/properties/Atmosphere/temperature.md +11 -0
  30. shamash_core-2026.2.0/src/shamash/docs/properties/Biosphere/description.md +6 -0
  31. shamash_core-2026.2.0/src/shamash/docs/properties/Biosphere/name.md +8 -0
  32. shamash_core-2026.2.0/src/shamash/docs/properties/Biosphere/parent_moon_or_planet.md +6 -0
  33. shamash_core-2026.2.0/src/shamash/docs/properties/Biosphere/photon_availability.md +19 -0
  34. shamash_core-2026.2.0/src/shamash/docs/properties/Biosphere/photon_flux_peak.md +6 -0
  35. shamash_core-2026.2.0/src/shamash/docs/properties/Biosphere/photosynthesis_type.md +19 -0
  36. shamash_core-2026.2.0/src/shamash/docs/properties/Biosphere/pigment_absorption_peak.md +20 -0
  37. shamash_core-2026.2.0/src/shamash/docs/properties/Biosphere/plant_color.md +27 -0
  38. shamash_core-2026.2.0/src/shamash/docs/properties/Biosphere/red_edge_wavelength.md +17 -0
  39. shamash_core-2026.2.0/src/shamash/docs/properties/Magnetosphere/bow_shock_distance.md +16 -0
  40. shamash_core-2026.2.0/src/shamash/docs/properties/Magnetosphere/description.md +6 -0
  41. shamash_core-2026.2.0/src/shamash/docs/properties/Magnetosphere/magnetopause_standoff.md +21 -0
  42. shamash_core-2026.2.0/src/shamash/docs/properties/Magnetosphere/magnetosheath_thickness.md +10 -0
  43. shamash_core-2026.2.0/src/shamash/docs/properties/Magnetosphere/magnetotail_length.md +13 -0
  44. shamash_core-2026.2.0/src/shamash/docs/properties/Magnetosphere/name.md +8 -0
  45. shamash_core-2026.2.0/src/shamash/docs/properties/Magnetosphere/parent_moon_or_planet.md +11 -0
  46. shamash_core-2026.2.0/src/shamash/docs/properties/Magnetosphere/shielded.md +13 -0
  47. shamash_core-2026.2.0/src/shamash/docs/properties/Magnetosphere/stellar_wind_density.md +20 -0
  48. shamash_core-2026.2.0/src/shamash/docs/properties/Magnetosphere/stellar_wind_pressure.md +11 -0
  49. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/absolute_magnitude.md +15 -0
  50. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/albedo_bond.md +9 -0
  51. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/albedo_gemoetric.md +12 -0
  52. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/brightness.md +11 -0
  53. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/density.md +11 -0
  54. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/description.md +6 -0
  55. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/escape_velocity.md +12 -0
  56. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/habitability.md +28 -0
  57. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/habitability_factors.md +12 -0
  58. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/habitability_limiting_factor.md +6 -0
  59. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/inner_moon_zone.md +15 -0
  60. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/main_planet_tidal_forces.md +7 -0
  61. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/main_planet_tidal_period.md +15 -0
  62. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/main_planet_tidal_range.md +18 -0
  63. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/mass.md +10 -0
  64. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/name.md +8 -0
  65. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/outer_moon_zone.md +18 -0
  66. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/parent_orbit.md +5 -0
  67. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/parent_planet.md +5 -0
  68. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/position.md +12 -0
  69. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/radius.md +11 -0
  70. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/stable.md +6 -0
  71. shamash_core-2026.2.0/src/shamash/docs/properties/Moon/tidal_force.md +17 -0
  72. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/aphelion_distance.md +15 -0
  73. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/description.md +6 -0
  74. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/eccentricity.md +19 -0
  75. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/inclination.md +7 -0
  76. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/longitude_of_apoapsis.md +6 -0
  77. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/longitude_of_periapsis.md +10 -0
  78. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/name.md +8 -0
  79. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/orbital_period.md +12 -0
  80. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/parent_celestial_object.md +13 -0
  81. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/perihelion_distance.md +17 -0
  82. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/semi_major_axis.md +22 -0
  83. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/true_anomaly.md +16 -0
  84. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/v_apoapsis.md +6 -0
  85. shamash_core-2026.2.0/src/shamash/docs/properties/Orbit/v_periapsis.md +12 -0
  86. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/albedo_bond.md +29 -0
  87. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/core_density.md +9 -0
  88. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/core_liquid_fraction.md +23 -0
  89. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/core_mass.md +10 -0
  90. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/core_mass_fraction.md +25 -0
  91. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/core_radius.md +11 -0
  92. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/density.md +17 -0
  93. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/description.md +6 -0
  94. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/escape_velocity.md +12 -0
  95. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/gravity.md +11 -0
  96. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/greenhouse_effect.md +32 -0
  97. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/habitability.md +29 -0
  98. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/habitability_factors.md +15 -0
  99. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/habitability_limiting_factor.md +5 -0
  100. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/height_observer.md +14 -0
  101. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/magnetic_moment.md +16 -0
  102. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/main_star_apparent_brightness.md +5 -0
  103. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/main_star_apparent_magnitude.md +5 -0
  104. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/main_star_apparent_size.md +7 -0
  105. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/main_star_tidal_forces.md +13 -0
  106. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/mantle_density.md +11 -0
  107. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/mass.md +15 -0
  108. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/max_total_tidal_forces.md +13 -0
  109. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/moons.md +6 -0
  110. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/name.md +8 -0
  111. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/orbits.md +6 -0
  112. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/parent_orbit.md +5 -0
  113. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/parent_star.md +6 -0
  114. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/position.md +12 -0
  115. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/radius.md +12 -0
  116. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/rotation_period.md +12 -0
  117. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/subsolar_longitude.md +7 -0
  118. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/surface_gravity.md +9 -0
  119. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/surface_magnetic_field_equatorial.md +10 -0
  120. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/surface_magnetic_field_polar.md +10 -0
  121. shamash_core-2026.2.0/src/shamash/docs/properties/Planet/surface_temperature.md +19 -0
  122. shamash_core-2026.2.0/src/shamash/docs/properties/Settings/default_first_moon_orbit_radius.md +19 -0
  123. shamash_core-2026.2.0/src/shamash/docs/properties/Settings/default_laplace_resonance_ratio.md +22 -0
  124. shamash_core-2026.2.0/src/shamash/docs/properties/Settings/default_moon_orbit_slots.md +16 -0
  125. shamash_core-2026.2.0/src/shamash/docs/properties/Star/core_temperature.md +19 -0
  126. shamash_core-2026.2.0/src/shamash/docs/properties/Star/current_age.md +21 -0
  127. shamash_core-2026.2.0/src/shamash/docs/properties/Star/density.md +15 -0
  128. shamash_core-2026.2.0/src/shamash/docs/properties/Star/description.md +6 -0
  129. shamash_core-2026.2.0/src/shamash/docs/properties/Star/habitable_zone.md +29 -0
  130. shamash_core-2026.2.0/src/shamash/docs/properties/Star/luminosity.md +33 -0
  131. shamash_core-2026.2.0/src/shamash/docs/properties/Star/magnitude.md +14 -0
  132. shamash_core-2026.2.0/src/shamash/docs/properties/Star/mass.md +42 -0
  133. shamash_core-2026.2.0/src/shamash/docs/properties/Star/mass_loss_rate.md +17 -0
  134. shamash_core-2026.2.0/src/shamash/docs/properties/Star/max_age.md +24 -0
  135. shamash_core-2026.2.0/src/shamash/docs/properties/Star/name.md +8 -0
  136. shamash_core-2026.2.0/src/shamash/docs/properties/Star/orbits.md +5 -0
  137. shamash_core-2026.2.0/src/shamash/docs/properties/Star/planets.md +7 -0
  138. shamash_core-2026.2.0/src/shamash/docs/properties/Star/position.md +12 -0
  139. shamash_core-2026.2.0/src/shamash/docs/properties/Star/radius.md +32 -0
  140. shamash_core-2026.2.0/src/shamash/docs/properties/Star/star_class.md +26 -0
  141. shamash_core-2026.2.0/src/shamash/docs/properties/Star/star_color.md +31 -0
  142. shamash_core-2026.2.0/src/shamash/docs/properties/Star/star_supports_earthlike_life.md +22 -0
  143. shamash_core-2026.2.0/src/shamash/docs/properties/Star/temperature.md +25 -0
  144. shamash_core-2026.2.0/src/shamash/docs/properties/Star/wind_velocity.md +8 -0
  145. shamash_core-2026.2.0/src/shamash/docs/properties/_sidebar.md +146 -0
  146. shamash_core-2026.2.0/src/shamash/models/__init__.py +108 -0
  147. shamash_core-2026.2.0/src/shamash/models/existence.py +65 -0
  148. shamash_core-2026.2.0/src/shamash/models/god.py +122 -0
  149. shamash_core-2026.2.0/src/shamash/models/habitability.py +314 -0
  150. shamash_core-2026.2.0/src/shamash/models/planetary/__init__.py +0 -0
  151. shamash_core-2026.2.0/src/shamash/models/planetary/athmosphere.py +300 -0
  152. shamash_core-2026.2.0/src/shamash/models/planetary/biosphere.py +239 -0
  153. shamash_core-2026.2.0/src/shamash/models/planetary/magnetosphere.py +184 -0
  154. shamash_core-2026.2.0/src/shamash/models/stellar/__init__.py +0 -0
  155. shamash_core-2026.2.0/src/shamash/models/stellar/moon.py +355 -0
  156. shamash_core-2026.2.0/src/shamash/models/stellar/orbit.py +196 -0
  157. shamash_core-2026.2.0/src/shamash/models/stellar/planet.py +437 -0
  158. shamash_core-2026.2.0/src/shamash/models/stellar/star.py +336 -0
  159. shamash_core-2026.2.0/src/shamash/services/__init__.py +71 -0
  160. shamash_core-2026.2.0/src/shamash/services/base/__init__.py +0 -0
  161. shamash_core-2026.2.0/src/shamash/services/base/service.py +44 -0
  162. shamash_core-2026.2.0/src/shamash/services/celestial/__init__.py +0 -0
  163. shamash_core-2026.2.0/src/shamash/services/celestial/service.py +180 -0
  164. shamash_core-2026.2.0/src/shamash/services/create/__init__.py +0 -0
  165. shamash_core-2026.2.0/src/shamash/services/create/service.py +441 -0
  166. shamash_core-2026.2.0/src/shamash/services/interaction/__init__.py +0 -0
  167. shamash_core-2026.2.0/src/shamash/services/interaction/service.py +107 -0
  168. shamash_core-2026.2.0/src/shamash/services/world/__init__.py +0 -0
  169. shamash_core-2026.2.0/src/shamash/services/world/formats.py +155 -0
  170. shamash_core-2026.2.0/src/shamash/services/world/service.py +369 -0
  171. shamash_core-2026.2.0/src/shamash/utils/__init__.py +119 -0
  172. shamash_core-2026.2.0/src/shamash/utils/autorepr.py +49 -0
  173. shamash_core-2026.2.0/src/shamash/utils/decorators.py +199 -0
  174. shamash_core-2026.2.0/src/shamash/utils/enums.py +43 -0
  175. shamash_core-2026.2.0/src/shamash/utils/helpers.py +54 -0
  176. shamash_core-2026.2.0/src/shamash/utils/logger.py +53 -0
  177. shamash_core-2026.2.0/src/shamash/utils/schema.py +122 -0
  178. shamash_core-2026.2.0/src/shamash/utils/units.py +60 -0
  179. shamash_core-2026.2.0/src/shamash/utils/validators.py +0 -0
  180. shamash_core-2026.2.0/src/shamash_core.egg-info/PKG-INFO +370 -0
  181. shamash_core-2026.2.0/src/shamash_core.egg-info/SOURCES.txt +189 -0
  182. shamash_core-2026.2.0/src/shamash_core.egg-info/dependency_links.txt +1 -0
  183. shamash_core-2026.2.0/src/shamash_core.egg-info/entry_points.txt +2 -0
  184. shamash_core-2026.2.0/src/shamash_core.egg-info/requires.txt +6 -0
  185. shamash_core-2026.2.0/src/shamash_core.egg-info/top_level.txt +1 -0
  186. shamash_core-2026.2.0/tests/test_cli.py +181 -0
  187. shamash_core-2026.2.0/tests/test_create.py +216 -0
  188. shamash_core-2026.2.0/tests/test_docs.py +44 -0
  189. shamash_core-2026.2.0/tests/test_physics.py +217 -0
  190. shamash_core-2026.2.0/tests/test_registry.py +87 -0
  191. shamash_core-2026.2.0/tests/test_worldfile.py +221 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fabian Schober
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,370 @@
1
+ Metadata-Version: 2.4
2
+ Name: shamash-core
3
+ Version: 2026.2.0
4
+ Summary: A Toolbox for creating a physically modelled world for worldbuilding purposes, based on Artifexian's Worldsmith.
5
+ License-Expression: MIT
6
+ Project-URL: Source, https://codeberg.org/schobernoise/shamash-core
7
+ Requires-Python: >=3.12
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: pyyaml
11
+ Requires-Dist: rich
12
+ Requires-Dist: naturedynamics>=1.1
13
+ Provides-Extra: dev
14
+ Requires-Dist: black; extra == "dev"
15
+ Dynamic: license-file
16
+
17
+ # Shamash
18
+
19
+ > This aims to be a physically accurate worldbuilder. A lot of these calculations are rather educated guesses than well-founded scientific principals, but they all have their foundation in recent scientific discoveries and laws of nature.
20
+
21
+ Based on the great [Artifexian](https://www.artifexian.com/)'s Work "The Worldsmith" I wanted to continue his journey. Intruiged by building on the very idea of quantifying reality - but at the same time horrified by looking at a spreadsheet - the only logical next step was to build a python application. :)
22
+
23
+ > [!important] AI Disclaimer
24
+ > Yeah, I know, this sucks. Until version 2026.0.3 I wrote everything myself, except some exporting functionality. The architecture, the Design Patterns, I came up with that myself. But with time being the only thing that does not accumulate over time (weird, right?) I simply couldn't stand another project wasting away over the years, and me not having the energy to finish it. Claude assists me heavily in writing the API and UI.
25
+
26
+ So, before the whole thing became a webfrontend with an API I designed it to be a CLI-Application. I like to work from the terminal, but after having hundreds of parameters scrolling past your tired eyes this was just not feasable any more. So I turned the CLI into an API (which still can be used as CLI as well) and created a React-Frontend.
27
+
28
+ Worldbuilding is an incredibly complex process. This application will never aim at calculating EVERYTHING, you know. I know some of you (including me) have those thoughts and it is only natural to desire a feeling of absolute control over reality. Understanding, caluclating, quantifiying everything until its smallest detail. But look into yourself. The motivation will most likely be fear, or some derivation of it. You are afraid to not be able to hold the world you are building in the palm of your hand.
29
+
30
+ But the very thing you are seeking to do - describing a reality by natural laws - is something we humans perfected since 300.000 years by immitating our natural surroundings (impressions), using them to express our feelings, pain and pleasure (expressions). This enables you to describe your newly formed reality in a way far more compley than any table of figures can. **Put your world into writing, not into a table, so other humans can comprehend what you are creating.**
31
+
32
+ ## The shamash repositories
33
+
34
+ shamash is split by audience:
35
+
36
+ - **shamash-core** (this repo) — the physics engine and the `shamash` CLI. Published on PyPI.
37
+ - **[shamash-server](https://codeberg.org/schobernoise/shamash-server)** — the HTTP API around the engine, dockerized.
38
+ - **[shamash-web](https://codeberg.org/schobernoise/shamash-web)** — the React frontend, dockerized, talking to a shamash-server.
39
+
40
+ ## Getting started
41
+
42
+ ```bash
43
+ pip install shamash-core
44
+ shamash -p
45
+ ```
46
+
47
+ The distribution is `shamash-core`; the command and the import name are both `shamash`.
48
+
49
+ For development, a Makefile is provided:
50
+
51
+ ```bash
52
+ make venv
53
+ uv pip install -e ../naturedynamics # the physics backend, as a sibling checkout
54
+ make install
55
+ make run
56
+ make test
57
+ ```
58
+
59
+ Without any paramaters, shamash reads the seed world packaged at `src/shamash/data/default.yml`, which represents our very solar system. `make run` is configured to use the `-p` flag, which pretty-prints out all calculations.
60
+
61
+ ### The CLI application
62
+
63
+ `shamash` is the terminal-first way to use this project — load a world, optionally change what gets read or written, and exit. A plain `shamash` prints nothing; it just loads the world and returns, which is what makes it safe to script. Every flag is optional and they compose:
64
+
65
+ ```bash
66
+ shamash # load src/shamash/data/default.yml, print nothing
67
+ shamash -w my_world.yml # load a different world file instead
68
+ shamash -p # also pretty-print the loaded (and computed) world to stdout
69
+ shamash -e out.yml # also export the loaded world to out.yml
70
+ shamash -f json # write JSON instead of YAML (also: csv)
71
+ shamash -i new_world.yml # copy the input world to new_world.yml, to seed a new one, then exit
72
+ shamash -l # also log to the configured log file (stderr always gets the log otherwise)
73
+ ```
74
+
75
+ `-p` and `-e` render through the exact same writer, so `shamash -p > world.yml` produces a file that reloads with `-w` byte-for-byte. That holds per format: `-f json -e world.json` reloads with `-w` too, and gives back the identical world. On a terminal, `-p` syntax-highlights the output with `rich`; piped or redirected, it falls back to the plain string, so the redirect stays clean.
76
+
77
+ `-f csv` is the flat one, and the exception: one row per scalar rather than a tree, `entity,type,property,source,value,unit,dimension`, with compound values exploded into rows of their own (`main_star_apparent_size[0]`, `atm_composition.o_2`). It is the same view the frontend's matrix tab shows, and it is **one-way** — a world cannot be read back from it. Use it to pull a computed world into a spreadsheet or a plotting script:
78
+
79
+ ```bash
80
+ shamash -f csv -p | awk -F, '$3 == "habitability"'
81
+ ```
82
+
83
+ #### Verbs
84
+
85
+ Flags act on a world; **verbs change one**. `create` makes one entity and hangs it off an existing one:
86
+
87
+ ```bash
88
+ shamash create Atmosphere earth -w my.yml # asks for what it needs
89
+ shamash create Planet sol -w my.yml # offers sol's free orbits, or makes one
90
+ shamash create Star --id alpha --set mass=1.0:MSol --set current_age=4.6:Gyr -w my.yml
91
+ ```
92
+
93
+ Flags work on either side of the verb, so `shamash -w my.yml create Orbit sol` reads the same.
94
+
95
+ Required fields it isn't given, it asks for; `--set key=value` answers one up front. `--set` also reaches the *optional* fields it never asks about — a planet's core (`--set core_density=10900`), a star's wind — and refuses a name the type doesn't have, so a typo is a visible error rather than a value that quietly never arrives. Values are SI unless you give a unit — `--set mass=1.0:MSol` goes through the same conversion and the same checks a world file's `{value: 1.0, unit: MSol}` does, so a wrong dimension is refused rather than quietly scaled.
96
+
97
+ Choices with no safe default are asked too: a body that already has an atmosphere, a parent that already has orbits, a file about to be overwritten. `--answer name=value` settles those up front (`--answer strategy=add`), which is what makes the whole thing scriptable — including questions about an entity `create` makes along the way, like the orbit a new planet needs (`--answer semi_major_axis=1.52:ASol`). **With nothing to ask and no terminal to ask at, it refuses instead of hanging** — a piped run tells you exactly which answers it was missing and exits 1.
98
+
99
+ What can host what is not a list anywhere; each relationship declares what the child reads off its parent, and a type qualifies by providing it:
100
+
101
+ ```
102
+ $ shamash create Atmosphere sol -w my.yml
103
+ Atmosphere cannot hang off 'sol': a Star has no surface_temperature,
104
+ which Atmosphere.parent_moon_or_planet needs. Types that do: Planet.
105
+ ```
106
+
107
+ That sentence is assembled from the models every time, so it follows them — the day a Moon can compute a `surface_temperature`, moon atmospheres start working and this refusal stops being produced, with nothing to update.
108
+
109
+ `create` writes back to the file `-w` names, or to `-e` when given. It refuses without one of them (the default world lives inside the installed package), asks before overwriting unless `-y`, and refuses `-f csv`, which does not reload.
110
+
111
+ ### As a library
112
+
113
+ Everything the CLI does is reachable from Python. A world loads into a registry, every value on it is computed on access, and `Worldloader` turns it back into text:
114
+
115
+ ```python
116
+ import shamash as sh
117
+
118
+ with sh.god.scope():
119
+ loader = sh.services.Worldloader()
120
+ loader.load(sh.services.BaseService.default_world_path())
121
+ print(sh.god.summons("earth").habitability)
122
+ print(loader.dumps(fmt="json"))
123
+ ```
124
+
125
+ `god.scope()` gives the world a registry of its own, so two worlds can be computed at once without seeing each other — that is what shamash-server does per request.
126
+
127
+ `sh.utils.describe_entities()` is the per-type schema — every field and computed property with its unit, whether it is required, and its description — derived from the models rather than written down anywhere.
128
+
129
+ ### Property documentation
130
+
131
+ Every field and computed property carries a `description`, and each has a long-form page with formulas and sources under `src/shamash/docs/properties/<Type>/<name>.md`. The pages ship inside the package, so a server always hands out the pages for exactly the engine version it runs; shamash-web renders them. `make test` fails if a description has no page or a page documents nothing.
132
+
133
+ ## Releases
134
+
135
+ Development happens on `origin` (`dev.fs.or.at`). A release is an annotated
136
+ tag on `main`, and `codeberg` only ever sees tagged states:
137
+
138
+ ```bash
139
+ git push origin main # every day
140
+ git tag -a v2026.1.1 -m "CLI verbs and output formats"
141
+ git push origin --tags # keep the markers on dev too
142
+ git push codeberg main v2026.1.1 # publish
143
+ ```
144
+
145
+ Tags go to **both** remotes; commits go to `origin` until they are released.
146
+ Then the same commit goes to PyPI:
147
+
148
+ ```bash
149
+ make publish PUBLISH_URL=https://test.pypi.org/legacy/ # check it installs
150
+ make publish
151
+ ```
152
+ That way the release history survives on the remote that has everything,
153
+ rather than only on the one it is published to.
154
+
155
+ So `git tag` is the list of releases, each heading below names one, and the
156
+ version in `pyproject.toml` is bumped in the commit the tag points at.
157
+ `__version__.py` reads it from there — see the note in `CLAUDE.md` about why
158
+ the checkout's `pyproject.toml` wins over `importlib.metadata`.
159
+
160
+ ### 2026.2.0
161
+
162
+ - [x] Split the project into repositories
163
+ - This repo becomes **shamash-core**: the engine and the CLI, published
164
+ on PyPI as `shamash-core`. The import name and the command stay
165
+ `shamash`.
166
+ - The HTTP layer moved to **shamash-server** and the frontend to
167
+ **shamash-web**, both dockerized; the marimo notebooks to a private
168
+ experiments repo. `shamash-api` is gone from this package.
169
+ - The property docs moved *into* the package
170
+ (`src/shamash/docs/properties/`), next to the descriptions they expand
171
+ on, so a page and its description change in one commit. The coverage
172
+ test moved with them and now checks both directions, the Settings
173
+ pages and the sidebar — it used to check only that entity descriptions
174
+ had a page, and skipped itself in any install without the frontend.
175
+ - `describe_entities`/`describe_config` moved from `api/schemas.py` to
176
+ `sh.utils`: they read only the models.
177
+ - MIT licensed, in all three public repos.
178
+ - Dependencies cut to what the engine imports: `pyyaml`, `rich`,
179
+ `naturedynamics`. `numpy`/`scipy`/`matplotlib` arrive through
180
+ `naturedynamics`, which declares them itself.
181
+
182
+ ### 2026.1.2
183
+
184
+ - [x] Bring back a test suite — `make test`, stdlib `unittest`, ~1 s
185
+ - It loads the real seed world and asserts what comes out, rather than
186
+ mocking collaborators: the physics is a pure function of `default.yml`,
187
+ so running it *is* the test. Most of it is a transcription of numbers
188
+ `CLAUDE.md` already presented as regression baselines — Sol at 1.000
189
+ RSol / 5770.8 K / G2.9, Earth habitability 1.000, `#B3F49A`,
190
+ magnetopause 9.52 R⊕ — which described a suite nobody had written down.
191
+ - 70 tests over the physics anchors, the loader's round-trips and error
192
+ taxonomy, `god.scope()` isolation under 8 threads, the HTTP contracts
193
+ (including that a 500 still carries its CORS header), the CLI, and the
194
+ `create` verb's parent rules.
195
+ - Mutation-probed while being written, which is the only reason to trust
196
+ it: feeding `Star.radius` kilograms fails 6 tests, dropping
197
+ `FACTOR_FLOOR` fails the hostile-world test, removing the
198
+ `Planet.moons` backref fails the tidal one.
199
+ - `make test-packaging` is separate (~15 s): it builds a wheel and runs
200
+ the CLI and the API from it with no source tree in sight.
201
+ - [x] Two bugs the suite found before it was finished
202
+ - `create Moon sol` ran the orbit cascade *before* discovering a Star
203
+ cannot host a moon, so it created an orbit and then refused — leaving
204
+ it behind in a world the caller was told nothing had been added to.
205
+ Legality is now decided first, so a refusal costs nothing.
206
+ - `create` asked its questions before validating `--set` names and the
207
+ `--id`, so a typo was reported only after you had answered three
208
+ prompts. Both are checked up front now.
209
+ - [x] Corrected numbers the docs stated but the code did not produce
210
+ - `magnetosphere.py` documented Earth's magnetopause at 9.6 planetary
211
+ radii and the bow shock at 12.5, in five places including user-facing
212
+ text mirrored into the docs site. The code computes 9.52 and 12.37.
213
+
214
+ ### 2026.1.1
215
+
216
+ - [x] Output formats for the CLI — `-f yaml|json|csv`
217
+ - Notation moved out of both the codec and the HTTP layer into
218
+ `services/world/formats.py`, so there is one YAML dumper call and one
219
+ JSON dumper call in the codebase and the CLI and API cannot drift.
220
+ `-p` and `-e` are byte-identical per format; `shamash -f json -p` is
221
+ byte-identical to `GET /v1/world/default`.
222
+ - csv is the flat view — one row per scalar, the same shape the frontend's
223
+ matrix tab shows — and is one-way.
224
+ - `Worldloader.loads` now parses a root-level `{` as JSON. PyYAML follows
225
+ YAML 1.1, where `5e-05` without a dot is a *string*, so the app could not
226
+ read back a file it had just written with `-f json -e`.
227
+ - [x] CLI verbs — `shamash create <Type> <parent_id>`
228
+ - `cli.py` grows subparsers and a `VERBS` map; flags work on either side of
229
+ the verb. `-w` names the file the verb modifies.
230
+ - What can host what is declared per relationship as `parent_needs` — what
231
+ the child reads off its parent — never as a table of types. The refusal
232
+ message is assembled from the models, so it follows them: the day a Moon
233
+ can compute a `surface_temperature`, moon atmospheres start working with
234
+ nothing to update.
235
+ - Services never prompt. They call `self.ask(questions)`; the CLI injects
236
+ `InteractionService.ask` and everything else gets `refuse_to_ask`, which
237
+ raises a 422 carrying the questions — a service reading stdin would block
238
+ a uvicorn worker forever, and `world:create-orbit` runs the same code.
239
+ - `--set` and `--answer` make a create fully scriptable; with nothing left
240
+ to ask it needs no terminal at all.
241
+
242
+ ### 2026.1.0
243
+
244
+ - [x] Put the whole thing in a Docker container for convenience and deployment
245
+ - `docker-compose.yml` + `docker/api.Dockerfile` (`pip install .`,
246
+ fetching `naturedynamics` over plain HTTPS — the repo is public, no
247
+ credentials needed) + `docker/frontend.Dockerfile` (nginx, proxying
248
+ `/v1`, `/healthz`, `/openapi.json` to the API container). See the
249
+ "Docker" section above.
250
+ - [x] Web frontend — **React**, in `frontend/`
251
+ - Settled by a measurement rather than a preference. A full seed-world
252
+ compute is **~18 ms** for 7.7 KB of JSON, so every edit can debounce into
253
+ one `POST /v1/world:compute` and replace the whole snapshot. The client
254
+ needs no physics and no derived-value graph of its own — the reactive
255
+ graph already exists on the server, as `god.summons()` plus lazy
256
+ `@property`.
257
+ - That is what decides it. Angular's strongest cards here are signals and
258
+ Reactive Forms, and neither has anything to do: there is nothing to derive
259
+ on the client, and the form is a flat set of numeric inputs generated from
260
+ `/v1/schema/entities`. What the UI actually is — an unstyled dense numeric
261
+ matrix and hand-drawn animated orbit diagrams — is where React's headless
262
+ ecosystem (TanStack Table/Virtual, d3 interop) has no Angular equivalent
263
+ that is both free and design-language-neutral.
264
+ - **`/openapi.json` alone is not enough**, and assuming otherwise is the
265
+ trap. `api/schemas.py` types `Entity` as `type` + `id` + `extra="allow"`
266
+ on purpose, so OpenAPI describes the envelope, `Quantity` and the error
267
+ body — and zero entity fields. The per-type schema lives only at
268
+ `GET /v1/schema/entities`. `frontend/scripts/generate.ts` generates from
269
+ both; the second half is what lets one generic component render all 54
270
+ fields and 70 computed properties.
271
+ - Stack: Vite, React 19, TanStack Query (`keepPreviousData`, so a recompute
272
+ never blanks the screen), TanStack Table for the matrix tab, TanStack
273
+ Router for the tabs, zustand for the draft, CodeMirror 6 for the YAML tab.
274
+ - `make ui-install`, then `make api` and `make ui` in two shells. `make
275
+ ui-gen` regenerates the typed client against a running API.
276
+ - Nine tabs, including a **Live View**: the system animated on one scale,
277
+ with the habitable zone drawn on that same scale and hover tooltips on
278
+ every body. Bodies are coloured from the model — a star by `star_color`,
279
+ a planet by its atmosphere's `sky_color`, a moon grey, an airless planet
280
+ a darker grey.
281
+ - A command row for `load world` / `save world` / `load default`. Loading
282
+ posts the file as `application/yaml`, so the loader's opinions stay in
283
+ one place and a JSON world file works through the same path.
284
+ - [x] Atmospheric `sky_color` — the colour of the sky from the ground
285
+ - Single-scattered starlight through the Rayleigh column, von Kries adapted
286
+ to the local star. Earth reads `#788CC4`; a 90 atm column washes out to
287
+ near-white, which is what a saturated column should do.
288
+
289
+ ### 2026.0.4
290
+
291
+ - [x] Stateless HTTP API (FastAPI), so a web frontend can do what `-w` does
292
+ - [x] Phase 0: make the package survive outside its source checkout
293
+ - [x] Resolve version/name/description without reading `pyproject.toml` at import
294
+ - [x] Ship `data/default.yml` as declared package data
295
+ - [x] Stop the exporter crashing on optional fields a world leaves out
296
+ - [x] Validate a world file's units against the dimension the field declares
297
+ - [x] Log normal conditions at DEBUG instead of ERROR
298
+ - [x] Request-scoped `god` registry (`contextvars`)
299
+ - [x] `Worldloader.loads`/`load_data`/`to_dict` seams, JSON and YAML in/out
300
+ - [x] `AppError` -> HTTP status, inherited down the MRO
301
+ - [x] `api/` package: app, routers, schemas, JSON/YAML content negotiation
302
+ - [x] `POST /v1/world:compute`, `GET /v1/world/default`, `GET /v1/schema/entities`
303
+ - [x] Console entry points (`shamash`, `shamash-api`), `make api`
304
+ - [x] Fix the review findings: caller mistakes returning 500, blind 500 logs, CORS-less error bodies
305
+
306
+ ### v2026.0.3
307
+
308
+ - [x] Refactor and Introduce Atmospheric model
309
+ - Maybe even in naturedynamics, taking atmospheric models from omniastro
310
+ - [x] Introduce Plant Color and Biosphere Module
311
+ - Based on Star and Atmosphere
312
+ - [x] Geomagnetic Dynamics/ Solarmagnetic Dynamics
313
+ - [x] Make Habitability not true or false but a probability scale, taking into account:
314
+ - Class of the Star and Brightness
315
+ - Calculation Method relative habitability to how far the planet is away
316
+
317
+ ### v2026.0.2
318
+
319
+ Settled on name for project: shamash.
320
+
321
+ - [x] Rename Project
322
+ - [x] Refactor export/import handling
323
+ - do not use pprint, but format in cli as well
324
+ - use flag for cli dump
325
+ - [x] Unify Units handling, refactor bad claude code
326
+ - Every function should have their units as metadata with them - decorators?
327
+ - Distances in space are AU/Parsecs/Lightyears
328
+ - [x] Fix main_star_apparent_size=<error: division by zero>
329
+ - [x] Improve logging
330
+ - [x] Add a flag to write to a log file
331
+ - [x] Star Class Calculation
332
+ - [x] Add Star Classes as Enums, maybe directly into naturedynamics
333
+ - [x] Fix Hillsphere Calculation and Inner/Outer Moon Zone Error
334
+ - [x] Also push naturedynamics when pushing worldcreator
335
+ - As of 2026-09-01 naturedynamics is no longer a submodule; it lives at
336
+ `~/Dev/projects/naturedynamics` and is installed into the venv.
337
+ - Release Versioning and Cycle ?
338
+ - [x] Add Horizon Distance
339
+ - [x] Add proper error handling
340
+ - [x] Add a flag to init a new world yaml file
341
+ - `shamash init new_world`
342
+ - [x] Add Flag to point to yaml world file
343
+ - [x] Make color calculation refined and add Hexcolor support
344
+
345
+ ### v2026.0.1
346
+
347
+ Finally, first working version finished, shamash.
348
+
349
+ ### Backlog
350
+
351
+ - [ ] Add Habitable Zone Shift Factor for planets, to shift habitable zone bonds,
352
+ - regarding how many greenhouse gases exist
353
+ - Axial Tilt
354
+ - Orbital Period
355
+ - [ ] Make Apparent Brightness, etc a function that can be calculated at any given point of the orbit.
356
+ - [ ] Add LSol as Unit for Luminosity
357
+ - [ ] Change ASol to AU
358
+ - [ ] Decide what log level a _caller's_ mistake deserves
359
+ - `AppError` logs at ERROR on construction. Over HTTP every 422 is the
360
+ client's bad world, not a server incident, so a busy API fills the error
361
+ log with things no operator can act on — but the same exception from the
362
+ CLI, against a world file you just edited, is worth an ERROR. One class,
363
+ two contexts; Phase 0 already established `log_level=` as the mechanism.
364
+ - [x] Containerise — done under 2026.1.0 above, once unblocked on
365
+ 2026-09-01 by the package no longer reading `pyproject.toml` at import,
366
+ shipping its seed world as package data, and running (CLI and API both)
367
+ from a wheel with no source tree.
368
+ - [ ] `make venv` pins `--python 3.13` while the venv in use is 3.14.6
369
+ - Both satisfy `requires-python >=3.12`, so nothing is broken; it just means
370
+ `make venv` builds a different interpreter than everything is tested on.