jeski 0.5.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.
jeski-0.5.0/PKG-INFO ADDED
@@ -0,0 +1,262 @@
1
+ Metadata-Version: 2.4
2
+ Name: jeski
3
+ Version: 0.5.0
4
+ Summary: Jeski Project, UI-Development made simple.
5
+ Author: Siddharth
6
+ License: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Requires-Python: >=3.6
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: pygame
12
+ Requires-Dist: pyautogui
13
+ Requires-Dist: keyboard
14
+ Requires-Dist: numpy
15
+ Requires-Dist: asteval
16
+ Requires-Dist: mouse
17
+ Dynamic: author
18
+ Dynamic: classifier
19
+ Dynamic: description
20
+ Dynamic: description-content-type
21
+ Dynamic: license
22
+ Dynamic: requires-dist
23
+ Dynamic: requires-python
24
+ Dynamic: summary
25
+
26
+ # Jeski Engine
27
+
28
+ **Jeski** is a Scratch-inspired 2D game engine and rapid prototyping wrapper built on top of **Pygame**. Created by **Siddharth Barnwal (Enirb)**, Jeski turns verbose Pygame boilerplate into intuitive, object-oriented building blocks—bringing sprites (`Entity`), costumes, stamps, clones, pixel-perfect mask collisions, speech/input bubbles (`Box`), geometric primitives, 1D/2D layout meshes, and multi-threaded background scripts (`Script`) to Python.
29
+
30
+ | Metadata | Details |
31
+ | :--- | :--- |
32
+ | **Package Name** | `Jeski` |
33
+ | **Author** | Siddharth Barnwal (`beast.barnwal` / `Enirb`) |
34
+ | **Engine Backend** | Pygame (`pygame`, `pygame.gfxdraw`) |
35
+ | **Python Compatibility** | Python 3.9+ |
36
+
37
+ ## Key Features
38
+
39
+ - **Zero-Boilerplate Engine Loop**: Initialize the display window, audio mixer, clock, and asset folders in a single `INITIALIZE()` call, and refresh frames with `UPDATE()` and `SMOOTH()`.
40
+ - **Scratch-Style `Entity` System**: Create sprites with support for `move()`, `turn()`, `pointTowards()`, `goto()`, `changeXby()`, `changeYby()`, `setSize()`, `changeSize()`, `stamp()`, and `createClone()`.
41
+ - **Costume & Animation Management**: Attach multiple `Costume` objects to any `Entity`, cycle through frames with `nextCostume()` / `previousCostume()`, or run background sprite-sheet loops via `startAnimation()` and `blink()`.
42
+ - **Pixel-Perfect Mask Collisions**: Built-in `touching()` and automatic rollback collision resolution (`check_collisions()`) powered by `pygame.mask`, plus live collision mask debugging (`M` key or `T` hotkey).
43
+ - **Interactive Speech & Input Bubbles**: Prompt players with Scratch-like `askAndWait()`, `say()`, and timed `sayFor()` dialog boxes directly on the canvas.
44
+ - **Rich Vector Shapes & Grouping**: Draw and manipulate `Rectangle`, `CurvedRectangle`, `Circle`, `Ellipse`, `Triangle`, `Polygon`, `Line`, `ZigZag`, and composite `Group` hierarchies (plus non-registered `*F` costume variants like `RectangleF` and `CircleF`).
45
+ - **Reactive UI & Grid Meshes**: Render live global variables on screen with `Variable` and `Text`, trigger native OS dialogs via `MESSAGE`, and align objects effortlessly using `GridMesh1D` and `GridMesh2D`.
46
+ - **Multi-Channel Audio (`SOUNDPLAYER`)**: Play, loop, fade, mute, and block on sound effects with automatic channel cleanup.
47
+
48
+ ## Installation
49
+
50
+ Install `Jeski` from PyPI using `pip`:
51
+
52
+ ```bash
53
+ pip install Jeski
54
+ ```
55
+
56
+ To ensure all runtime dependencies are installed alongside `Jeski`:
57
+
58
+ ```bash
59
+ pip install pygame numpy pyautogui keyboard mouse asteval safeImport
60
+ ```
61
+
62
+ > **Platform Note**: Because `Jeski` uses the `keyboard` and `mouse` libraries for global hotkey polling alongside `pyautogui`, Linux users may need root permissions or X11 display access, and Windows users can use the built-in `RunAsAdmin()` helper when global hooks require elevation.
63
+
64
+ ## Quick Start
65
+
66
+ Here is a complete, runnable example demonstrating a player sprite, geometric obstacles, live variable tracking, and keyboard controls:
67
+
68
+ ```python
69
+ from Jeski import *
70
+
71
+ # Optional: Set your app name before initializing
72
+ __APPNAME__ = "SpaceDash"
73
+ CONFIG.WINDOWTITLE = "SpaceDash - Jeski Demo"
74
+ CONFIG.backgroundColor = (240, 244, 248)
75
+
76
+ # 1. Start the Jeski Engine
77
+ INITIALIZE(stayInActiveDirectory=True)
78
+
79
+ # 2. Create a score variable and display it on screen
80
+ score = 0
81
+ score_label = Variable("score", x=WINDOW.w // 2, y=30, size=36, color=colors.BLUE)
82
+
83
+ # 3. Create the player Entity (uses a colored rectangle if no image path is provided)
84
+ player = Entity(
85
+ name="Player1",
86
+ x=CONFIG.centerX,
87
+ y=CONFIG.centerY,
88
+ sizeX=50,
89
+ sizeY=50,
90
+ color=colors.RED,
91
+ collider=True
92
+ )
93
+
94
+ # 4. Add a decorative Circle shape
95
+ goal = Circle(center=(200, 200), radius=25, color=colors.GREEN)
96
+
97
+ # 5. Main game loop
98
+ while CORE.RUNNING:
99
+ UPDATE()
100
+
101
+ # Poll movement keys using Pygame's key state in CORE.KEYS
102
+ if CORE.KEYS[pygame.K_w] or CORE.KEYS[pygame.K_UP]:
103
+ player.move(6)
104
+ if CORE.KEYS[pygame.K_s] or CORE.KEYS[pygame.K_DOWN]:
105
+ player.move(-6)
106
+ if CORE.KEYS[pygame.K_a] or CORE.KEYS[pygame.K_LEFT]:
107
+ player.turn(-4)
108
+ if CORE.KEYS[pygame.K_d] or CORE.KEYS[pygame.K_RIGHT]:
109
+ player.turn(4)
110
+
111
+ # Check pixel-perfect collision with the goal circle
112
+ if player.touching(goal):
113
+ score += 1
114
+ goal.center = (random.randint(60, WINDOW.w - 60), random.randint(60, WINDOW.h - 60))
115
+ goal.refresh()
116
+
117
+ SMOOTH()
118
+ ```
119
+
120
+ ## Core Architecture & API Reference
121
+
122
+ ### 1. Engine Lifecycle (`__init__.py`)
123
+
124
+ | Function | Description |
125
+ | :--- | :--- |
126
+ | `INITIALIZE(**kwargs)` | Initializes Pygame, mixer, fonts, `CORE.SCREEN`, `CORE.CLOCK`, and asset directories. Pass `stayInActiveDirectory=True` to keep your current working directory. Alias: `INITIALISE()`. |
127
+ | `UPDATE()` | Clears the screen with `CONFIG.backgroundColor`, processes window/input events (`UPDATEVARS()`), updates `SOUNDPLAYER`, renders all stamps and entities (`DRAWSCREEN()`), and ticks `CORE.CLOCK` at `CONFIG.FPS`. |
128
+ | `SMOOTH(smooth=None, noPauseWait=False)` | Sleeps for `CONFIG.smoothWait` (default `1/60` sec) and yields execution while honoring `CONFIG.PAUSED`. |
129
+ | `SHUTDOWN()` / `QUIT()` | Stops the engine loop (`CORE.RUNNING = False`) or posts a `pygame.QUIT` event. |
130
+ | `startConfigSync(data_dict)` | Starts a background `Script` that continuously synchronizes a dictionary of variable names with the caller's global scope. |
131
+
132
+ ### 2. Sprites & Entities (`entities/entity.py`)
133
+
134
+ `Entity` is the core sprite class in Jeski. Every `Entity` is automatically added to `CORE.ENTITIES` (unless `type='Stamp'`) and rendered each frame.
135
+
136
+ ```python
137
+ hero = Entity(
138
+ image="hero.png", # Optional path to image file (or pass rawimage=Surface)
139
+ x=300, y=300, # Defaults to screen center (CONFIG.centerX, CONFIG.centerY)
140
+ sizeX=64, sizeY=64, # Dimensions when using procedural rectangle fallback
141
+ color=colors.BLUE, # Fill color if no image is supplied
142
+ centered=True, # Center sprite on (x, y)
143
+ collider=True # Enable automatic collision rollback in check_collisions()
144
+ )
145
+ ```
146
+
147
+ #### Movement, Rotation & Scaling
148
+
149
+ - `hero.move(steps, raw=False)`: Moves forward along `hero.direction` (clamped to window bounds unless `raw=True`).
150
+ - `hero.turn(deg)`: Rotates the entity by `deg` degrees and checks collisions.
151
+ - `hero.pointTowards(other_entity)`: Rotates to face another entity's `(x, y)` coordinates.
152
+ - `hero.goto(x, y)` / `hero._goto(other_entity)`: Teleports to coordinates or another entity's position.
153
+ - `hero.changeXby(steps)` (`chx`) / `hero.changeYby(steps)` (`chy`): Moves along a single axis with collision rollback.
154
+ - `hero.setSize(percent)` / `hero.changeSize(delta_percent)` (`chs`) / `hero.setSizeToVal((w, h))`: Scales `original_image` smoothly using `pygame.transform.smoothscale`.
155
+ - `hero.rotationStyle`: Set to `2` for full 360° rotation (default), `1` for left-right horizontal flip, or `0` for fixed orientation.
156
+
157
+ #### Costumes, Visual Effects & Layering
158
+
159
+ - `hero.addCostume(Costume(name, obj))` / `hero.removeCostume(idx)`: Manages the entity's costume list.
160
+ - `hero.nextCostume()` / `hero.previousCostume()` / `hero.changeCostume(idx)`: Switches active appearance.
161
+ - `hero.transparency`: Value from `0` (opaque) to `255` (invisible).
162
+ - `hero.brightness`: Positive values (`0` to `255`) brighten via `BLEND_RGBA_ADD`; negative values darken via `BLEND_RGBA_SUB`.
163
+ - `hero.hide()` / `hero.show()`: Toggles visibility.
164
+ - `hero.bringToFront()` / `hero.sendToBack()`: Reorders draw priority inside `CORE.ENTITIES`.
165
+
166
+ #### Clones, Stamps & Collisions
167
+
168
+ - `hero.stamp(var=None, ret=False)`: Leaves a static visual copy on `CORE.STAMPS` (press `Q` at runtime to clear stamps).
169
+ - `hero.createClone(ret=False, config=None)`: Spawns an independent `Clone` entity inheriting position, direction, costumes, and variables.
170
+ - `hero.touching(other_or_mouse)`: Returns `True` on pixel-perfect mask overlap with another entity or `'__mouse__'`.
171
+ - `hero.isClicked()`: Returns `True` if the mouse button is down and touching the entity's mask.
172
+ - `hero.delete()`: Removes the entity from `CORE.ENTITIES` and any registered reference lists.
173
+
174
+ #### Dialogs (`Box`)
175
+
176
+ - `answer = hero.askAndWait("What is your name?")`: Opens an interactive text input box next to the entity and returns the submitted string.
177
+ - `hero.sayFor("Hello!", timeout=2)`: Displays a speech bubble for `timeout` seconds.
178
+ - `hero.say("Thinking...")`: Displays a persistent speech bubble bound to `hero.var['msg']` (set `hero.var['msg'] = ''` to dismiss).
179
+
180
+ ### 3. Geometric Shapes & Groups (`entities/shapes.py`)
181
+
182
+ All shapes support `BASICDRAW` caching, masks, and `Entity` helper methods via `verifyAttributes()`. Each class also provides a `*F` subclass (e.g., `RectangleF`, `CircleF`, `PolygonF`) with `trueEntity=False` for building `Costume` objects or composite `Group` hierarchies without adding sub-parts directly to `CORE.ENTITIES`.
183
+
184
+ | Shape Class | Constructor Signature |
185
+ | :--- | :--- |
186
+ | `Image` / `ImageF` | `Image(path, x=None, y=None, raw=False, trueEntity=True)` |
187
+ | `Rectangle` / `RectangleF` | `Rectangle(x, y, w, h, color=colors.BLACK, trueEntity=True)` |
188
+ | `CurvedRectangle` / `CurvedRectangleF` | `CurvedRectangle(x, y, w, h, curve, color=colors.BLACK, trueEntity=True)` |
189
+ | `Circle` / `CircleF` | `Circle(center, radius, width=0, color=colors.BLACK, trueEntity=True)` |
190
+ | `Ellipse` / `EllipseF` | `Ellipse(center, radiusMinor, radiusMajor, width=0, color=colors.BLACK, trueEntity=True)` |
191
+ | `Triangle` / `TriangleF` | `Triangle(cord1, cord2, cord3, color=colors.BLACK, trueEntity=True)` |
192
+ | `Polygon` / `PolygonF` | `Polygon(cords, color=colors.BLACK, trueEntity=True)` |
193
+ | `Line` / `LineF` | `Line(cord1, cord2, color=colors.BLACK, width=5, trueEntity=True)` |
194
+ | `ZigZag` / `ZigZagF` | `ZigZag(cords, color=colors.BLACK, width=5, trueEntity=True)` |
195
+ | `Group` / `GroupF` | `Group(attributes=None, entities=None, tight=False, trueEntity=True)` |
196
+
197
+ ### 4. UI, Text, Grids & Meshes (`entities/ui.py`, `mesh.py`)
198
+
199
+ - **`Text(text, x, y, font=None, size=40, align='center', color=colors.BLACK)`**: Renders cached Pygame font surfaces. Update properties dynamically with `text_obj.change('text', 'New Value')`.
200
+ - **`Variable(variable_name, x, y, size=40, color=colors.BLACK)`**: Subclasses `Text` and spawns a background `Script` that watches a global variable by name (e.g., `Variable('score', 100, 50)`) and re-renders automatically whenever its value changes.
201
+ - **`MESSAGE`**: Static wrapper around `tkinter.messagebox` providing `info()`, `warning()` / `warn()`, `error()`, `yesNo()`, `okCancel()`, `retryCancel()`, and `yesNoCancel()`.
202
+ - **`GridMesh2D(x=10, y=10, center=True, margin=0)` & `GridMesh1D(type='x', c=10, center=True, margin=0)`**: Automatically computes cell widths/heights across `WINDOW` and positions objects added via `.add(obj, coords=(col, row))`.
203
+
204
+ ### 5. Animations, Audio & Concurrency (`animations.py`, `sounds.py`, `scripts.py`)
205
+
206
+ - **`Script(function, starter='CORE.RUNNING', once=True, loop=None, waitUntilFinished=False)`**: Runs `function` in a daemon thread when the `starter` expression evaluates to truthy.
207
+ - **`startAnimation(obj, costs=[0, 1, 2], fps=10)`**: Cycles `obj` through the specified costume indices at `fps` frames per second in a background `Script`.
208
+ - **`blink(obj, fast=False)`**: Pulses an entity's brightness up to `100` and back to its original value.
209
+ - **`SOUNDPLAYER`**:
210
+ - `SOUNDPLAYER.play(sound, raw=False, config={'volume': 50, 'loops': 0, 'fade_ms': 0}, untilFinished=False)`
211
+ - `SOUNDPLAYER.setMasterVolume(80)`
212
+ - `SOUNDPLAYER.fadeAll(500)` / `SOUNDPLAYER.stopAll()`
213
+ - `SOUNDPLAYER.mute()` / `SOUNDPLAYER.unmute()`
214
+
215
+ ### 6. Configuration & Built-in Shortcuts (`config.py`)
216
+
217
+ Customize `WINDOW` and `CONFIG` before calling `INITIALIZE()`:
218
+
219
+ ```python
220
+ WINDOW.WIDTH = 1280
221
+ WINDOW.HEIGHT = 720
222
+ CONFIG.WINDOWTITLE = "My Jeski Game"
223
+ CONFIG.FPS = 60
224
+ CONFIG.backgroundColor = colors.WHITE
225
+ CONFIG.debug = True
226
+ ```
227
+
228
+ **Built-in Runtime Hotkeys:**
229
+ - **`M` key** (or **`T`** when `CONFIG.debug = True`): Toggles red/translucent collision mask overlays (`CONFIG.showMask`) across all entities.
230
+ - **`Q` key**: Clears all `Stamp` entities from `CORE.ENTITIES`.
231
+
232
+ ## Project Structure
233
+
234
+ ```text
235
+ Jeski/
236
+ ├── __init__.py # Engine lifecycle (INITIALIZE, UPDATE, DRAWSCREEN, UPDATEVARS)
237
+ ├── __main__.py # Built-in 2-player demo script
238
+ ├── animations.py # Costume frame animation and brightness blink effects
239
+ ├── commands.py # Shell execution (RunCommand), PyInstaller paths, UAC elevation
240
+ ├── config.py # CORE state, WINDOW dimensions, CONFIG settings, colors, GUI aliases
241
+ ├── credits.py # Author metadata
242
+ ├── deps.py # Dependency imports and safeImport verification fallback
243
+ ├── grid.py # Grid module stub (implemented in utils.py / __init__.py)
244
+ ├── imageTools.py # Surface brightness and alpha manipulation helpers
245
+ ├── mesh.py # GridMesh1D and GridMesh2D layout managers
246
+ ├── scripts.py # Threaded Script runner and roughScript helper
247
+ ├── sounds.py # SOUNDPLAYER multi-channel mixer controller
248
+ ├── tests.py # Interactive live-variable entity test harness (TESTS_)
249
+ ├── utils.py # Surface compositing, attribute verification, eval helpers, timing
250
+ ├── assets/ # Built-in WAV sound effects (alert.wav, coin.wav, Lose.wav)
251
+ └── entities/
252
+ ├── __init__.py # Exports Entity, shapes, and UI classes
253
+ ├── base.py # BASICDRAW surface caching, rotation, brightness, mask overlay
254
+ ├── entity.py # Core Entity, Costume, and Box (say/ask) classes
255
+ ├── shapes.py # Vector shapes, Group compositor, and *F non-entity subclasses
256
+ ├── _shapes.py # Legacy shapes module
257
+ └── ui.py # MESSAGE dialogs, Text renderer, and reactive Variable widget
258
+ ```
259
+
260
+ ## Author & Credits
261
+
262
+ Created and maintained by **Siddharth Barnwal** (`Enirb` / `beast.barnwal`).
jeski-0.5.0/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # Jeski Engine
2
+
3
+ **Jeski** is a Scratch-inspired 2D game engine and rapid prototyping wrapper built on top of **Pygame**. Created by **Siddharth Barnwal (Enirb)**, Jeski turns verbose Pygame boilerplate into intuitive, object-oriented building blocks—bringing sprites (`Entity`), costumes, stamps, clones, pixel-perfect mask collisions, speech/input bubbles (`Box`), geometric primitives, 1D/2D layout meshes, and multi-threaded background scripts (`Script`) to Python.
4
+
5
+ | Metadata | Details |
6
+ | :--- | :--- |
7
+ | **Package Name** | `Jeski` |
8
+ | **Author** | Siddharth Barnwal (`beast.barnwal` / `Enirb`) |
9
+ | **Engine Backend** | Pygame (`pygame`, `pygame.gfxdraw`) |
10
+ | **Python Compatibility** | Python 3.9+ |
11
+
12
+ ## Key Features
13
+
14
+ - **Zero-Boilerplate Engine Loop**: Initialize the display window, audio mixer, clock, and asset folders in a single `INITIALIZE()` call, and refresh frames with `UPDATE()` and `SMOOTH()`.
15
+ - **Scratch-Style `Entity` System**: Create sprites with support for `move()`, `turn()`, `pointTowards()`, `goto()`, `changeXby()`, `changeYby()`, `setSize()`, `changeSize()`, `stamp()`, and `createClone()`.
16
+ - **Costume & Animation Management**: Attach multiple `Costume` objects to any `Entity`, cycle through frames with `nextCostume()` / `previousCostume()`, or run background sprite-sheet loops via `startAnimation()` and `blink()`.
17
+ - **Pixel-Perfect Mask Collisions**: Built-in `touching()` and automatic rollback collision resolution (`check_collisions()`) powered by `pygame.mask`, plus live collision mask debugging (`M` key or `T` hotkey).
18
+ - **Interactive Speech & Input Bubbles**: Prompt players with Scratch-like `askAndWait()`, `say()`, and timed `sayFor()` dialog boxes directly on the canvas.
19
+ - **Rich Vector Shapes & Grouping**: Draw and manipulate `Rectangle`, `CurvedRectangle`, `Circle`, `Ellipse`, `Triangle`, `Polygon`, `Line`, `ZigZag`, and composite `Group` hierarchies (plus non-registered `*F` costume variants like `RectangleF` and `CircleF`).
20
+ - **Reactive UI & Grid Meshes**: Render live global variables on screen with `Variable` and `Text`, trigger native OS dialogs via `MESSAGE`, and align objects effortlessly using `GridMesh1D` and `GridMesh2D`.
21
+ - **Multi-Channel Audio (`SOUNDPLAYER`)**: Play, loop, fade, mute, and block on sound effects with automatic channel cleanup.
22
+
23
+ ## Installation
24
+
25
+ Install `Jeski` from PyPI using `pip`:
26
+
27
+ ```bash
28
+ pip install Jeski
29
+ ```
30
+
31
+ To ensure all runtime dependencies are installed alongside `Jeski`:
32
+
33
+ ```bash
34
+ pip install pygame numpy pyautogui keyboard mouse asteval safeImport
35
+ ```
36
+
37
+ > **Platform Note**: Because `Jeski` uses the `keyboard` and `mouse` libraries for global hotkey polling alongside `pyautogui`, Linux users may need root permissions or X11 display access, and Windows users can use the built-in `RunAsAdmin()` helper when global hooks require elevation.
38
+
39
+ ## Quick Start
40
+
41
+ Here is a complete, runnable example demonstrating a player sprite, geometric obstacles, live variable tracking, and keyboard controls:
42
+
43
+ ```python
44
+ from Jeski import *
45
+
46
+ # Optional: Set your app name before initializing
47
+ __APPNAME__ = "SpaceDash"
48
+ CONFIG.WINDOWTITLE = "SpaceDash - Jeski Demo"
49
+ CONFIG.backgroundColor = (240, 244, 248)
50
+
51
+ # 1. Start the Jeski Engine
52
+ INITIALIZE(stayInActiveDirectory=True)
53
+
54
+ # 2. Create a score variable and display it on screen
55
+ score = 0
56
+ score_label = Variable("score", x=WINDOW.w // 2, y=30, size=36, color=colors.BLUE)
57
+
58
+ # 3. Create the player Entity (uses a colored rectangle if no image path is provided)
59
+ player = Entity(
60
+ name="Player1",
61
+ x=CONFIG.centerX,
62
+ y=CONFIG.centerY,
63
+ sizeX=50,
64
+ sizeY=50,
65
+ color=colors.RED,
66
+ collider=True
67
+ )
68
+
69
+ # 4. Add a decorative Circle shape
70
+ goal = Circle(center=(200, 200), radius=25, color=colors.GREEN)
71
+
72
+ # 5. Main game loop
73
+ while CORE.RUNNING:
74
+ UPDATE()
75
+
76
+ # Poll movement keys using Pygame's key state in CORE.KEYS
77
+ if CORE.KEYS[pygame.K_w] or CORE.KEYS[pygame.K_UP]:
78
+ player.move(6)
79
+ if CORE.KEYS[pygame.K_s] or CORE.KEYS[pygame.K_DOWN]:
80
+ player.move(-6)
81
+ if CORE.KEYS[pygame.K_a] or CORE.KEYS[pygame.K_LEFT]:
82
+ player.turn(-4)
83
+ if CORE.KEYS[pygame.K_d] or CORE.KEYS[pygame.K_RIGHT]:
84
+ player.turn(4)
85
+
86
+ # Check pixel-perfect collision with the goal circle
87
+ if player.touching(goal):
88
+ score += 1
89
+ goal.center = (random.randint(60, WINDOW.w - 60), random.randint(60, WINDOW.h - 60))
90
+ goal.refresh()
91
+
92
+ SMOOTH()
93
+ ```
94
+
95
+ ## Core Architecture & API Reference
96
+
97
+ ### 1. Engine Lifecycle (`__init__.py`)
98
+
99
+ | Function | Description |
100
+ | :--- | :--- |
101
+ | `INITIALIZE(**kwargs)` | Initializes Pygame, mixer, fonts, `CORE.SCREEN`, `CORE.CLOCK`, and asset directories. Pass `stayInActiveDirectory=True` to keep your current working directory. Alias: `INITIALISE()`. |
102
+ | `UPDATE()` | Clears the screen with `CONFIG.backgroundColor`, processes window/input events (`UPDATEVARS()`), updates `SOUNDPLAYER`, renders all stamps and entities (`DRAWSCREEN()`), and ticks `CORE.CLOCK` at `CONFIG.FPS`. |
103
+ | `SMOOTH(smooth=None, noPauseWait=False)` | Sleeps for `CONFIG.smoothWait` (default `1/60` sec) and yields execution while honoring `CONFIG.PAUSED`. |
104
+ | `SHUTDOWN()` / `QUIT()` | Stops the engine loop (`CORE.RUNNING = False`) or posts a `pygame.QUIT` event. |
105
+ | `startConfigSync(data_dict)` | Starts a background `Script` that continuously synchronizes a dictionary of variable names with the caller's global scope. |
106
+
107
+ ### 2. Sprites & Entities (`entities/entity.py`)
108
+
109
+ `Entity` is the core sprite class in Jeski. Every `Entity` is automatically added to `CORE.ENTITIES` (unless `type='Stamp'`) and rendered each frame.
110
+
111
+ ```python
112
+ hero = Entity(
113
+ image="hero.png", # Optional path to image file (or pass rawimage=Surface)
114
+ x=300, y=300, # Defaults to screen center (CONFIG.centerX, CONFIG.centerY)
115
+ sizeX=64, sizeY=64, # Dimensions when using procedural rectangle fallback
116
+ color=colors.BLUE, # Fill color if no image is supplied
117
+ centered=True, # Center sprite on (x, y)
118
+ collider=True # Enable automatic collision rollback in check_collisions()
119
+ )
120
+ ```
121
+
122
+ #### Movement, Rotation & Scaling
123
+
124
+ - `hero.move(steps, raw=False)`: Moves forward along `hero.direction` (clamped to window bounds unless `raw=True`).
125
+ - `hero.turn(deg)`: Rotates the entity by `deg` degrees and checks collisions.
126
+ - `hero.pointTowards(other_entity)`: Rotates to face another entity's `(x, y)` coordinates.
127
+ - `hero.goto(x, y)` / `hero._goto(other_entity)`: Teleports to coordinates or another entity's position.
128
+ - `hero.changeXby(steps)` (`chx`) / `hero.changeYby(steps)` (`chy`): Moves along a single axis with collision rollback.
129
+ - `hero.setSize(percent)` / `hero.changeSize(delta_percent)` (`chs`) / `hero.setSizeToVal((w, h))`: Scales `original_image` smoothly using `pygame.transform.smoothscale`.
130
+ - `hero.rotationStyle`: Set to `2` for full 360° rotation (default), `1` for left-right horizontal flip, or `0` for fixed orientation.
131
+
132
+ #### Costumes, Visual Effects & Layering
133
+
134
+ - `hero.addCostume(Costume(name, obj))` / `hero.removeCostume(idx)`: Manages the entity's costume list.
135
+ - `hero.nextCostume()` / `hero.previousCostume()` / `hero.changeCostume(idx)`: Switches active appearance.
136
+ - `hero.transparency`: Value from `0` (opaque) to `255` (invisible).
137
+ - `hero.brightness`: Positive values (`0` to `255`) brighten via `BLEND_RGBA_ADD`; negative values darken via `BLEND_RGBA_SUB`.
138
+ - `hero.hide()` / `hero.show()`: Toggles visibility.
139
+ - `hero.bringToFront()` / `hero.sendToBack()`: Reorders draw priority inside `CORE.ENTITIES`.
140
+
141
+ #### Clones, Stamps & Collisions
142
+
143
+ - `hero.stamp(var=None, ret=False)`: Leaves a static visual copy on `CORE.STAMPS` (press `Q` at runtime to clear stamps).
144
+ - `hero.createClone(ret=False, config=None)`: Spawns an independent `Clone` entity inheriting position, direction, costumes, and variables.
145
+ - `hero.touching(other_or_mouse)`: Returns `True` on pixel-perfect mask overlap with another entity or `'__mouse__'`.
146
+ - `hero.isClicked()`: Returns `True` if the mouse button is down and touching the entity's mask.
147
+ - `hero.delete()`: Removes the entity from `CORE.ENTITIES` and any registered reference lists.
148
+
149
+ #### Dialogs (`Box`)
150
+
151
+ - `answer = hero.askAndWait("What is your name?")`: Opens an interactive text input box next to the entity and returns the submitted string.
152
+ - `hero.sayFor("Hello!", timeout=2)`: Displays a speech bubble for `timeout` seconds.
153
+ - `hero.say("Thinking...")`: Displays a persistent speech bubble bound to `hero.var['msg']` (set `hero.var['msg'] = ''` to dismiss).
154
+
155
+ ### 3. Geometric Shapes & Groups (`entities/shapes.py`)
156
+
157
+ All shapes support `BASICDRAW` caching, masks, and `Entity` helper methods via `verifyAttributes()`. Each class also provides a `*F` subclass (e.g., `RectangleF`, `CircleF`, `PolygonF`) with `trueEntity=False` for building `Costume` objects or composite `Group` hierarchies without adding sub-parts directly to `CORE.ENTITIES`.
158
+
159
+ | Shape Class | Constructor Signature |
160
+ | :--- | :--- |
161
+ | `Image` / `ImageF` | `Image(path, x=None, y=None, raw=False, trueEntity=True)` |
162
+ | `Rectangle` / `RectangleF` | `Rectangle(x, y, w, h, color=colors.BLACK, trueEntity=True)` |
163
+ | `CurvedRectangle` / `CurvedRectangleF` | `CurvedRectangle(x, y, w, h, curve, color=colors.BLACK, trueEntity=True)` |
164
+ | `Circle` / `CircleF` | `Circle(center, radius, width=0, color=colors.BLACK, trueEntity=True)` |
165
+ | `Ellipse` / `EllipseF` | `Ellipse(center, radiusMinor, radiusMajor, width=0, color=colors.BLACK, trueEntity=True)` |
166
+ | `Triangle` / `TriangleF` | `Triangle(cord1, cord2, cord3, color=colors.BLACK, trueEntity=True)` |
167
+ | `Polygon` / `PolygonF` | `Polygon(cords, color=colors.BLACK, trueEntity=True)` |
168
+ | `Line` / `LineF` | `Line(cord1, cord2, color=colors.BLACK, width=5, trueEntity=True)` |
169
+ | `ZigZag` / `ZigZagF` | `ZigZag(cords, color=colors.BLACK, width=5, trueEntity=True)` |
170
+ | `Group` / `GroupF` | `Group(attributes=None, entities=None, tight=False, trueEntity=True)` |
171
+
172
+ ### 4. UI, Text, Grids & Meshes (`entities/ui.py`, `mesh.py`)
173
+
174
+ - **`Text(text, x, y, font=None, size=40, align='center', color=colors.BLACK)`**: Renders cached Pygame font surfaces. Update properties dynamically with `text_obj.change('text', 'New Value')`.
175
+ - **`Variable(variable_name, x, y, size=40, color=colors.BLACK)`**: Subclasses `Text` and spawns a background `Script` that watches a global variable by name (e.g., `Variable('score', 100, 50)`) and re-renders automatically whenever its value changes.
176
+ - **`MESSAGE`**: Static wrapper around `tkinter.messagebox` providing `info()`, `warning()` / `warn()`, `error()`, `yesNo()`, `okCancel()`, `retryCancel()`, and `yesNoCancel()`.
177
+ - **`GridMesh2D(x=10, y=10, center=True, margin=0)` & `GridMesh1D(type='x', c=10, center=True, margin=0)`**: Automatically computes cell widths/heights across `WINDOW` and positions objects added via `.add(obj, coords=(col, row))`.
178
+
179
+ ### 5. Animations, Audio & Concurrency (`animations.py`, `sounds.py`, `scripts.py`)
180
+
181
+ - **`Script(function, starter='CORE.RUNNING', once=True, loop=None, waitUntilFinished=False)`**: Runs `function` in a daemon thread when the `starter` expression evaluates to truthy.
182
+ - **`startAnimation(obj, costs=[0, 1, 2], fps=10)`**: Cycles `obj` through the specified costume indices at `fps` frames per second in a background `Script`.
183
+ - **`blink(obj, fast=False)`**: Pulses an entity's brightness up to `100` and back to its original value.
184
+ - **`SOUNDPLAYER`**:
185
+ - `SOUNDPLAYER.play(sound, raw=False, config={'volume': 50, 'loops': 0, 'fade_ms': 0}, untilFinished=False)`
186
+ - `SOUNDPLAYER.setMasterVolume(80)`
187
+ - `SOUNDPLAYER.fadeAll(500)` / `SOUNDPLAYER.stopAll()`
188
+ - `SOUNDPLAYER.mute()` / `SOUNDPLAYER.unmute()`
189
+
190
+ ### 6. Configuration & Built-in Shortcuts (`config.py`)
191
+
192
+ Customize `WINDOW` and `CONFIG` before calling `INITIALIZE()`:
193
+
194
+ ```python
195
+ WINDOW.WIDTH = 1280
196
+ WINDOW.HEIGHT = 720
197
+ CONFIG.WINDOWTITLE = "My Jeski Game"
198
+ CONFIG.FPS = 60
199
+ CONFIG.backgroundColor = colors.WHITE
200
+ CONFIG.debug = True
201
+ ```
202
+
203
+ **Built-in Runtime Hotkeys:**
204
+ - **`M` key** (or **`T`** when `CONFIG.debug = True`): Toggles red/translucent collision mask overlays (`CONFIG.showMask`) across all entities.
205
+ - **`Q` key**: Clears all `Stamp` entities from `CORE.ENTITIES`.
206
+
207
+ ## Project Structure
208
+
209
+ ```text
210
+ Jeski/
211
+ ├── __init__.py # Engine lifecycle (INITIALIZE, UPDATE, DRAWSCREEN, UPDATEVARS)
212
+ ├── __main__.py # Built-in 2-player demo script
213
+ ├── animations.py # Costume frame animation and brightness blink effects
214
+ ├── commands.py # Shell execution (RunCommand), PyInstaller paths, UAC elevation
215
+ ├── config.py # CORE state, WINDOW dimensions, CONFIG settings, colors, GUI aliases
216
+ ├── credits.py # Author metadata
217
+ ├── deps.py # Dependency imports and safeImport verification fallback
218
+ ├── grid.py # Grid module stub (implemented in utils.py / __init__.py)
219
+ ├── imageTools.py # Surface brightness and alpha manipulation helpers
220
+ ├── mesh.py # GridMesh1D and GridMesh2D layout managers
221
+ ├── scripts.py # Threaded Script runner and roughScript helper
222
+ ├── sounds.py # SOUNDPLAYER multi-channel mixer controller
223
+ ├── tests.py # Interactive live-variable entity test harness (TESTS_)
224
+ ├── utils.py # Surface compositing, attribute verification, eval helpers, timing
225
+ ├── assets/ # Built-in WAV sound effects (alert.wav, coin.wav, Lose.wav)
226
+ └── entities/
227
+ ├── __init__.py # Exports Entity, shapes, and UI classes
228
+ ├── base.py # BASICDRAW surface caching, rotation, brightness, mask overlay
229
+ ├── entity.py # Core Entity, Costume, and Box (say/ask) classes
230
+ ├── shapes.py # Vector shapes, Group compositor, and *F non-entity subclasses
231
+ ├── _shapes.py # Legacy shapes module
232
+ └── ui.py # MESSAGE dialogs, Text renderer, and reactive Variable widget
233
+ ```
234
+
235
+ ## Author & Credits
236
+
237
+ Created and maintained by **Siddharth Barnwal** (`Enirb` / `beast.barnwal`).