Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
de1e743
Fix type hinting issue in _remove_previous_build function
Natuworkguy Aug 29, 2026
c8e16cd
Fix config
Natuworkguy Aug 29, 2026
de92e83
Add docstring to __main__.py for clarity on GUI execution
Natuworkguy Aug 29, 2026
8affc79
Add docstrings to _QueueWriter and build functions for improved clarity
Natuworkguy Aug 29, 2026
e269b83
Put all loaders in engine.loaders
Natuworkguy Aug 29, 2026
b98eddc
Merge branch 'main' of https://github.com/Natuworkguy/ABS-Engine into…
Natuworkguy Aug 29, 2026
a4c73f5
Refactor nut_source to raise exceptions for missing or invalid script…
Natuworkguy Aug 29, 2026
e9dc83b
Refactor tcl_source to improve error handling for script paths
Natuworkguy Aug 29, 2026
8cf7f12
Update pyright exclude configuration to include default excludes
Natuworkguy Aug 30, 2026
0c5abf6
Remove unused ABS specific cache files from .gitignore
Natuworkguy Aug 30, 2026
56846d1
Add .venv directory to markdownlint ignore list
Natuworkguy Aug 30, 2026
0c79920
Fix markdown
Natuworkguy Aug 30, 2026
ca12863
Add more float support
Natuworkguy Aug 31, 2026
384ef52
Add script directory to sys.path for dynamic module loading
Natuworkguy Aug 31, 2026
5b627b1
Implement script reloading to clear cached modules and bytecode
Natuworkguy Aug 31, 2026
7e059dd
Enhance Editor class to handle default values and clear fields on emp…
Natuworkguy Aug 31, 2026
7225883
Refactor game execution to use multiprocessing for improved performan…
Natuworkguy Aug 31, 2026
59d4b73
Add Music class for background music playback with volume control and…
Natuworkguy Aug 31, 2026
4ed70b2
Call _update_rect after initializing the scriptfile module in Entity …
Natuworkguy Aug 31, 2026
67f815f
Change Text.x and Text.y to floats
Natuworkguy Aug 31, 2026
fc81906
Update get_center function signature to return float coordinates
Natuworkguy Aug 31, 2026
dd2892b
Correct docstring of get_center()
Natuworkguy Sep 1, 2026
b627495
Change Entity.center position type to tuple[float, float]
Natuworkguy Sep 1, 2026
871bf40
Set max line length for markdown
Natuworkguy Sep 1, 2026
f1eee0a
Update documentation for clarity and accuracy
Natuworkguy Sep 2, 2026
689cf7a
Refactor Text constructor to move 'text' parameter to the beginning
Natuworkguy Sep 2, 2026
8bfe038
Add implementation note for clamp function in docstring
Natuworkguy Sep 2, 2026
1091b0f
Add EntityAnim class and update Entity to support animations
Natuworkguy Sep 2, 2026
06cca26
Enhance EntityAnim class with loop control and restart functionality
Natuworkguy Sep 2, 2026
c350225
Add support for animation file types in file dialog
Natuworkguy Sep 2, 2026
fb0217d
Fix formatting of logger call
elijahcroft Sep 2, 2026
24442a0
Fix pyinstaller build
elijahcroft Sep 2, 2026
1d5781a
Add repo to game requirements.txt
Natuworkguy Sep 2, 2026
29d2d48
Merge pull request #36 from elijahcroft/format/logger-call
Natuworkguy Sep 2, 2026
af43908
Merge pull request #37 from elijahcroft/fix/pyinstaller-build
Natuworkguy Sep 2, 2026
bc6495f
Refactor docstrings to include class references for better clarity
Natuworkguy Sep 2, 2026
788a063
Merge branch 'dev' of https://github.com/Natuworkguy/ABS-Engine into dev
Natuworkguy Sep 2, 2026
25e9b1b
Add VSCode extensions recommendations for improved development experi…
Natuworkguy Sep 2, 2026
7ea8197
Fix default values for Entity coordinates to use float type
Natuworkguy Sep 3, 2026
f5bc538
Fix Entity constructor to use float type for width and height parameters
Natuworkguy Sep 3, 2026
7e93964
Migrate Entity to FRect
Natuworkguy Sep 3, 2026
64f0039
Migrate Entity to FRect
Natuworkguy Sep 3, 2026
3a39d05
Merge branch 'dev' of https://github.com/Natuworkguy/ABS-Engine into dev
Natuworkguy Sep 3, 2026
5c0b50e
Fix repository URL format in requirements.txt
Natuworkguy Sep 3, 2026
2954ef8
Fix formatting of .gitattributes entry for absp files
Natuworkguy Sep 3, 2026
e82df49
Map engine/ onto the abs_engine import name
Natuworkguy Sep 3, 2026
f18df08
Fix package variable initialization in __main__.py
Natuworkguy Sep 3, 2026
216f0d9
Update .gitattributes to include additional export-ignore entries
Natuworkguy Sep 4, 2026
74bd5dc
Add .env to exclude list in .flake8 configuration
Natuworkguy Sep 4, 2026
f2058f6
Fix package variable initialization in __main__.py to default to "eng…
Natuworkguy Sep 4, 2026
df33a1c
Add copyright notice to theme.tcl
Natuworkguy Sep 4, 2026
fed005c
Change AI policy source reference to permalink
Natuworkguy Sep 4, 2026
7738ebd
Update commit message guidelines in CONTRIBUTING.md
Natuworkguy Sep 4, 2026
87846e3
Add copyright notice and license reference to error and main modules
Natuworkguy Sep 5, 2026
a36e45c
Merge branch 'dev' of https://github.com/Natuworkguy/ABS-Engine into dev
Natuworkguy Sep 5, 2026
5b0bf71
Refactor error handling in ABSFatalError to use eprint for consistency
Natuworkguy Sep 8, 2026
cf38239
Fix link formatting in AI Policy reference
Natuworkguy Sep 8, 2026
f8f6278
Add color parameter to superclass initialization in Text entity
Natuworkguy Sep 10, 2026
70cd1cb
Merge branch 'dev' of https://github.com/Natuworkguy/ABS-Engine into dev
Natuworkguy Sep 10, 2026
7f0db14
Format superclass initialization in Text entity
Natuworkguy Sep 10, 2026
e0a20be
Use SPDX license expression in project metadata
Natuworkguy Sep 11, 2026
5ed467b
Add C stuff
Natuworkguy Sep 11, 2026
1b7587e
Enhance error handling in c_source function to raise ModuleNotFoundEr…
Natuworkguy Sep 11, 2026
1c78c5f
Store animation frame starts in an array
Natuworkguy Sep 11, 2026
bb5b32b
Merge pull request #38 from Natuworkguy/add/c-stuff
Natuworkguy Sep 11, 2026
40dff2d
Improve debug representation of Entity class to display address in up…
Natuworkguy Sep 11, 2026
55b1550
Bump version to 0.5.7
Natuworkguy Sep 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4

[*.py]
max_line_length = 100

[*.{nut,tcl}]
max_line_length = 100

[*.{yml,yaml,json,toml}]
indent_size = 2

[*.md]
max_line_length = 81
trim_trailing_whitespace = false

[*.{cfg,ini,flake8}]
indent_size = 4
3 changes: 2 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[flake8]
ignore = E501, W503
exclude =
.venv
.venv
.env
9 changes: 9 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
* text=auto eol=lf

*.absp text linguist-language=JSON linguist-detectable=true diff=json

.github export-ignore
.vscode export-ignore
.editorconfig export-ignore
.flake8 export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.markdownlint-cli2.yaml export-ignore
AGENTS.md export-ignore
10 changes: 5 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ cython_debug/
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
.vscode/
# (shared workspace config is un-ignored below)
.vscode/*
!.vscode/extensions.json

# Ruff stuff:
.ruff_cache/
Expand All @@ -213,7 +215,5 @@ __marimo__/
# Agents
.agents/

### ABS Specific ###

# ABS cache files
abs_cache/
# Compiled engine C
engine/c/build/
7 changes: 7 additions & 0 deletions .markdownlint-cli2.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
ignores:
- "LICENSE"
- ".venv/**"

globs:
- "**/*.{md,markdown}"

config:
MD013: false
17 changes: 17 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"recommendations": [
"ms-python.python",
"ms-python.vscode-pylance",

"charliermarsh.ruff",
"astral-sh.ty",
"ms-python.mypy-type-checker",
"ms-python.flake8",
"nwgh.bandit",
"kennethlove.interrogate",
"DavidAnson.vscode-markdownlint",

"marcinbar.vscode-squirrel",
"rashwell.tcl"
]
}
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Contributions of all types are welcome, including:

Please read this document before submitting changes.

> [!Note]
> [!NOTE]
> All contributions should target the `dev` branch. Changes are reviewed and
> tested there before being merged into `main` for releases.

Expand Down Expand Up @@ -98,6 +98,7 @@ All contributions should prioritize:
provided they do not produce large or significant changes.
- **Trivial Edits Allowed:** Very small, obvious changes such as typo fixes,
whitespace cleanup, or minor wording updates are permitted.
- **Commit messages allowed**: Generated commit messages are allowed as long as they are an accurate description of the change being made.
- **Human Responsibility:** All contributions must be reviewed, tested, and
approved by a human author.

Expand All @@ -115,7 +116,7 @@ All contributions should prioritize:
- **Trivial Changes Only:** Very small edits are allowed.

<!-- markdownlint-disable MD033 -->
<small>This AI Policy is derived from [Gravel's AI Policy](https://github.com/Pacsfury/Gravel-Launcher/blob/main/AI-POLICY.md).</small>
<small>This AI Policy is derived from [Gravel's AI Policy](https://github.com/Pacsfury/Gravel-Launcher/blob/ed0301ba7aa82342ac937cf1d149d68d00008724/AI-POLICY.md).</small>
<!-- markdownlint-enable MD033 -->

---
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
include engine/py.typed
recursive-include engine/tcl *.tcl
recursive-include engine/nut *.nut
recursive-include engine/c *.c *.h
6 changes: 6 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@
This folder contains the documentation for ABS Engine.

Documentation may include guides, tutorials, references, examples, and other resources related to using and developing games with ABS Engine.

> [!TIP]
> If you're new to ABS Engine, check out:
>
> * [Scripting Docs](scripting.md)
> * [Build Tools Docs](using_build_tools.md)
4 changes: 2 additions & 2 deletions docs/accessing_the_console.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ python3 run.pyw

Make sure you run it with the `python3` or `py` command. Directly using the file path will not show the console.

Bad Example:
Don't do this:

```powershell
& "C:/Users/User/ABS-Engine/run.pyw"
```

*Good* Example:
Do this:

```powershell
py C:/Users/User/ABS-Engine/run.pyw
Expand Down
4 changes: 2 additions & 2 deletions docs/debugging_games.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ Here are the main parts of the message:
```

**Type**: The severity of the message (can be "INFO", "WARNING", or "CRITICAL")
**Source**: Shows which module the message originated from. In this example, the message came from `engine/core.py`.
**Source**: Shows which module the message originated from. In this example, the message came from `engine/core/__init__.py`.
**Message**: The message being printed

Example of a critical error message:

```text
(CRITICAL) ENGINE.GUI: Initialized game
(CRITICAL) ENGINE.GUI: Could not load icon image.
| | |
| |______ |_______
| |Source| |Message|
Expand Down
5 changes: 2 additions & 3 deletions docs/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ This document describes ABS Engine's error module (`engine.core.errors`).

## Overview

`engine.core.errors` is not only for fatal, unrecoverable errors. It also will
define precise, engine-specific exception types for situations that
`engine.core.errors` is not only for fatal, unrecoverable errors. It will also define precise, engine-specific exception types for situations that
could otherwise be mistaken for an ordinary, expected error (e.g. a
generic `ValueError` or `KeyError`) but that the user of the engine
should actually be catching and handling deliberately. Naming these
Expand Down Expand Up @@ -41,7 +40,7 @@ def __init__(self, message: str) -> Never: ...
from engine.core.errors import ABSFatalError

if renderer_context_lost:
ABSFatalError("Lost graphics context, cannot continue")
raise ABSFatalError("Lost graphics context, cannot continue")
```

Do **not** wrap this in a `try`/`except` expecting to recover. It's
Expand Down
2 changes: 1 addition & 1 deletion docs/game_file_structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ MyGame
```

Do not create game.absp, as it is generated by ABS Engine.
It contains the project name, game settings, and entity names,
It contains the project name, game settings, entity names,
properties, and data.

## Game Data Structure
Expand Down
78 changes: 78 additions & 0 deletions docs/music.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Music

Every [`Game`](using_the_engine_api.md) owns a small music mixer as
`game.music`. It plays one background track at a time, which is what
background music usually is: a single looping track that changes when the
scene or the mood does.

From a [script](scripting.md), reach it through the entity's scene:

```python
def init(entity):
game = entity.parent.game
game.music.play("assets/theme.ogg")
```

> [!TIP]
> Music is not entity-specific, so start it from your main script.
> See the tip about main scripts in the [Main Scripts section of the scripting docs](scripting.md#main-scripts).

Using the engine API directly:

```python
from engine.core import Game


game = Game(GP_BASE_PATH=".")

game.music.set_volume(0.5)
game.music.play("data/audio/theme.ogg")

game.run()
```

## Methods

| Method | Description |
| --- | --- |
| `play(track, *, loops=-1, fade_ms=0)` | Start `track`, replacing whatever was playing. `track` is a path relative to the project root. `loops` is how many extra times to repeat it, `-1` forever. `fade_ms` fades the track in. |
| `stop(*, fade_ms=0)` | Stop the current track and forget it. `fade_ms` fades it out instead of cutting it. |
| `pause()` | Hold the current track where it is. |
| `resume()` | Carry on with a paused track. |
| `set_volume(volume)` | Set how loud music plays, from `0.0` to `1.0`. Values outside that range are clamped. Applies to later tracks too. |
| `get_volume()` | Return the volume music is set to play at, from `0.0` to `1.0`. |
| `is_playing()` | Return whether a track is audible right now. A paused track is not playing. |

## Properties

| Property | Description | Type |
| --- | --- | --- |
| `track` | Path of the loaded track, or `None` when nothing is loaded | `Optional[str]` |
| `available` | Whether an audio device was opened | `bool` |
| `base_path` | Project root that `track` paths are given relative to | `str` |

## Formats

Playable formats come from pygame, which uses SDL_mixer. OGG and WAV are the
safe choices; MP3 support depends on how the player's SDL_mixer was built.
Prefer OGG for music, since it is compressed and always supported.

## Machines Without Audio

Some machines have no working audio device: a headless build server, a
container, or a desktop with sound disabled. Rather than crash a game over
it, the mixer logs a warning at startup and sets `available` to `False`.
Every method stays safe to call, and none of them do anything:

```python
def init(entity):
music = entity.parent.game.music

music.play("data/audio/theme.ogg") # Fine. Silent, but fine.

if not music.available:
entity.parent.game.gamedata["subtitles"] = True
```

A missing or unreadable track file is handled the same way: the load is
logged as a warning and whatever was already playing keeps playing.
1 change: 1 addition & 0 deletions docs/scenes.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Scenes are managed by `engine.core.Game`, and each scene is represented by
Every `Game` has:

- `game.scenes`: A list of all scenes in the game.
- `game.music`: See [this article](music.md)
- `game.current_scene`: The index of the scene currently being shown.
- `game.add_scene()`: A method that creates a new scene and returns its index.
- `game.switch_scene(scene_index)`: A method that changes the active scene.
Expand Down
44 changes: 27 additions & 17 deletions docs/scripting.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ With scripting, you can move and manipulate objects, create animations, and much
In other words, scripting allows you to make entities in your game _do things_.
Here's how to get started:

> [!TIP]
> If you're planning on using the engine API, see:
>
> * [Using the Engine API Directly](using_the_engine_api.md)
> * [OSE Docs](ose.md)

To create a script file, first follow the
[recommended file structure](game_file_structure.md).
The `assets/` folder is not needed for this tutorial.
Expand All @@ -23,7 +29,7 @@ Then, launch ABS Engine and follow these steps:
6. Click "Save", then "Save Project"
7. Verify that `game.absp` was saved in your project folder

>[!Tip]
> [!TIP]
> Name your scripts after the entity they're attached to.
> This makes it easy to identify them later.

Expand All @@ -41,18 +47,6 @@ def update(entity, dt):
Go back to ABS Engine and click "Run".
You should see a white square moving continuously from left to right.

>[!Tip]
> Because the engine requires a script to
> be attached to an entity in your game,
> put everything in the game that is not
> entity-specific (e.g. playing background
> music, etc.) in the script attached to
> the player entity (The entity that the
> player controls). This is called a main
> script. If your game does not have a player
> entity, place a new entity off screen that
> has the main script attached to it.

Let's break down what this code does.
In a script file, three functions are commonly defined:

Expand All @@ -63,7 +57,9 @@ event(entity: Entity, event: pygame.event.Event) -> None
```

`init()` - Called once when the game starts

`update()` - Called every frame (multiple times per second)

`event()` - Called when a pygame event is triggered

## Entity Properties
Expand All @@ -82,7 +78,7 @@ The `engine.core.Entity` class has the following properties:
| `width` | Width in pixels | `float` |
| `height` | Height in pixels | `float` |
| `color` | RGB color value | `tuple[int, int, int]` |
| `rect` | Pygame rect object on screen | `pygame.Rect` |
| `rect` | Pygame rect object on screen | `pygame.FRect` |
| `scriptfile` | Path to the attached script | `str` |
| `image` | Image attached to entity | `EntityImage` or `None` |
| `id` | Unique entity UUID | `str` |
Expand All @@ -94,9 +90,9 @@ The `engine.core.Entity` class has the following properties:

The `init()`, `update()`, and `event()` functions are callback functions that ABS Engine calls at specific times:

- `init(entity: Entity) -> None` - Called when the game starts
- `update(entity: Entity, dt: float) -> None` - Called every frame
- `event(entity: Entity, event: pygame.event.Event) -> None` - Called when an a pygame event occurs
* `init(entity: Entity) -> None` - Called when the game starts
* `update(entity: Entity, dt: float) -> None` - Called every frame
* `event(entity: Entity, event: pygame.event.Event) -> None` - Called when an a pygame event occurs

Here's an example script that creates a simple game with player movement.
The game uses a top-down perspective with a player-controlled square
Expand Down Expand Up @@ -151,3 +147,17 @@ def event(entity, event):
> If the game window freezes or shows a black screen at startup,
> check that your script file has no syntax errors. It is completely normal for a game to crash if there are code errors.
> See [Debugging Games](debugging_games.md) for help diagnosing issues.

## Main Scripts

> [!TIP]
> Because the engine requires a script to
> be attached to an entity in your game,
> put everything in the game that is not
> entity-specific (e.g. playing background
> music, etc.) in the script attached to
> the player entity (The entity that the
> player controls). This is called a main
> script. If your game does not have a player
> entity, place a new entity off screen that
> has the main script attached to it.
2 changes: 1 addition & 1 deletion docs/using_build_tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Click "Build Game", then "Yes".
ABS Engine will now compile the game and all of its dependencies
to the folder that contains the project file, using Pyinstaller
under the hood. A "Building Game" window stays open with a progress
bar while this happens, and only closes once Pyinstaller has
bar and log while this happens, and only closes once Pyinstaller has
actually finished.

When you run the new `run.py` file in that folder,
Expand Down
Loading