aether-engine 1.8.0__tar.gz → 1.8.1__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 (123) hide show
  1. {aether_engine-1.8.0 → aether_engine-1.8.1}/MANIFEST.in +3 -0
  2. {aether_engine-1.8.0/aether_engine.egg-info → aether_engine-1.8.1}/PKG-INFO +12 -6
  3. {aether_engine-1.8.0 → aether_engine-1.8.1}/README.md +7 -1
  4. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/__init__.py +1 -1
  5. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/cli.py +36 -14
  6. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/_identity.py +1 -1
  7. aether_engine-1.8.1/aether/docs/GUIDE.md +270 -0
  8. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/ui/hud.py +67 -12
  9. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/web/content.py +10 -7
  10. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/web/plain_content.py +9 -4
  11. {aether_engine-1.8.0 → aether_engine-1.8.1/aether_engine.egg-info}/PKG-INFO +12 -6
  12. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether_engine.egg-info/SOURCES.txt +2 -0
  13. aether_engine-1.8.1/docs/GUIDE.md +270 -0
  14. {aether_engine-1.8.0 → aether_engine-1.8.1}/setup.py +1 -1
  15. {aether_engine-1.8.0 → aether_engine-1.8.1}/LICENSE +0 -0
  16. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/__main__.py +0 -0
  17. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/accelerators/__init__.py +0 -0
  18. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/accelerators/gameplay.py +0 -0
  19. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/accelerators/voxel.py +0 -0
  20. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/ai/behavior_tree.py +0 -0
  21. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/ai/navmesh.py +0 -0
  22. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/animation/skeleton.py +0 -0
  23. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/assets/__pycache__/asset_pipeline.cpython-314.pyc +0 -0
  24. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/assets/asset_pipeline.py +0 -0
  25. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/assets/fonts/AetherSans.ttf +0 -0
  26. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/audio/__init__.py +0 -0
  27. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/audio/audio_manager.py +0 -0
  28. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/audio/music.py +0 -0
  29. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/audio/sfx.py +0 -0
  30. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/audio/sound.py +0 -0
  31. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/__init__.py +0 -0
  32. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/achievement_system.py +0 -0
  33. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/application.py +0 -0
  34. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/boot_splash.py +0 -0
  35. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/branding_guard.py +0 -0
  36. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/config.py +0 -0
  37. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/console.py +0 -0
  38. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/engine.py +0 -0
  39. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/event_bus.py +0 -0
  40. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/input.py +0 -0
  41. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/plugin_system.py +0 -0
  42. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/save_system.py +0 -0
  43. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/time_manager.py +0 -0
  44. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/core/window.py +0 -0
  45. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/editor/__init__.py +0 -0
  46. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/environment/environment_system.py +0 -0
  47. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/__init__.py +0 -0
  48. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/camera.py +0 -0
  49. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/first_person.py +0 -0
  50. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/framebuffer.py +0 -0
  51. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/light.py +0 -0
  52. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/lod_system.py +0 -0
  53. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/material.py +0 -0
  54. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/mesh.py +0 -0
  55. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/mesh_factory.py +0 -0
  56. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/particle_system.py +0 -0
  57. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/post_process.py +0 -0
  58. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/renderer.py +0 -0
  59. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/shader.py +0 -0
  60. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/shader_library.py +0 -0
  61. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/sky_atmosphere.py +0 -0
  62. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/terrain.py +0 -0
  63. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/texture.py +0 -0
  64. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/voxel_mesh.py +0 -0
  65. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics/water.py +0 -0
  66. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/graphics2d/__init__.py +0 -0
  67. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/network/network_manager.py +0 -0
  68. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/physics/__init__.py +0 -0
  69. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/physics/bullet_backend.py +0 -0
  70. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/physics/collider.py +0 -0
  71. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/physics/physics2d.py +0 -0
  72. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/physics/physics3d.py +0 -0
  73. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/physics/physics_world.py +0 -0
  74. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/physics/raycast.py +0 -0
  75. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/physics/rigidbody.py +0 -0
  76. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/platform/steam_api.py +0 -0
  77. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/resources/__init__.py +0 -0
  78. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/resources/asset_database.py +0 -0
  79. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/resources/asset_loader.py +0 -0
  80. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/resources/loaders/model_loader.py +0 -0
  81. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/resources/loaders/obj_loader.py +0 -0
  82. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/resources/loaders/texture_loader.py +0 -0
  83. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/resources/resource_manager.py +0 -0
  84. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/resources/save_load.py +0 -0
  85. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/resources/serialization.py +0 -0
  86. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/scene/__init__.py +0 -0
  87. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/scene/component.py +0 -0
  88. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/scene/entity.py +0 -0
  89. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/scene/scene.py +0 -0
  90. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/scene/scene_graph.py +0 -0
  91. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/scene/scene_manager.py +0 -0
  92. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/tools/__init__.py +0 -0
  93. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/tools/packager.py +0 -0
  94. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/ui/__init__.py +0 -0
  95. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/ui/button.py +0 -0
  96. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/ui/canvas.py +0 -0
  97. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/ui/text.py +0 -0
  98. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/utils/__init__.py +0 -0
  99. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/utils/fonts.py +0 -0
  100. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/utils/logger.py +0 -0
  101. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/utils/math_utils.py +0 -0
  102. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/utils/object_pool.py +0 -0
  103. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/utils/profiler.py +0 -0
  104. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/web/__init__.py +0 -0
  105. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/web/bot_detect.py +0 -0
  106. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/web/config.py +0 -0
  107. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/web/notifications.py +0 -0
  108. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/web/plain.py +0 -0
  109. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/web/registry.py +0 -0
  110. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/web/secrets.py +0 -0
  111. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/web/server.py +0 -0
  112. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/web/templates.py +0 -0
  113. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether/web/urls.py +0 -0
  114. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether_engine.egg-info/dependency_links.txt +0 -0
  115. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether_engine.egg-info/entry_points.txt +0 -0
  116. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether_engine.egg-info/requires.txt +4 -4
  117. {aether_engine-1.8.0 → aether_engine-1.8.1}/aether_engine.egg-info/top_level.txt +0 -0
  118. {aether_engine-1.8.0 → aether_engine-1.8.1}/examples/01_hello_cube.py +0 -0
  119. {aether_engine-1.8.0 → aether_engine-1.8.1}/examples/02_sphere_scene.py +0 -0
  120. {aether_engine-1.8.0 → aether_engine-1.8.1}/examples/03_first_person.py +0 -0
  121. {aether_engine-1.8.0 → aether_engine-1.8.1}/examples/04_physics2d.py +0 -0
  122. {aether_engine-1.8.0 → aether_engine-1.8.1}/pyproject.toml +0 -0
  123. {aether_engine-1.8.0 → aether_engine-1.8.1}/setup.cfg +0 -0
@@ -1,13 +1,16 @@
1
1
  include README.md
2
2
  include LICENSE
3
3
  include pyproject.toml
4
+ include docs/GUIDE.md
4
5
 
5
6
  recursive-include aether *.py
6
7
  recursive-include aether *.glsl
7
8
  recursive-include aether *.vert
8
9
  recursive-include aether *.frag
9
10
  recursive-include aether *.json
11
+ recursive-include aether *.md
10
12
  recursive-include aether/assets *
13
+ recursive-include aether/docs *
11
14
 
12
15
  recursive-include examples *.py
13
16
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aether-engine
3
- Version: 1.8.0
3
+ Version: 1.8.1
4
4
  Summary: 3D/2D game engine by entiti937 — OpenGL, physics, FPS, mandatory branding splash
5
5
  Home-page: https://pypi.org/project/aether-engine/
6
6
  Author: entiti937
@@ -31,13 +31,13 @@ Requires-Dist: trimesh>=3.21; extra == "models"
31
31
  Provides-Extra: build
32
32
  Requires-Dist: pyinstaller>=6.0; extra == "build"
33
33
  Provides-Extra: full
34
- Requires-Dist: pygame-ce>=2.5; extra == "full"
35
- Requires-Dist: trimesh>=3.21; extra == "full"
34
+ Requires-Dist: pymunk>=6.0; extra == "full"
36
35
  Requires-Dist: imageio>=2.31; extra == "full"
37
- Requires-Dist: pyinstaller>=6.0; extra == "full"
38
36
  Requires-Dist: pyyaml>=6.0; extra == "full"
39
- Requires-Dist: pymunk>=6.0; extra == "full"
37
+ Requires-Dist: pyinstaller>=6.0; extra == "full"
40
38
  Requires-Dist: freetype-py>=2.4; extra == "full"
39
+ Requires-Dist: trimesh>=3.21; extra == "full"
40
+ Requires-Dist: pygame-ce>=2.5; extra == "full"
41
41
  Dynamic: author
42
42
  Dynamic: classifier
43
43
  Dynamic: description
@@ -52,7 +52,7 @@ Dynamic: summary
52
52
  # Aether Engine
53
53
 
54
54
  **3D / 2D игровой движок на Python + OpenGL**
55
- **Разработчик:** entiti937 · **Версия:** 1.8.0 · **Лицензия:** MIT
55
+ **Разработчик:** entiti937 · **Версия:** 1.8.1 · **Лицензия:** MIT
56
56
  **PyPI:** https://pypi.org/project/aether-engine/
57
57
 
58
58
  > Полное руководство: [`docs/GUIDE.md`](docs/GUIDE.md) · сайт: `aether website`
@@ -70,6 +70,12 @@ import aether # правильно
70
70
  # import aether_engine # НЕПРАВИЛЬНО — такого модуля нет
71
71
  ```
72
72
 
73
+ ## Что нового в 1.8.1
74
+
75
+ - `Hud.draw_bar(x, y, w, h, value, max_value, color)` — простой и понятный вызов
76
+ - `aether docs` печатает **полный** GUIDE.md (гайд вшит в пакет)
77
+ - Координаты HUD явно: (0,0) = центр экрана
78
+
73
79
  ## Что нового в 1.8.0
74
80
 
75
81
  - `Scene.remove()` / `despawn()` / `find()`
@@ -1,7 +1,7 @@
1
1
  # Aether Engine
2
2
 
3
3
  **3D / 2D игровой движок на Python + OpenGL**
4
- **Разработчик:** entiti937 · **Версия:** 1.8.0 · **Лицензия:** MIT
4
+ **Разработчик:** entiti937 · **Версия:** 1.8.1 · **Лицензия:** MIT
5
5
  **PyPI:** https://pypi.org/project/aether-engine/
6
6
 
7
7
  > Полное руководство: [`docs/GUIDE.md`](docs/GUIDE.md) · сайт: `aether website`
@@ -19,6 +19,12 @@ import aether # правильно
19
19
  # import aether_engine # НЕПРАВИЛЬНО — такого модуля нет
20
20
  ```
21
21
 
22
+ ## Что нового в 1.8.1
23
+
24
+ - `Hud.draw_bar(x, y, w, h, value, max_value, color)` — простой и понятный вызов
25
+ - `aether docs` печатает **полный** GUIDE.md (гайд вшит в пакет)
26
+ - Координаты HUD явно: (0,0) = центр экрана
27
+
22
28
  ## Что нового в 1.8.0
23
29
 
24
30
  - `Scene.remove()` / `despawn()` / `find()`
@@ -31,7 +31,7 @@ from aether.audio.sfx import SfxBank
31
31
  from aether.resources.save_load import save_json, load_json
32
32
  from aether.physics.raycast import Raycaster
33
33
 
34
- __version__ = "1.8.0"
34
+ __version__ = "1.8.1"
35
35
 
36
36
  from aether.graphics.voxel_mesh import ChunkedVoxelMesher
37
37
  from aether.accelerators import is_native_available, backend_name
@@ -60,10 +60,15 @@ TRANSFORM
60
60
  tf.set_position(x,y,z) / set_rotation / set_scale
61
61
  tf.translate(dx,dy,dz)
62
62
 
63
- HUD
63
+ HUD (координаты: 0,0 = ЦЕНТР экрана, +Y вверх; текста нет — пишите в title)
64
+ from aether import Hud
64
65
  engine.draw_hud = True
65
66
  hud = Hud(engine.renderer2d)
66
- hud.clear(); hud.draw_crosshair(); hud.draw_bar(...); hud.draw_hotbar(...)
67
+ hud.clear()
68
+ # draw_bar(x, y, width, height, value, max_value, color)
69
+ hud.draw_bar(-500, 300, 200, 20, hp, 100, (0.8, 0.2, 0.2, 1.0))
70
+ hud.draw_crosshair()
71
+ engine.window.set_title(f"HP {{hp}}")
67
72
 
68
73
  FPS / КАМЕРА
69
74
  engine.enable_first_person(camera, eye_height=1.7, walk_speed=6)
@@ -109,13 +114,13 @@ NPC / НАГРАДЫ (RUST, опционально)
109
114
  aether build my_game.py --name MyGame --console
110
115
 
111
116
  ИНСТРУМЕНТЫ
112
- aether help — эта справка
113
- aether docs — краткий гайд по API
114
- aether website — documentation site (domain in bell notifications)
117
+ aether help — краткая шпаргалка
118
+ aether docs — ПОЛНЫЙ гайд (весь GUIDE.md в терминал)
119
+ aether website — HTML-сайт документации
115
120
  python -m aether website
116
121
  python games/aether_craft.py
117
122
 
118
- ПОЛНАЯ ДОКУМЕНТАЦИЯ: docs/GUIDE.md
123
+ ПОЛНАЯ ДОКУМЕНТАЦИЯ: aether docs | сайт: aether website
119
124
  PyPI: https://pypi.org/project/aether-engine/
120
125
  """
121
126
 
@@ -126,12 +131,29 @@ def cmd_help(_args):
126
131
 
127
132
 
128
133
  def cmd_docs(_args):
129
- guide = Path(__file__).resolve().parents[2] / "docs" / "GUIDE.md"
130
- if guide.exists():
131
- print(guide.read_text(encoding="utf-8"))
132
- else:
133
- print(QUICK_REFERENCE)
134
- return 0
134
+ """Print the full bundled developer guide."""
135
+ here = Path(__file__).resolve().parent
136
+ candidates = [
137
+ here / "docs" / "GUIDE.md",
138
+ here.parents[1] / "docs" / "GUIDE.md",
139
+ here.parents[0] / "docs" / "GUIDE.md",
140
+ ]
141
+ for guide in candidates:
142
+ if guide.exists():
143
+ text = guide.read_text(encoding="utf-8")
144
+ try:
145
+ sys.stdout.reconfigure(encoding="utf-8", errors="replace")
146
+ except Exception:
147
+ pass
148
+ try:
149
+ print(text)
150
+ except UnicodeEncodeError:
151
+ sys.stdout.buffer.write(text.encode("utf-8", errors="replace"))
152
+ sys.stdout.buffer.write(b"\n")
153
+ return 0
154
+ print(QUICK_REFERENCE)
155
+ print("\n[aether docs] GUIDE.md not found in package — reinstall: pip install -U aether-engine")
156
+ return 1
135
157
 
136
158
 
137
159
  def cmd_build(args):
@@ -161,8 +183,8 @@ def main(argv=None):
161
183
 
162
184
  sub = parser.add_subparsers(dest="command")
163
185
 
164
- sub.add_parser("help", help="Краткая справка по API и командам").set_defaults(func=cmd_help)
165
- sub.add_parser("docs", help="Полная документация").set_defaults(func=cmd_docs)
186
+ sub.add_parser("help", help="Краткая шпаргалка").set_defaults(func=cmd_help)
187
+ sub.add_parser("docs", help="Полный гайд разработчика (весь GUIDE.md)").set_defaults(func=cmd_docs)
166
188
 
167
189
  p_build = sub.add_parser("build", help="Собрать игру в .exe (PyInstaller)")
168
190
  p_build.add_argument("script", help="Путь к main.py игры")
@@ -20,7 +20,7 @@ _B = {
20
20
  ]),
21
21
  "sig": bytes([
22
22
  230, 194, 211, 207, 194, 213, 135, 226, 201, 192, 206, 201, 194,
23
- 135, 150, 137, 159, 137, 151,
23
+ 135, 150, 137, 159, 137, 150,
24
24
  ]),
25
25
  }
26
26
 
@@ -0,0 +1,270 @@
1
+ # Aether Engine — Full Developer Guide
2
+
3
+ **Version:** 1.8.1 · **Author:** entiti937 · **License:** MIT
4
+ **PyPI package:** `aether-engine`
5
+ **Python import:** `import aether` ← NEVER `import aether_engine`
6
+
7
+ Commands:
8
+ - `aether help` — short cheat sheet
9
+ - `aether docs` — **this full guide** (printed to terminal)
10
+ - `aether website` — local HTML docs (+ `/plain/all` for AI)
11
+
12
+ ---
13
+
14
+ ## 0. Exact package names
15
+
16
+ ```bash
17
+ pip install -U "aether-engine[full]"
18
+ ```
19
+
20
+ ```python
21
+ from aether import Engine, Scene, Entity, Transform, MeshRenderer
22
+ from aether import MeshFactory, Material, Camera, Hud, HudBar, Sprite, AssetLoader
23
+ ```
24
+
25
+ ---
26
+
27
+ ## 1. Minimal 3D game
28
+
29
+ ```python
30
+ from aether import (
31
+ Engine, Scene, Entity, Transform, MeshRenderer,
32
+ MeshFactory, Material, Camera,
33
+ )
34
+
35
+ engine = Engine(1280, 720, "My Game")
36
+ scene = Scene("Main")
37
+ camera = Camera(position=(0, 2, 8), yaw=-90, pitch=-15)
38
+ scene.set_main_camera(camera)
39
+
40
+ cube = Entity("Cube")
41
+ cube.add_component(Transform(position=(0, 1, 0)))
42
+ mat = Material("green")
43
+ mat.albedo[:] = (0.2, 0.9, 0.4)
44
+ cube.add_component(MeshRenderer(mesh=MeshFactory.create_cube(), material=mat))
45
+ scene.spawn(cube)
46
+
47
+ engine.load_scene(scene)
48
+ engine.enable_first_person(camera)
49
+ engine.run() # blocks until ESC
50
+ ```
51
+
52
+ ---
53
+
54
+ ## 2. Scene — add / remove objects
55
+
56
+ ```python
57
+ scene.spawn(entity) # add
58
+ scene.remove(entity) # REMOVE from scene + destroy() ← use this to delete
59
+ scene.despawn(entity) # same as remove
60
+ found = scene.find("Player") # Entity or None
61
+ ```
62
+
63
+ **Important:** `entity.destroy()` alone does NOT remove it from `scene.entities`. Always prefer `scene.remove(entity)`.
64
+
65
+ ---
66
+
67
+ ## 3. Transform
68
+
69
+ `position`, `rotation`, `scale` = **numpy float32 arrays** length 3. Rotation in **degrees**.
70
+
71
+ ```python
72
+ tf = Transform(position=(0, 1, 0), rotation=(0, 45, 0), scale=(1, 1, 1))
73
+ tf.set_position(x, y, z)
74
+ tf.position[:] = (1, 2, 3)
75
+ tf.position[1] += 0.1
76
+ tf.translate(dx, dy, dz)
77
+ tf.set_rotation(rx, ry, rz)
78
+ tf.rotate(0, 90 * dt, 0)
79
+ tf.set_scale(sx, sy, sz)
80
+ ```
81
+
82
+ ---
83
+
84
+ ## 4. Camera
85
+
86
+ ```python
87
+ cam = Camera(position=(0, 5, 10), yaw=-90, pitch=-20, fov=60)
88
+ cam.position = (x, y, z) # tuple OK
89
+ cam.yaw = -45
90
+ cam.pitch = -15
91
+ cam.look_at(target) # world point or player_tf.position
92
+ cam.rotate(dx, dy) # mouse deltas
93
+ ```
94
+
95
+ Third-person follow:
96
+
97
+ ```python
98
+ engine.free_camera = False # REQUIRED when you move the camera yourself
99
+ target = player_tf.position
100
+ cam.position = (target[0], target[1] + 6, target[2] + 10)
101
+ cam.look_at(target)
102
+ ```
103
+
104
+ FPS: `engine.enable_first_person(camera, eye_height=1.7, walk_speed=6)`
105
+
106
+ ---
107
+
108
+ ## 5. MeshFactory — ALL primitives
109
+
110
+ | Method | Signature |
111
+ |--------|-----------|
112
+ | cube | `create_cube(size=1.0)` |
113
+ | plane | `create_plane(size=10.0)` |
114
+ | sphere | `create_sphere(radius=1.0, sectors=24, stacks=16)` |
115
+ | cylinder | `create_cylinder(radius=0.5, height=1.0, segments=24, capped=True)` |
116
+ | pyramid | `create_pyramid(size=1.0, height=1.0)` |
117
+
118
+ ```python
119
+ MeshFactory.create_cylinder(radius=0.8, height=3.0, segments=24)
120
+ ```
121
+
122
+ ---
123
+
124
+ ## 6. Material
125
+
126
+ ```python
127
+ mat = Material("metal")
128
+ mat.albedo[:] = (0.9, 0.2, 0.2) # RGB 0..1 numpy
129
+ mat.metallic = 0.8
130
+ mat.roughness = 0.3
131
+ mat.ao = 1.0
132
+ ```
133
+
134
+ ---
135
+
136
+ ## 7. HUD — exact API (read carefully)
137
+
138
+ Enable overlay:
139
+
140
+ ```python
141
+ from aether import Hud, HudBar
142
+
143
+ engine.draw_hud = True
144
+ hud = Hud(engine.renderer2d)
145
+ ```
146
+
147
+ **Coordinates:** origin `(0,0)` = **center of the window**, +X right, +Y up.
148
+ Not top-left pixels. On 1280×720, top-left area ≈ `(-500, 300)`.
149
+
150
+ **No bitmap text yet.** Put strings in the window title:
151
+
152
+ ```python
153
+ engine.window.set_title(f"HP {hp} | score {score}")
154
+ ```
155
+
156
+ ### draw_bar — exact signatures
157
+
158
+ ```python
159
+ # RECOMMENDED — current value + max value + color
160
+ hud.draw_bar(x, y, width, height, value, max_value, color)
161
+ hud.draw_bar(-500, 300, 200, 20, hp, 100, (0.8, 0.2, 0.2, 1.0))
162
+
163
+ # Fraction 0..1 only
164
+ hud.draw_bar(-500, 300, 200, 20, 0.75)
165
+
166
+ # HudBar object
167
+ hud.draw_bar(-500, 300, 200, 20, HudBar("hp", value=0.75, color=(0.8, 0.2, 0.2, 1.0)))
168
+ ```
169
+
170
+ ### Other HUD methods
171
+
172
+ ```python
173
+ hud.clear() # call every frame before drawing
174
+ hud.draw_crosshair(size=10, thickness=2)
175
+ hud.draw_hotbar(slots=7, selected=0, colors=[(1,0,0), (0,1,0)], y=-220)
176
+ hud.draw_rect(x, y, width, height, color=(1,1,1,1), layer=70)
177
+ hud.draw_panel(x, y, width, height)
178
+ ```
179
+
180
+ Full frame example:
181
+
182
+ ```python
183
+ def update(dt):
184
+ hud.clear()
185
+ hud.draw_bar(-500, 300, 200, 20, hp, 100, (0.8, 0.2, 0.2, 1.0))
186
+ hud.draw_crosshair()
187
+ engine.window.set_title(f"HP {hp}")
188
+ ```
189
+
190
+ ---
191
+
192
+ ## 8. Assets
193
+
194
+ ```python
195
+ from aether import AssetLoader, Sprite
196
+
197
+ mesh = AssetLoader.load_model("hero.glb")
198
+ sprite = Sprite.from_image("icon.png", x=0, y=0)
199
+ tex_id = AssetLoader.load_texture("wall.jpg")
200
+ ```
201
+
202
+ ---
203
+
204
+ ## 9. Physics
205
+
206
+ **2D (ready):** `engine.physics2d` (pymunk) — see `examples/04_physics2d.py`
207
+
208
+ ```python
209
+ engine.set_mode("2d")
210
+ pw = engine.physics2d
211
+ ground = pw.create_box(0, -200, 600, 40, static=True)
212
+ ball = pw.create_circle(0, 0, 20, mass=1.0)
213
+ sprite.x, sprite.y = ball.x, ball.y # Y-up, same space
214
+ ```
215
+
216
+ **3D:** lightweight built-in solver. PyBullet/Jolt planned later.
217
+
218
+ ```python
219
+ from aether import BoxCollider
220
+ body = engine.physics3d.create_body_for_entity(ent, mass=1.0, collider=BoxCollider(size=(1,1,1)))
221
+ ```
222
+
223
+ ---
224
+
225
+ ## 10. Input / update
226
+
227
+ ```python
228
+ import glfw
229
+
230
+ def update(dt):
231
+ if engine.input.get_key(glfw.KEY_W):
232
+ ...
233
+ if engine.input.get_key_down(glfw.KEY_SPACE):
234
+ ...
235
+
236
+ engine.on_update(update)
237
+ ```
238
+
239
+ ---
240
+
241
+ ## 11. Window vs audio
242
+
243
+ - **GLFW** — window, input, OpenGL 4.6
244
+ - **pygame-ce** — sound mixer only (display never initialized)
245
+
246
+ ---
247
+
248
+ ## 12. CLI
249
+
250
+ ```bash
251
+ aether help
252
+ aether docs # full guide (this file)
253
+ aether website # HTML docs on localhost
254
+ aether build game.py --name MyGame
255
+ ```
256
+
257
+ ---
258
+
259
+ ## 13. Examples
260
+
261
+ | File | Topic |
262
+ |------|--------|
263
+ | `examples/01_hello_cube.py` | Basics |
264
+ | `examples/02_sphere_scene.py` | Materials |
265
+ | `examples/03_first_person.py` | FPS |
266
+ | `examples/04_physics2d.py` | 2D physics |
267
+
268
+ ---
269
+
270
+ Aether Engine © entiti937
@@ -2,21 +2,40 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  from dataclasses import dataclass
5
- from typing import List, Tuple
5
+ from typing import List, Optional, Tuple, Union
6
6
 
7
7
  from aether.graphics2d import Sprite
8
8
 
9
+ Color = Tuple[float, float, float, float]
10
+
9
11
 
10
12
  @dataclass
11
13
  class HudBar:
12
- label: str
13
- value: float # 0..1
14
- color: Tuple[float, float, float, float] = (0.2, 0.85, 0.35, 0.95)
15
- back: Tuple[float, float, float, float] = (0.1, 0.1, 0.12, 0.7)
14
+ """Progress bar data. value is 0..1 (fraction filled)."""
15
+
16
+ label: str = ""
17
+ value: float = 1.0 # 0..1
18
+ color: Color = (0.2, 0.85, 0.35, 0.95)
19
+ back: Color = (0.1, 0.1, 0.12, 0.7)
16
20
 
17
21
 
18
22
  class Hud:
19
- """Build sprites for a simple game HUD (hotbar, bars, crosshair)."""
23
+ """
24
+ Immediate-mode HUD (colored rectangles only — no TrueType text yet).
25
+
26
+ Coordinate system (IMPORTANT):
27
+ Origin (0, 0) = CENTER of the window.
28
+ +X right, +Y up. Same as engine 2D mode.
29
+ Example top-left HP bar on 1280x720: draw_bar(-500, 300, 200, 20, hp, 100)
30
+
31
+ Typical usage each frame:
32
+ engine.draw_hud = True
33
+ hud = Hud(engine.renderer2d)
34
+ hud.clear()
35
+ hud.draw_bar(-500, 300, 200, 20, hp, max_hp, (0.8, 0.2, 0.2, 1.0))
36
+ hud.draw_crosshair()
37
+ engine.window.set_title(f"HP {hp}") # text goes here for now
38
+ """
20
39
 
21
40
  def __init__(self, renderer2d):
22
41
  self.r = renderer2d
@@ -24,6 +43,7 @@ class Hud:
24
43
  self._owned: List[Sprite] = []
25
44
 
26
45
  def clear(self):
46
+ """Remove HUD sprites from last frame. Call once at the start of each update."""
27
47
  for s in self._owned:
28
48
  if s in self.r.sprites:
29
49
  self.r.sprites.remove(s)
@@ -35,11 +55,13 @@ class Hud:
35
55
  return sprite
36
56
 
37
57
  def draw_crosshair(self, size: float = 10.0, thickness: float = 2.0):
58
+ """White crosshair at screen center."""
38
59
  c = (1, 1, 1, 0.9)
39
60
  self._add(Sprite(0, 0, size, thickness, color=c, layer=100))
40
61
  self._add(Sprite(0, 0, thickness, size, color=c, layer=100))
41
62
 
42
63
  def draw_hotbar(self, slots: int, selected: int, colors, y: float = -220):
64
+ """Inventory-style slots along the bottom."""
43
65
  slot_w, slot_h, gap = 44, 44, 6
44
66
  total = slots * slot_w + (slots - 1) * gap
45
67
  start_x = -total * 0.5 + slot_w * 0.5
@@ -50,7 +72,40 @@ class Hud:
50
72
  col = colors[i] if i < len(colors) else (0.4, 0.4, 0.4, 1)
51
73
  self._add(Sprite(x, y, slot_w - 6, slot_h - 6, color=(*col[:3], 1.0), layer=91))
52
74
 
53
- def draw_bar(self, x: float, y: float, width: float, height: float, bar: HudBar):
75
+ def draw_bar(
76
+ self,
77
+ x: float,
78
+ y: float,
79
+ width: float,
80
+ height: float,
81
+ value: Union[float, HudBar],
82
+ max_value: Optional[float] = None,
83
+ color: Color = (0.8, 0.2, 0.2, 1.0),
84
+ back: Color = (0.1, 0.1, 0.12, 0.7),
85
+ ):
86
+ """
87
+ Draw a horizontal progress bar. Center of the bar is at (x, y).
88
+
89
+ Easy form (recommended):
90
+ hud.draw_bar(-500, 300, 200, 20, hp, 100, (0.8, 0.2, 0.2, 1.0))
91
+ # x y w h cur max RGBA color
92
+
93
+ With fraction 0..1:
94
+ hud.draw_bar(-500, 300, 200, 20, 0.75)
95
+
96
+ With HudBar object:
97
+ hud.draw_bar(-500, 300, 200, 20, HudBar("hp", value=0.75, color=(...)))
98
+ """
99
+ if isinstance(value, HudBar):
100
+ bar = value
101
+ else:
102
+ cur = float(value)
103
+ if max_value is None or float(max_value) <= 0:
104
+ frac = cur if 0.0 <= cur <= 1.0 else 0.0
105
+ else:
106
+ frac = cur / float(max_value)
107
+ bar = HudBar(value=frac, color=color, back=back)
108
+
54
109
  self._add(Sprite(x, y, width, height, color=bar.back, layer=80))
55
110
  fill = max(0.0, min(1.0, bar.value)) * (width - 4)
56
111
  self._add(
@@ -70,10 +125,10 @@ class Hud:
70
125
  y: float,
71
126
  width: float,
72
127
  height: float,
73
- color=(1.0, 1.0, 1.0, 1.0),
128
+ color: Color = (1.0, 1.0, 1.0, 1.0),
74
129
  layer: int = 70,
75
130
  ):
76
- """Draw a solid screen-space rectangle (center at x,y)."""
131
+ """Solid rectangle. Center at (x, y)."""
77
132
  self._add(Sprite(x, y, width, height, color=color, layer=layer))
78
133
 
79
134
  def draw_panel(
@@ -82,11 +137,11 @@ class Hud:
82
137
  y: float,
83
138
  width: float,
84
139
  height: float,
85
- fill=(0.05, 0.06, 0.08, 0.75),
86
- border=(0.9, 0.9, 0.95, 0.9),
140
+ fill: Color = (0.05, 0.06, 0.08, 0.75),
141
+ border: Color = (0.9, 0.9, 0.95, 0.9),
87
142
  border_thickness: float = 2.0,
88
143
  ):
89
- """Draw a simple bordered panel (no text — use window title / print for text)."""
144
+ """Bordered panel. No text — use engine.window.set_title(...) for strings."""
90
145
  self.draw_rect(x, y, width, height, color=fill, layer=70)
91
146
  t = border_thickness
92
147
  self.draw_rect(x, y + height * 0.5, width, t, color=border, layer=71)
@@ -247,16 +247,19 @@ mat.metallic = 0.8
247
247
  mat.roughness = 0.3</code></pre>
248
248
 
249
249
  <h2>Hud</h2>
250
- <p>Colored quads only — <strong>no bitmap text yet</strong>. Use window title for scores.</p>
251
- <pre><code>from aether import Hud, HudBar
250
+ <p><strong>Coords:</strong> (0,0) = center of window, +Y up. No text — use <code>engine.window.set_title(...)</code>.</p>
251
+ <pre><code>from aether import Hud
252
+
252
253
  engine.draw_hud = True
253
254
  hud = Hud(engine.renderer2d)
254
255
  hud.clear()
256
+ # draw_bar(x, y, width, height, value, max_value, color)
257
+ hud.draw_bar(-500, 300, 200, 20, hp, 100, (0.8, 0.2, 0.2, 1.0))
255
258
  hud.draw_crosshair()
256
- hud.draw_bar(-400, 300, 200, 18, HudBar("hp", value=0.75))
257
259
  hud.draw_hotbar(7, 0, colors=[(1,0,0),(0,1,0)])
258
260
  hud.draw_rect(0, -250, 120, 40, color=(0,0,0,0.5))
259
- hud.draw_panel(0, 250, 300, 60)</code></pre>
261
+ hud.draw_panel(0, 250, 300, 60)
262
+ engine.window.set_title(f"HP {hp}")</code></pre>
260
263
  </section>
261
264
  """,
262
265
  "api-3d": """
@@ -322,8 +325,8 @@ hero = Sprite.from_image("sprites/hero.png", x=0, y=0)
322
325
  engine.renderer2d.add_sprite(hero)</code></pre>
323
326
 
324
327
  <h2>HUD on top of 3D</h2>
325
- <p>Colored quads only (no TrueType text yet). Use window title for scores.</p>
326
- <pre><code>from aether import Hud, HudBar
328
+ <p>Coords: (0,0)=screen center. Exact bar API:</p>
329
+ <pre><code>from aether import Hud
327
330
 
328
331
  engine.draw_hud = True
329
332
  hud = Hud(engine.renderer2d)
@@ -331,7 +334,7 @@ hud = Hud(engine.renderer2d)
331
334
  def update(dt):
332
335
  hud.clear()
333
336
  hud.draw_crosshair(size=12)
334
- hud.draw_bar(-500, 320, 220, 16, HudBar("hp", value=0.75))
337
+ hud.draw_bar(-500, 320, 220, 16, hp, 100, (0.8, 0.2, 0.2, 1.0))
335
338
  engine.window.set_title(f"Score {score}")
336
339
 
337
340
  engine.on_update(update)</code></pre>
@@ -133,9 +133,13 @@ MATERIAL
133
133
  - albedo (np.array RGB), metallic, roughness, ao
134
134
 
135
135
  HUD (engine.draw_hud=True; no text rendering yet)
136
- - clear(), draw_crosshair(), draw_bar(x,y,w,h,HudBar), draw_hotbar(...)
137
- - draw_rect(...), draw_panel(...)
138
- - Use engine.window.set_title(...) for score text
136
+ - Coords: (0,0)=CENTER of window, +Y up
137
+ - clear() every frame
138
+ - draw_bar(x, y, width, height, value, max_value, color)
139
+ Example: hud.draw_bar(-500, 300, 200, 20, hp, 100, (0.8, 0.2, 0.2, 1.0))
140
+ - Also: draw_bar(..., 0.75) fraction, or draw_bar(..., HudBar(...))
141
+ - draw_crosshair(), draw_hotbar(...), draw_rect(...), draw_panel(...)
142
+ - Text: engine.window.set_title(f"HP {hp}")
139
143
  """,
140
144
  "api-3d": """
141
145
  Engine(width, height, title)
@@ -150,7 +154,8 @@ scene.remove(entity)
150
154
  engine.set_mode("2d")
151
155
  engine.renderer2d.add_sprite(Sprite(x, y, w, h, color=(r,g,b,a)))
152
156
  Sprite.from_image("icon.png")
153
- Hud: draw_crosshair, draw_bar, draw_hotbar, draw_rect, draw_panel (no text)
157
+ Hud: draw_bar(x,y,w,h, value, max_value, color) — also fraction or HudBar
158
+ Coords (0,0)=screen center. draw_crosshair, draw_hotbar, draw_rect, draw_panel (no text)
154
159
  """,
155
160
  "physics": """
156
161
  2D PHYSICS — AVAILABLE NOW (pymunk via engine.physics2d)