pyguara 0.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 (146) hide show
  1. pyguara-0.2.0/.gitignore +181 -0
  2. pyguara-0.2.0/LICENSE +8 -0
  3. pyguara-0.2.0/PKG-INFO +167 -0
  4. pyguara-0.2.0/README.md +121 -0
  5. pyguara-0.2.0/pyguara/__init__.py +0 -0
  6. pyguara-0.2.0/pyguara/ai/ai_system.py +29 -0
  7. pyguara-0.2.0/pyguara/ai/blackboard.py +32 -0
  8. pyguara-0.2.0/pyguara/ai/components.py +76 -0
  9. pyguara-0.2.0/pyguara/ai/fsm.py +82 -0
  10. pyguara-0.2.0/pyguara/ai/pathfinding/astar.py +58 -0
  11. pyguara-0.2.0/pyguara/ai/pathfinding/core.py +29 -0
  12. pyguara-0.2.0/pyguara/ai/pathfinding/grid.py +72 -0
  13. pyguara-0.2.0/pyguara/ai/steering.py +55 -0
  14. pyguara-0.2.0/pyguara/app_scene.py +132 -0
  15. pyguara-0.2.0/pyguara/application/__init__.py +6 -0
  16. pyguara-0.2.0/pyguara/application/application.py +100 -0
  17. pyguara-0.2.0/pyguara/application/bootstrap.py +132 -0
  18. pyguara-0.2.0/pyguara/application/sandbox.py +116 -0
  19. pyguara-0.2.0/pyguara/audio/__init__.py +1 -0
  20. pyguara-0.2.0/pyguara/audio/audio_system.py +116 -0
  21. pyguara-0.2.0/pyguara/audio/backends/pygame/loaders.py +30 -0
  22. pyguara-0.2.0/pyguara/audio/backends/pygame/pygame_audio.py +185 -0
  23. pyguara-0.2.0/pyguara/audio/backends/pygame/types.py +37 -0
  24. pyguara-0.2.0/pyguara/audio/manager.py +248 -0
  25. pyguara-0.2.0/pyguara/common/components.py +316 -0
  26. pyguara-0.2.0/pyguara/common/constants.py +1 -0
  27. pyguara-0.2.0/pyguara/common/palette.py +43 -0
  28. pyguara-0.2.0/pyguara/common/types.py +311 -0
  29. pyguara-0.2.0/pyguara/config/__init__.py +14 -0
  30. pyguara-0.2.0/pyguara/config/events.py +39 -0
  31. pyguara-0.2.0/pyguara/config/manager.py +128 -0
  32. pyguara-0.2.0/pyguara/config/types.py +82 -0
  33. pyguara-0.2.0/pyguara/config/validation.py +76 -0
  34. pyguara-0.2.0/pyguara/di/__init__.py +34 -0
  35. pyguara-0.2.0/pyguara/di/container.py +369 -0
  36. pyguara-0.2.0/pyguara/di/decorators.py +56 -0
  37. pyguara-0.2.0/pyguara/di/exceptions.py +33 -0
  38. pyguara-0.2.0/pyguara/di/types.py +70 -0
  39. pyguara-0.2.0/pyguara/ecs/__init__.py +14 -0
  40. pyguara-0.2.0/pyguara/ecs/component.py +40 -0
  41. pyguara-0.2.0/pyguara/ecs/entity.py +158 -0
  42. pyguara-0.2.0/pyguara/ecs/manager.py +195 -0
  43. pyguara-0.2.0/pyguara/ecs/query_cache.py +197 -0
  44. pyguara-0.2.0/pyguara/editor/__init__.py +1 -0
  45. pyguara-0.2.0/pyguara/editor/drawers.py +187 -0
  46. pyguara-0.2.0/pyguara/editor/layer.py +165 -0
  47. pyguara-0.2.0/pyguara/editor/panels/assets.py +163 -0
  48. pyguara-0.2.0/pyguara/editor/panels/hierarchy.py +64 -0
  49. pyguara-0.2.0/pyguara/editor/panels/inspector.py +81 -0
  50. pyguara-0.2.0/pyguara/error/__init__.py +24 -0
  51. pyguara-0.2.0/pyguara/error/exceptions.py +107 -0
  52. pyguara-0.2.0/pyguara/error/handlers.py +110 -0
  53. pyguara-0.2.0/pyguara/error/types.py +27 -0
  54. pyguara-0.2.0/pyguara/events/__init__.py +1 -0
  55. pyguara-0.2.0/pyguara/events/dispatcher.py +161 -0
  56. pyguara-0.2.0/pyguara/events/input.py +50 -0
  57. pyguara-0.2.0/pyguara/events/lifecycle.py +31 -0
  58. pyguara-0.2.0/pyguara/events/protocols.py +92 -0
  59. pyguara-0.2.0/pyguara/events/types.py +40 -0
  60. pyguara-0.2.0/pyguara/events/window.py +20 -0
  61. pyguara-0.2.0/pyguara/graphics/__init__.py +1 -0
  62. pyguara-0.2.0/pyguara/graphics/animation_system.py +37 -0
  63. pyguara-0.2.0/pyguara/graphics/atlas.py +110 -0
  64. pyguara-0.2.0/pyguara/graphics/backends/headless_renderer.py +115 -0
  65. pyguara-0.2.0/pyguara/graphics/backends/pygame/loaders.py +27 -0
  66. pyguara-0.2.0/pyguara/graphics/backends/pygame/pygame_renderer.py +113 -0
  67. pyguara-0.2.0/pyguara/graphics/backends/pygame/pygame_window.py +75 -0
  68. pyguara-0.2.0/pyguara/graphics/backends/pygame/types.py +34 -0
  69. pyguara-0.2.0/pyguara/graphics/backends/pygame/ui_renderer.py +115 -0
  70. pyguara-0.2.0/pyguara/graphics/color.py +1 -0
  71. pyguara-0.2.0/pyguara/graphics/components/__init__.py +27 -0
  72. pyguara-0.2.0/pyguara/graphics/components/animation.py +312 -0
  73. pyguara-0.2.0/pyguara/graphics/components/camera.py +407 -0
  74. pyguara-0.2.0/pyguara/graphics/components/geometry.py +150 -0
  75. pyguara-0.2.0/pyguara/graphics/components/particles.py +387 -0
  76. pyguara-0.2.0/pyguara/graphics/components/sprite.py +32 -0
  77. pyguara-0.2.0/pyguara/graphics/pipeline/batch.py +99 -0
  78. pyguara-0.2.0/pyguara/graphics/pipeline/queue.py +37 -0
  79. pyguara-0.2.0/pyguara/graphics/pipeline/render_system.py +95 -0
  80. pyguara-0.2.0/pyguara/graphics/pipeline/viewport.py +147 -0
  81. pyguara-0.2.0/pyguara/graphics/protocols.py +318 -0
  82. pyguara-0.2.0/pyguara/graphics/spritesheet.py +79 -0
  83. pyguara-0.2.0/pyguara/graphics/types.py +66 -0
  84. pyguara-0.2.0/pyguara/graphics/window.py +80 -0
  85. pyguara-0.2.0/pyguara/input/__init__.py +21 -0
  86. pyguara-0.2.0/pyguara/input/binding.py +42 -0
  87. pyguara-0.2.0/pyguara/input/events.py +63 -0
  88. pyguara-0.2.0/pyguara/input/gamepad.py +358 -0
  89. pyguara-0.2.0/pyguara/input/keys.py +19 -0
  90. pyguara-0.2.0/pyguara/input/manager.py +196 -0
  91. pyguara-0.2.0/pyguara/input/types.py +114 -0
  92. pyguara-0.2.0/pyguara/log/__init__.py +19 -0
  93. pyguara-0.2.0/pyguara/log/events.py +31 -0
  94. pyguara-0.2.0/pyguara/log/handlers.py +75 -0
  95. pyguara-0.2.0/pyguara/log/logger.py +173 -0
  96. pyguara-0.2.0/pyguara/log/manager.py +68 -0
  97. pyguara-0.2.0/pyguara/log/types.py +30 -0
  98. pyguara-0.2.0/pyguara/persistence/manager.py +136 -0
  99. pyguara-0.2.0/pyguara/persistence/serializer.py +110 -0
  100. pyguara-0.2.0/pyguara/persistence/storage.py +99 -0
  101. pyguara-0.2.0/pyguara/persistence/types.py +77 -0
  102. pyguara-0.2.0/pyguara/physics/__init__.py +17 -0
  103. pyguara-0.2.0/pyguara/physics/backends/pymunk_impl.py +448 -0
  104. pyguara-0.2.0/pyguara/physics/collision_system.py +295 -0
  105. pyguara-0.2.0/pyguara/physics/components.py +63 -0
  106. pyguara-0.2.0/pyguara/physics/events.py +187 -0
  107. pyguara-0.2.0/pyguara/physics/joints.py +349 -0
  108. pyguara-0.2.0/pyguara/physics/materials.py +63 -0
  109. pyguara-0.2.0/pyguara/physics/physics_system.py +109 -0
  110. pyguara-0.2.0/pyguara/physics/protocols.py +138 -0
  111. pyguara-0.2.0/pyguara/physics/types.py +103 -0
  112. pyguara-0.2.0/pyguara/resources/data.py +69 -0
  113. pyguara-0.2.0/pyguara/resources/loader.py +43 -0
  114. pyguara-0.2.0/pyguara/resources/loaders/data_loader.py +40 -0
  115. pyguara-0.2.0/pyguara/resources/manager.py +368 -0
  116. pyguara-0.2.0/pyguara/resources/types.py +75 -0
  117. pyguara-0.2.0/pyguara/scene/base.py +83 -0
  118. pyguara-0.2.0/pyguara/scene/manager.py +55 -0
  119. pyguara-0.2.0/pyguara/scene/serializer.py +93 -0
  120. pyguara-0.2.0/pyguara/tools/base.py +80 -0
  121. pyguara-0.2.0/pyguara/tools/debugger.py +80 -0
  122. pyguara-0.2.0/pyguara/tools/event_monitor.py +83 -0
  123. pyguara-0.2.0/pyguara/tools/inspector.py +166 -0
  124. pyguara-0.2.0/pyguara/tools/manager.py +132 -0
  125. pyguara-0.2.0/pyguara/tools/performance.py +59 -0
  126. pyguara-0.2.0/pyguara/tools/shortcuts_panel.py +59 -0
  127. pyguara-0.2.0/pyguara/ui/__init__.py +27 -0
  128. pyguara-0.2.0/pyguara/ui/base.py +117 -0
  129. pyguara-0.2.0/pyguara/ui/components/__init__.py +27 -0
  130. pyguara-0.2.0/pyguara/ui/components/button.py +48 -0
  131. pyguara-0.2.0/pyguara/ui/components/canvas.py +29 -0
  132. pyguara-0.2.0/pyguara/ui/components/checkbox.py +60 -0
  133. pyguara-0.2.0/pyguara/ui/components/image.py +27 -0
  134. pyguara-0.2.0/pyguara/ui/components/label.py +35 -0
  135. pyguara-0.2.0/pyguara/ui/components/navbar.py +33 -0
  136. pyguara-0.2.0/pyguara/ui/components/panel.py +31 -0
  137. pyguara-0.2.0/pyguara/ui/components/progress_bar.py +36 -0
  138. pyguara-0.2.0/pyguara/ui/components/slider.py +84 -0
  139. pyguara-0.2.0/pyguara/ui/components/text.py +46 -0
  140. pyguara-0.2.0/pyguara/ui/components/text_input.py +77 -0
  141. pyguara-0.2.0/pyguara/ui/components/widget.py +25 -0
  142. pyguara-0.2.0/pyguara/ui/layout.py +87 -0
  143. pyguara-0.2.0/pyguara/ui/manager.py +58 -0
  144. pyguara-0.2.0/pyguara/ui/theme.py +37 -0
  145. pyguara-0.2.0/pyguara/ui/types.py +113 -0
  146. pyguara-0.2.0/pyproject.toml +289 -0
@@ -0,0 +1,181 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Unit test / coverage reports
36
+ htmlcov/
37
+ .tox/
38
+ .nox/
39
+ .coverage
40
+ .coverage.*
41
+ .cache
42
+ nosetests.xml
43
+ coverage.xml
44
+ *.cover
45
+ *.py,cover
46
+ .hypothesis/
47
+ .pytest_cache/
48
+ cover/
49
+
50
+ # Translations
51
+ *.mo
52
+ *.pot
53
+
54
+ # Django stuff:
55
+ *.log
56
+ local_settings.py
57
+ db.sqlite3
58
+ db.sqlite3-journal
59
+
60
+ # Flask stuff:
61
+ instance/
62
+ .webassets-cache
63
+
64
+ # Scrapy stuff:
65
+ .scrapy
66
+
67
+ # Sphinx documentation
68
+ docs/_build/
69
+
70
+ # PyBuilder
71
+ .pybuilder/
72
+ target/
73
+
74
+ # Jupyter Notebook
75
+ .ipynb_checkpoints
76
+
77
+ # IPython
78
+ profile_default/
79
+ ipython_config.py
80
+
81
+ # pyenv
82
+ # For a library or package, you might want to ignore these files since the code is
83
+ # intended to run in multiple environments; otherwise, check them in:
84
+ # .python-version
85
+
86
+ # pipenv
87
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
88
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
89
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
90
+ # install all needed dependencies.
91
+ #Pipfile.lock
92
+
93
+ # poetry
94
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
95
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
96
+ # commonly ignored for libraries.
97
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
98
+ #poetry.lock
99
+
100
+ # pdm
101
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
102
+ #pdm.lock
103
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
104
+ # in version control.
105
+ # https://pdm.fming.dev/#use-with-ide
106
+ .pdm.toml
107
+
108
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
109
+ __pypackages__/
110
+
111
+ # Celery stuff
112
+ celerybeat-schedule
113
+ celerybeat.pid
114
+
115
+ # SageMath parsed files
116
+ *.sage.py
117
+
118
+ # Environments
119
+ .env
120
+ .venv
121
+ env/
122
+ venv/
123
+ ENV/
124
+ env.bak/
125
+ venv.bak/
126
+
127
+ # Spyder project settings
128
+ .spyderproject
129
+ .spyproject
130
+
131
+ # Rope project settings
132
+ .ropeproject
133
+
134
+ # mkdocs documentation
135
+ /site
136
+
137
+ # mypy
138
+ .mypy_cache/
139
+ .dmypy.json
140
+ dmypy.json
141
+
142
+ # Pyre type checker
143
+ .pyre/
144
+
145
+ # pytype static type analyzer
146
+ .pytype/
147
+
148
+ # Cython debug symbols
149
+ cython_debug/
150
+
151
+ # PyCharm
152
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
153
+ # be added to the global gitignore or merged into this project gitignore. For a PyCharm
154
+ # project, it is recommended to ignore these files.
155
+ .idea/
156
+
157
+ # UV specific
158
+ .uv/
159
+
160
+ # Project specific
161
+ *.profile
162
+ *.stats
163
+ *.prof
164
+
165
+ # Game specific
166
+ saves/
167
+ logs/
168
+ *.log
169
+
170
+ # Configuration runtime files
171
+ temp/
172
+ screenshots/
173
+
174
+ # OS specific
175
+ .DS_Store
176
+ .DS_Store?
177
+ ._*
178
+ .Spotlight-V100
179
+ .Trashes
180
+ ehthumbs.db
181
+ Thumbs.db
pyguara-0.2.0/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ The MIT License (MIT)
2
+ Copyright © 2026 Wedeueis Braz
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
+
6
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
+
8
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
pyguara-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,167 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyguara
3
+ Version: 0.2.0
4
+ Summary: Python game engine featuring a event and data driven archictecture.
5
+ Author-email: Wedeueis Braz <wedeueisbraz@gmail.com>
6
+ License-File: LICENSE
7
+ Keywords: 2d,action-rpg,data-driven,event-driven,game-engine
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Topic :: Games/Entertainment
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Requires-Python: >=3.12
16
+ Requires-Dist: click>=8.1.7
17
+ Requires-Dist: dataclasses-json>=0.6.0
18
+ Requires-Dist: msgpack>=1.1.2
19
+ Requires-Dist: pillow>=12.1.0
20
+ Requires-Dist: pygame-ce>=2.5.6
21
+ Requires-Dist: pymunk>=7.2.0
22
+ Provides-Extra: benchmark
23
+ Requires-Dist: memory-profiler>=0.61.0; extra == 'benchmark'
24
+ Requires-Dist: py-spy>=0.3.0; extra == 'benchmark'
25
+ Requires-Dist: pytest-benchmark>=4.0.0; extra == 'benchmark'
26
+ Provides-Extra: dev
27
+ Requires-Dist: build>=0.10.0; extra == 'dev'
28
+ Requires-Dist: imgui>=2.0.0; extra == 'dev'
29
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
30
+ Requires-Dist: pillow>=11.3.0; extra == 'dev'
31
+ Requires-Dist: pre-commit>=3.0.0; extra == 'dev'
32
+ Requires-Dist: pytest-benchmark>=4.0.0; extra == 'dev'
33
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
34
+ Requires-Dist: pytest-mock>=3.10.0; extra == 'dev'
35
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
36
+ Requires-Dist: ruff>=0.14.0; extra == 'dev'
37
+ Requires-Dist: syrupy>=4.9.1; extra == 'dev'
38
+ Requires-Dist: tox>=4.0.0; extra == 'dev'
39
+ Requires-Dist: twine>=4.0.0; extra == 'dev'
40
+ Provides-Extra: docs
41
+ Requires-Dist: mkdocs-material>=9.0.0; extra == 'docs'
42
+ Requires-Dist: mkdocs-mermaid2-plugin>=0.6.0; extra == 'docs'
43
+ Requires-Dist: mkdocs>=1.5.0; extra == 'docs'
44
+ Requires-Dist: pymdown-extensions>=10.0.0; extra == 'docs'
45
+ Description-Content-Type: text/markdown
46
+
47
+ # PyGuara
48
+
49
+ **PyGuara** is a modern, modular, and high-performance 2D game engine for Python 3.12+. It features a robust Entity-Component-System (ECS) architecture, a native Dependency Injection (DI) container, and a decoupled event-driven design, making it suitable for scalable and maintainable game development.
50
+
51
+ > **Note:** This project is currently in **Pre-Alpha**. APIs are subject to change.
52
+
53
+ [![CI](https://github.com/Wedeueis/pyguara/actions/workflows/ci.yml/badge.svg)](https://github.com/Wedeueis/pyguara/actions/workflows/ci.yml)
54
+ [![codecov](https://codecov.io/gh/Wedeueis/pyguara/graph/badge.svg?token=YOUR_CODECOV_TOKEN)](https://codecov.io/gh/Wedeueis/pyguara)
55
+ [![PyPI version](https://badge.fury.io/py/pyguara.svg)](https://badge.fury.io/py/pyguara)
56
+ [![Python versions](https://img.shields.io/pypi/pyversions/pyguara.svg)](https://pypi.org/project/pyguara/)
57
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
58
+ [![License](https://img.shields.io/github/license/Wedeueis/pyguara)](https://github.com/Wedeueis/pyguara/blob/main/LICENSE)
59
+
60
+ ## 🚀 Key Features
61
+
62
+ * **⚡ Performance-First ECS**:
63
+ * Optimized `EntityManager` using **Inverted Indexes** for $O(1)$ component queries.
64
+ * Cache-friendly data layout designed to minimize Python overhead.
65
+ * **💉 Native Dependency Injection**:
66
+ * Built-in `DIContainer` supporting **Singleton**, **Transient**, and **Scoped** lifetimes.
67
+ * Automatic dependency resolution via Python type hints.
68
+ * **🎨 Decoupled Rendering Pipeline**:
69
+ * Backend-agnostic design (currently supporting `pygame-ce`).
70
+ * Support for **Z-sorting**, **Batching**, and efficient draw call management.
71
+ * **📢 Event-Driven Architecture**:
72
+ * Protocol-based event system for loose coupling between subsystems (Input, Physics, AI).
73
+ * **🤖 Integrated AI & Physics**:
74
+ * Built-in Finite State Machines (FSM), Steering Behaviors, and Blackboard patterns.
75
+ * Physics integration via `pymunk`.
76
+
77
+ ## 🛠️ Installation
78
+
79
+ PyGuara requires **Python 3.12** or higher.
80
+
81
+ ### Using `uv` (Recommended)
82
+
83
+ ```bash
84
+ # Clone the repository
85
+ git clone https://github.com/Wedeueis/pyguara
86
+ cd pyguara
87
+
88
+ # Sync dependencies
89
+ uv sync
90
+ ```
91
+
92
+ ### Using `pip`
93
+
94
+ ```bash
95
+ pip install -e .[dev]
96
+ ```
97
+
98
+ ## 🎮 Quick Start
99
+
100
+ To run the default example scene included with the engine:
101
+
102
+ ```bash
103
+ python main.py
104
+ ```
105
+
106
+ ### Creating a Basic Scene
107
+
108
+ Here is a minimal example of how to define a scene using PyGuara's ECS:
109
+
110
+ ```python
111
+ from pyguara.scene.base import Scene
112
+ from pyguara.common.components import Transform
113
+ from pyguara.graphics.components.sprite import Sprite
114
+ from pyguara.common.types import Vector2
115
+
116
+ class MyGameScene(Scene):
117
+ def on_enter(self) -> None:
118
+ print("Welcome to PyGuara!")
119
+
120
+ # Create an entity
121
+ player = self.entity_manager.create_entity("player")
122
+
123
+ # Add components
124
+ player.add_component(Transform(position=Vector2(100, 100)))
125
+ player.add_component(Sprite(texture_path="assets/player.png"))
126
+
127
+ def update(self, dt: float) -> None:
128
+ # Game logic goes here
129
+ pass
130
+ ```
131
+
132
+ ## 🏗️ Architecture Overview
133
+
134
+ The codebase is organized to enforce separation of concerns:
135
+
136
+ * `pyguara/ecs/`: The core Entity-Component-System implementation.
137
+ * `pyguara/di/`: The Dependency Injection container.
138
+ * `pyguara/events/`: The event dispatching system.
139
+ * `pyguara/graphics/`: Rendering protocols, pipelines, and backends.
140
+ * `pyguara/physics/`: Physics engine integration (Pymunk).
141
+ * `pyguara/application/`: Application lifecycle and bootstrapping.
142
+
143
+ ## 🤝 Contributing
144
+
145
+ Contributions are welcome! Please ensure you adhere to the project's code quality standards.
146
+
147
+ 1. **Install development dependencies**:
148
+ ```bash
149
+ uv sync --extra dev
150
+ ```
151
+ 2. **Run tests**:
152
+ ```bash
153
+ pytest
154
+ ```
155
+ 3. **Run linters**:
156
+ ```bash
157
+ ruff check .
158
+ mypy pyguara
159
+ ```
160
+
161
+ ## 📄 License
162
+
163
+ This project is licensed under the MIT License - see the LICENSE file for details.
164
+
165
+ ## ✍️ Author
166
+
167
+ Developed by **Wedeueis Braz**.
@@ -0,0 +1,121 @@
1
+ # PyGuara
2
+
3
+ **PyGuara** is a modern, modular, and high-performance 2D game engine for Python 3.12+. It features a robust Entity-Component-System (ECS) architecture, a native Dependency Injection (DI) container, and a decoupled event-driven design, making it suitable for scalable and maintainable game development.
4
+
5
+ > **Note:** This project is currently in **Pre-Alpha**. APIs are subject to change.
6
+
7
+ [![CI](https://github.com/Wedeueis/pyguara/actions/workflows/ci.yml/badge.svg)](https://github.com/Wedeueis/pyguara/actions/workflows/ci.yml)
8
+ [![codecov](https://codecov.io/gh/Wedeueis/pyguara/graph/badge.svg?token=YOUR_CODECOV_TOKEN)](https://codecov.io/gh/Wedeueis/pyguara)
9
+ [![PyPI version](https://badge.fury.io/py/pyguara.svg)](https://badge.fury.io/py/pyguara)
10
+ [![Python versions](https://img.shields.io/pypi/pyversions/pyguara.svg)](https://pypi.org/project/pyguara/)
11
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
12
+ [![License](https://img.shields.io/github/license/Wedeueis/pyguara)](https://github.com/Wedeueis/pyguara/blob/main/LICENSE)
13
+
14
+ ## 🚀 Key Features
15
+
16
+ * **⚡ Performance-First ECS**:
17
+ * Optimized `EntityManager` using **Inverted Indexes** for $O(1)$ component queries.
18
+ * Cache-friendly data layout designed to minimize Python overhead.
19
+ * **💉 Native Dependency Injection**:
20
+ * Built-in `DIContainer` supporting **Singleton**, **Transient**, and **Scoped** lifetimes.
21
+ * Automatic dependency resolution via Python type hints.
22
+ * **🎨 Decoupled Rendering Pipeline**:
23
+ * Backend-agnostic design (currently supporting `pygame-ce`).
24
+ * Support for **Z-sorting**, **Batching**, and efficient draw call management.
25
+ * **📢 Event-Driven Architecture**:
26
+ * Protocol-based event system for loose coupling between subsystems (Input, Physics, AI).
27
+ * **🤖 Integrated AI & Physics**:
28
+ * Built-in Finite State Machines (FSM), Steering Behaviors, and Blackboard patterns.
29
+ * Physics integration via `pymunk`.
30
+
31
+ ## 🛠️ Installation
32
+
33
+ PyGuara requires **Python 3.12** or higher.
34
+
35
+ ### Using `uv` (Recommended)
36
+
37
+ ```bash
38
+ # Clone the repository
39
+ git clone https://github.com/Wedeueis/pyguara
40
+ cd pyguara
41
+
42
+ # Sync dependencies
43
+ uv sync
44
+ ```
45
+
46
+ ### Using `pip`
47
+
48
+ ```bash
49
+ pip install -e .[dev]
50
+ ```
51
+
52
+ ## 🎮 Quick Start
53
+
54
+ To run the default example scene included with the engine:
55
+
56
+ ```bash
57
+ python main.py
58
+ ```
59
+
60
+ ### Creating a Basic Scene
61
+
62
+ Here is a minimal example of how to define a scene using PyGuara's ECS:
63
+
64
+ ```python
65
+ from pyguara.scene.base import Scene
66
+ from pyguara.common.components import Transform
67
+ from pyguara.graphics.components.sprite import Sprite
68
+ from pyguara.common.types import Vector2
69
+
70
+ class MyGameScene(Scene):
71
+ def on_enter(self) -> None:
72
+ print("Welcome to PyGuara!")
73
+
74
+ # Create an entity
75
+ player = self.entity_manager.create_entity("player")
76
+
77
+ # Add components
78
+ player.add_component(Transform(position=Vector2(100, 100)))
79
+ player.add_component(Sprite(texture_path="assets/player.png"))
80
+
81
+ def update(self, dt: float) -> None:
82
+ # Game logic goes here
83
+ pass
84
+ ```
85
+
86
+ ## 🏗️ Architecture Overview
87
+
88
+ The codebase is organized to enforce separation of concerns:
89
+
90
+ * `pyguara/ecs/`: The core Entity-Component-System implementation.
91
+ * `pyguara/di/`: The Dependency Injection container.
92
+ * `pyguara/events/`: The event dispatching system.
93
+ * `pyguara/graphics/`: Rendering protocols, pipelines, and backends.
94
+ * `pyguara/physics/`: Physics engine integration (Pymunk).
95
+ * `pyguara/application/`: Application lifecycle and bootstrapping.
96
+
97
+ ## 🤝 Contributing
98
+
99
+ Contributions are welcome! Please ensure you adhere to the project's code quality standards.
100
+
101
+ 1. **Install development dependencies**:
102
+ ```bash
103
+ uv sync --extra dev
104
+ ```
105
+ 2. **Run tests**:
106
+ ```bash
107
+ pytest
108
+ ```
109
+ 3. **Run linters**:
110
+ ```bash
111
+ ruff check .
112
+ mypy pyguara
113
+ ```
114
+
115
+ ## 📄 License
116
+
117
+ This project is licensed under the MIT License - see the LICENSE file for details.
118
+
119
+ ## ✍️ Author
120
+
121
+ Developed by **Wedeueis Braz**.
File without changes
@@ -0,0 +1,29 @@
1
+ """Systems for updating AI logic."""
2
+
3
+ from pyguara.ai.components import AIComponent
4
+ from pyguara.ecs.manager import EntityManager
5
+
6
+
7
+ class AISystem:
8
+ """Updates AI decision making (FSMs/Trees)."""
9
+
10
+ def __init__(self, entity_manager: EntityManager):
11
+ """Initialize the AI system for all Entities."""
12
+ self.manager = entity_manager
13
+
14
+ def update(self, dt: float) -> None:
15
+ """Update all AI components."""
16
+ # Query entities with AI
17
+ for entity in self.manager.get_entities_with(AIComponent):
18
+ ai: AIComponent = entity.ai_component # Using __getattr__ magic
19
+
20
+ if not ai.enabled:
21
+ continue
22
+
23
+ # Update FSM if present
24
+ if ai.fsm:
25
+ ai.fsm.update(dt)
26
+
27
+ # (Future) Update Behavior Tree if present
28
+ # if ai.behavior_tree:
29
+ # ai.behavior_tree.tick(dt)
@@ -0,0 +1,32 @@
1
+ """Blackboard system for sharing data between AI nodes and states."""
2
+
3
+ from typing import Any, Dict
4
+
5
+
6
+ class Blackboard:
7
+ """
8
+ A shared memory container for AI decision making.
9
+
10
+ Allows different parts of an AI (e.g., nodes in a Behavior Tree or states
11
+ in an FSM) to read and write shared data without tight coupling.
12
+ """
13
+
14
+ def __init__(self) -> None:
15
+ """Initialize the blackboard."""
16
+ self._data: Dict[str, Any] = {}
17
+
18
+ def set(self, key: str, value: Any) -> None:
19
+ """Set a value in the blackboard."""
20
+ self._data[key] = value
21
+
22
+ def get(self, key: str, default: Any = None) -> Any:
23
+ """Retrieve a value from the blackboard."""
24
+ return self._data.get(key, default)
25
+
26
+ def has(self, key: str) -> bool:
27
+ """Check if a key exists."""
28
+ return key in self._data
29
+
30
+ def clear(self) -> None:
31
+ """Clear all data."""
32
+ self._data.clear()
@@ -0,0 +1,76 @@
1
+ """ECS components for AI."""
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import Optional, List
5
+
6
+ from pyguara.common.types import Vector2
7
+ from pyguara.ai.blackboard import Blackboard
8
+ from pyguara.ai.fsm import StateMachine
9
+ from pyguara.ecs.component import BaseComponent
10
+
11
+
12
+ @dataclass
13
+ class AIComponent(BaseComponent):
14
+ """
15
+ Component that holds the AI brain (FSM or Behavior Tree).
16
+
17
+ Attributes:
18
+ blackboard: Shared memory for this agent.
19
+ fsm: Optional Finite State Machine.
20
+ enabled: Whether AI logic should run.
21
+ """
22
+
23
+ blackboard: Blackboard = field(default_factory=Blackboard)
24
+ fsm: Optional[StateMachine] = None
25
+ enabled: bool = True
26
+
27
+ def __post_init__(self) -> None:
28
+ """Call superclass init after initialization."""
29
+ super().__init__()
30
+
31
+
32
+ @dataclass
33
+ class SteeringAgent(BaseComponent):
34
+ """
35
+ Component that defines movement capabilities.
36
+
37
+ Attributes:
38
+ max_speed: Maximum movement speed.
39
+ max_force: Maximum steering force (turn speed/acceleration).
40
+ mass: Used to calculate acceleration (Force / Mass).
41
+ """
42
+
43
+ max_speed: float = 200.0
44
+ max_force: float = 500.0
45
+ mass: float = 1.0
46
+
47
+ def __post_init__(self) -> None:
48
+ """Call superclass init after initialization."""
49
+ super().__init__()
50
+
51
+
52
+ @dataclass
53
+ class Navigator(BaseComponent):
54
+ """
55
+ Component that handles pathfollowing.
56
+
57
+ Attributes:
58
+ path: Current list of waypoints.
59
+ current_index: Which waypoint we are moving toward.
60
+ reach_threshold: How close to get before switching to next waypoint.
61
+ """
62
+
63
+ path: List[Vector2] = field(default_factory=list)
64
+ current_index: int = 0
65
+ reach_threshold: float = 5.0
66
+
67
+ def set_path(self, path: List[Vector2]) -> None:
68
+ """Set the path defined by a list of vectors."""
69
+ self.path = path
70
+ self.current_index = 0
71
+
72
+ def get_current_target(self) -> Optional[Vector2]:
73
+ """Return the current imediate destination."""
74
+ if 0 <= self.current_index < len(self.path):
75
+ return self.path[self.current_index]
76
+ return None
@@ -0,0 +1,82 @@
1
+ """Finite State Machine (FSM) implementation."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from typing import Dict, Optional
5
+
6
+ from pyguara.ai.blackboard import Blackboard
7
+ from pyguara.ecs.entity import Entity
8
+
9
+
10
+ class State(ABC):
11
+ """Abstract base class for FSM states."""
12
+
13
+ def __init__(self, entity: Entity, blackboard: Blackboard):
14
+ """Initialize the state of an entity and a Blackboard."""
15
+ self.entity = entity
16
+ self.blackboard = blackboard
17
+
18
+ @abstractmethod
19
+ def on_enter(self) -> None:
20
+ """Call when entering this state."""
21
+ pass
22
+
23
+ @abstractmethod
24
+ def on_exit(self) -> None:
25
+ """Call when exiting this state."""
26
+ pass
27
+
28
+ @abstractmethod
29
+ def update(self, dt: float) -> Optional[str]:
30
+ """
31
+ Update the state logic.
32
+
33
+ Returns:
34
+ Name of the next state to transition to, or None to stay.
35
+ """
36
+ pass
37
+
38
+
39
+ class StateMachine:
40
+ """Manages states and transitions for an entity."""
41
+
42
+ def __init__(self, entity: Entity, blackboard: Blackboard):
43
+ """Initialize the State Machine of an entity and a Blackboard."""
44
+ self.entity = entity
45
+ self.blackboard = blackboard
46
+ self._states: Dict[str, State] = {}
47
+ self._current_state: Optional[State] = None
48
+ self._current_state_name: str = ""
49
+
50
+ def add_state(self, name: str, state: State) -> None:
51
+ """Register a state instance."""
52
+ self._states[name] = state
53
+
54
+ def set_initial_state(self, name: str) -> None:
55
+ """Set the starting state."""
56
+ if name in self._states:
57
+ self._current_state = self._states[name]
58
+ self._current_state_name = name
59
+ self._current_state.on_enter()
60
+
61
+ def update(self, dt: float) -> None:
62
+ """Update current state and handle transitions."""
63
+ if not self._current_state:
64
+ return
65
+
66
+ # Update returns potential transition
67
+ next_state_name = self._current_state.update(dt)
68
+
69
+ if next_state_name and next_state_name != self._current_state_name:
70
+ self._transition_to(next_state_name)
71
+
72
+ def _transition_to(self, name: str) -> None:
73
+ """Execute transition logic."""
74
+ if name not in self._states:
75
+ return
76
+
77
+ if self._current_state:
78
+ self._current_state.on_exit()
79
+
80
+ self._current_state = self._states[name]
81
+ self._current_state_name = name
82
+ self._current_state.on_enter()