My 2D Engine
A beginner-friendly 2D game engine built with Python and Pygame.
My 2D Engine is designed to make building 2D games easier without requiring you to write an entire game framework from scratch.
It provides systems for:
- 🎮 Entities
- ⚙️ Physics
- 🧱 Collision
- 🟦 One-way platforms
- ↔️ Moving platforms
- 🗺️ Tilemaps
- 🎥 Cameras
- 🎨 Rendering
- 🎞️ Animations
- 💥 Hitboxes
- ✨ Particles
- 🔊 Sound
- 🎹 Keyboard and mouse input
- 🖼️ Asset management
- 🧩 Components
- 🖥️ UI
- 🎬 Scenes
- 💾 Save/load
- 🐛 Debugging
The engine is intended primarily for 2D platformers, arcade games, rhythm games, top-down games, shooters, and other small-to-medium 2D projects.
Table of Contents
- Requirements
- Installation
- Project Structure
- Quick Start
- Engine
- Entities
- Entity Properties
- Movement
- Physics
- Gravity
- Jumping
- Friction
- Acceleration
- Maximum Speed
- Custom Entity Updates
- Tags
- Sprites
- Animations
- Solids
- Collision
- One-Way Platforms
- Moving Platforms
- Hitboxes
- Particles
- Input
- Keyboard Input
- Mouse Input
- Tilemaps
- Tile Definitions
- Tilemap Layers
- Spawn Points
- Tilemap Collision
- Camera
- Rendering
- Components
- Scenes
- UI
- Asset Manager
- Sound
- Save and Load
- Debug Mode
- Complete Example
- Recommended Game Structure
- Common Mistakes
- Engine Architecture
- Current Limitations
- FAQ
Requirements
You need:
- Python 3.10+
- Pygame 2.x
Install Pygame with:
pip install pygame
Or:
python -m pip install pygame
Installation
Clone or download the engine.
Your project should contain the engine folder:
my_game/
│
├── main.py
│
└── engine/
├── engine.py
├── core/
├── collisions/
├── camera/
├── rendering/
├── scenes/
└── tilemap/
Run your game with:
python main.py
Project Structure
The engine is separated into different systems.
engine/
│
├── engine.py
│
├── core/
│ ├── entity.py
│ ├── updater.py
│ ├── animation.py
│ ├── physics.py
│ ├── solid.py
│ ├── sound.py
│ ├── particle.py
│ ├── hitbox.py
│ ├── component.py
│ ├── input.py
│ ├── asset_manager.py
│ ├── ui.py
│ ├── save.py
│ └── debug.py
│
├── collisions/
│ └── collisions.py
│
├── camera/
│ └── camera.py
│
├── rendering/
│ └── renderer.py
│
├── scenes/
│ └── scene.py
│
└── tilemap/
└── tilemap.py
You normally don't need to modify these files when making a game.
Your game code should primarily go into:
main.py
and your own game-specific files.
Quick Start
The smallest possible game is:
from engine.engine import Engine
game = Engine()
game.run()
This creates the game window and starts the engine.
Creating an Entity
Entities are the basic objects used in the engine.
Create one:
player = game.add_entity("player")
Set its position:
player.position = [100, 100]
Set its size:
player.size = [40, 40]
Set its color:
player.color = [255, 0, 0]
Enable collision:
player.collidable = True
Entity Properties
An entity contains several useful properties.
Position
player.position = [100, 200]
The position is:
[x, y]
Velocity
player.velocity = [5, 0]
The first value controls horizontal velocity.
The second controls vertical velocity.
player.velocity[0] = 5
moves right.
player.velocity[0] = -5
moves left.
player.velocity[1] = -10
moves upward.
Size
player.size = [50, 50]
Color
player.color = [255, 0, 0]
Colors use RGB values:
Red = [255, 0, 0]
Green = [0, 255, 0]
Blue = [0, 0, 255]
White = [255, 255, 255]
Black = [0, 0, 0]
Visibility
player.visible = True
Hide an entity:
player.visible = False
Active State
player.active = True
Disable an entity:
player.active = False
Inactive entities are not updated.
Movement
The engine lets you directly control velocity:
player.velocity[0] = 5
Or create acceleration-based movement:
player.set_acceleration(0.5)
For a normal platformer, a custom update function is usually useful:
def update(player, keys):
if game.input.down("left"):
player.velocity[0] -= 0.5
if game.input.down("right"):
player.velocity[0] += 0.5
player.set_update(update)
Physics
Every entity has a physics system:
player.physics
The physics system supports:
- Acceleration
- Maximum speed
- Friction
- Air friction
- Gravity scaling
Gravity
Enable gravity:
player.set_gravity(0.5)
The value controls how quickly vertical velocity increases.
Example:
player.set_gravity(0.6)
You can modify the gravity scale:
player.physics.gravity_scale = 0.5
This makes the entity experience half the normal gravity.
Jumping
Set jump strength:
player.set_jump(12)
Then:
player.jump()
The engine checks whether the entity is grounded.
You can also check:
if player.grounded:
print("Player is standing on something")
Friction
Set ground and air friction:
player.set_friction(
2,
0.2
)
The first value is ground friction.
The second value is air friction.
Higher friction makes the entity stop faster.
For responsive movement, smaller values are usually preferable.
Acceleration
Enable acceleration:
player.set_acceleration(0.5)
You can also specify X and Y acceleration:
player.set_acceleration(
0.5,
0.2
)
Maximum Speed
Set horizontal and vertical maximum speeds:
player.set_max_speed(
7,
20
)
The first value is maximum X speed.
The second value is maximum Y speed.
Custom Entity Updates
Every entity can have its own update function.
def player_update(player, keys):
if game.input.down("left"):
player.velocity[0] -= 0.5
if game.input.down("right"):
player.velocity[0] += 0.5
if game.input.pressed("jump"):
player.jump()
player.set_update(
player_update
)
The engine calls this function every frame.
This is where game-specific logic should normally go.
Tags
Tags allow you to categorize entities.
Add a tag:
player.add_tag("player")
Add multiple:
player.add_tag("character")
player.add_tag("friendly")
Check:
if player.has_tag("player"):
print("This is the player")
Remove:
player.remove_tag("friendly")
Tags are useful for:
player
enemy
boss
projectile
coin
NPC
enemy_projectile
collectible
Finding Entities
Get an entity by name:
player = game.get_entity("player")
If it cannot be found, the result is:
None
Sprites
Entities can use images.
player.set_sprite(
"assets/player.png"
)
Remove the sprite:
player.remove_sprite()
The renderer automatically uses the sprite when rendering the entity.
Animations
The engine contains an animation manager.
You can create an animation from separate images:
player.add_animation_images(
"idle",
[
"assets/idle1.png",
"assets/idle2.png",
"assets/idle3.png"
],
speed=10
)
Play it:
player.play_animation("idle")
Restart it:
player.play_animation(
"idle",
restart=True
)
Check whether an animation has finished:
if player.animation_finished():
print("Animation finished")
You can use animations for:
Idle
Run
Jump
Fall
Attack
Death
Hurt
Dash
Solids
Solids are objects that entities can collide with.
Create one:
platform = game.add_solid(
100,
400,
500,
40
)
The arguments are:
x
y
width
height
You can change its color:
platform.color = [
100,
100,
100
]
Collision
Enable collision on an entity:
player.collidable = True
The collision system handles movement against solid objects.
The system separates horizontal and vertical movement so basic platformer collisions can be handled independently.
One-Way Platforms
One-way platforms allow an entity to pass through from below and land on top.
Create one:
platform = game.add_one_way_platform(
200,
300,
200,
20
)
Conceptually:
PLAYER
↓
───────────────
PLATFORM
Player can pass upward
and land when falling.
This is useful for platformers.
Moving Platforms
Create a horizontal moving platform:
platform = game.add_moving_platform(
400,
350,
150,
25,
velocity_x=50
)
Create a vertical moving platform:
platform = game.add_moving_platform(
400,
350,
150,
25,
velocity_y=-50
)
Both directions can be used:
platform = game.add_moving_platform(
400,
350,
150,
25,
velocity_x=50,
velocity_y=-30
)
Moving platforms are useful for:
- Platforming challenges
- Elevators
- Moving obstacles
- Puzzle levels
Hitboxes
Hitboxes are areas that detect entities.
Create one:
trigger = game.add_hitbox(
600,
300,
100,
100
)
Create an event:
def entered(entity):
print(
entity.name,
"entered the trigger"
)
trigger.on_enter(
entered
)
Hitboxes are useful for:
Triggers
Damage zones
Checkpoints
Portals
Collectibles
Boss arenas
Level transitions
Particles
The particle system can create visual effects.
Example:
game.particles.emit(
400,
300,
count=30,
color=(255, 200, 50),
size=6,
speed=150,
lifetime=1,
gravity=100
)
Parameters include:
x
y
count
color
size
speed
lifetime
gravity
image
Example explosion:
game.particles.emit(
enemy.position[0],
enemy.position[1],
count=50,
color=(255, 100, 20),
size=5,
speed=250,
lifetime=0.8,
gravity=150
)
Particles can also load animation images and sprite sheets.
Input
The input system provides keyboard and mouse controls.
Bind a key:
game.input.bind(
"left",
pygame.K_a
)
game.input.bind(
"right",
pygame.K_d
)
game.input.bind(
"jump",
pygame.K_SPACE
)
This means your game logic doesn't need to constantly reference raw Pygame keys.
Keyboard Input
Held
Use:
game.input.down("left")
This is True while the key is held.
Example:
if game.input.down("left"):
player.velocity[0] -= 0.5
Pressed
Use:
game.input.pressed("jump")
This is useful for actions that should happen once per press.
Example:
if game.input.pressed("jump"):
player.jump()
Mouse Input
Get mouse position:
mouse_x, mouse_y = game.input.mouse_pos()
Check whether a mouse button is held:
game.input.mouse_down(1)
Check whether it was pressed:
game.input.mouse_pressed(1)
Mouse button 1 is normally the left mouse button.
Tilemaps
Tilemaps let you build levels using characters.
Create a tilemap:
tilemap = Tilemap(
game,
50
)
The 50 means each tile is 50×50 pixels.
Defining Tiles
Define a solid tile:
tilemap.define_tile(
"#",
color=[80, 80, 80],
solid=True,
layer=0
)
Define another:
tilemap.define_tile(
"G",
color=[80, 180, 80],
solid=True,
layer=1
)
The character determines which tile gets created.
Loading a Tilemap
Example:
tilemap.load(
"""
########################
# #
# GGG #
# #
# P #
########################
"""
)
If # is defined as a tile, every # becomes that tile.
Tilemap Layers
Tiles can be assigned layers:
tilemap.define_tile(
"#",
color=[100, 100, 100],
solid=True,
layer=0
)
Higher layers can be used for visual ordering.
A possible design is:
Layer 0 → Ground
Layer 1 → Decoration
Layer 2 → Foreground
Spawn Points
Define a spawn character:
tilemap.define_spawn(
"P",
"player_spawn"
)
Load the map:
tilemap.load(
"""
########
# #
# P #
########
"""
)
Get the spawn:
spawn = tilemap.get_spawn(
"player_spawn"
)
Place the player:
player.position = spawn
Tilemap Collision
Add an entity to the tilemap's collision system:
tilemap.add_collision_entity(
player
)
Solid tiles can then interact with that entity.
Camera
The camera controls what part of the world is visible.
Create one:
camera = Camera(
game.window_w,
game.window_h
)
Make it follow the player:
camera.follow(
player
)
Attach it to the engine:
game.add_camera(
camera
)
The camera is useful for:
- Large levels
- Platformers
- Scrolling games
- Top-down games
- Following players
Rendering
The renderer is responsible for drawing the game world.
The general rendering order is:
Background
↓
Solids / Tilemap
↓
Entities
↓
Particles
↓
UI
↓
Debug information
This means UI and debug information can be displayed above the game world.
Components
Components let you attach custom systems/data to entities.
Create a component:
from engine.core.component import Component
class Health(Component):
def __init__(self, amount):
super().__init__()
self.health = amount
def damage(self, amount):
self.health -= amount
Add it:
player.add_component(
Health(100)
)
Get a component:
health = player.get_component(
Health
)
Check:
if player.has_component(Health):
print("Player has health")
Remove:
player.remove_component(
health
)
Components are useful for systems such as:
Health
Inventory
Weapons
AI
Stats
Dialogue
Abilities
Status effects
Scenes
Scenes allow different parts of a game to be separated.
Example:
from engine.scenes.scene import Scene
class Level1(Scene):
def start(self):
self.player = self.game.add_entity(
"player"
)
def update(self, dt):
pass
Register it:
game.scene.register(
"level1",
Level1(game)
)
Load it:
game.scene.load(
"level1"
)
Possible scenes:
Main Menu
Level 1
Level 2
Boss
Game Over
Credits
Scenes can track game objects created for them and clean them up when switching scenes.
UI
The engine contains a UI system for screen-space elements.
The UI manager can create:
Text
Panels
Buttons
Sliders
Text
Example:
game.ui.text(
"Hello World",
20,
20,
size=28
)
Another:
game.ui.text(
"A / D = Move",
20,
60,
size=20
)
Panels
Create a UI panel:
panel = game.ui.panel(
20,
20,
300,
200
)
Panels are useful for:
Menus
Inventory
Settings
HUD backgrounds
Dialogue boxes
Buttons
Create a button:
def clicked():
print("Button clicked!")
button = game.ui.button(
"Start Game",
100,
100,
200,
50,
clicked
)
Buttons can be used for:
Menus
Settings
Inventory
Pause screens
Level selection
Sliders
Create a slider:
slider = game.ui.slider(
100,
200,
300,
30
)
Sliders are useful for:
Volume
Brightness
Settings
Game values
Asset Manager
The asset manager handles loading and caching resources.
Access it with:
game.assets
Images
Load an image:
image = game.assets.image(
"assets/player.png"
)
Give it a custom name:
image = game.assets.image(
"assets/player.png",
name="player"
)
The engine caches loaded images so the same resource does not need to be loaded repeatedly.
Sounds
Load a sound:
sound = game.assets.sound(
"assets/jump.wav"
)
Fonts
Load a font:
font = game.assets.font(
"assets/font.ttf",
32
)
Asset Caching
The asset manager keeps loaded resources in memory.
This is useful because repeatedly loading the same file is inefficient.
You can clear the asset cache:
game.assets.clear()
Sound
The engine includes a sound manager.
Access it with:
game.sounds
Use the sound manager for game audio instead of creating a completely separate audio system for every object.
Typical uses include:
Jump sounds
Weapons
UI clicks
Explosions
Music
Environment sounds
Save and Load
The engine includes a JSON-based save system.
Save:
game.save(
"save1"
)
Load:
game.load(
"save1"
)
The engine can automatically save basic entity information such as:
Position
Velocity
Active state
You can also provide your own data:
game.save(
"save1",
{
"coins": 50,
"level": 3
}
)
Debug Mode
Debugging can be enabled with:
game.debug = True
Press:
F3
to toggle debugging during runtime.
The debug system can display information such as:
FPS
Entity count
Solid count
Hitbox count
Particle count
Camera information
Entity collision boxes
Solid collision boxes
Physics information
Velocity visualization
Debug mode is extremely useful when developing a game.
Complete Example
Here is a small complete platformer using the engine:
import pygame
from engine.engine import Engine
from engine.camera.camera import Camera
from engine.tilemap.tilemap import Tilemap
game = Engine()
game.input.bind(
"left",
pygame.K_a
)
game.input.bind(
"right",
pygame.K_d
)
game.input.bind(
"jump",
pygame.K_SPACE
)
player = game.add_entity(
"player"
)
player.position = [
100,
100
]
player.size = [
40,
40
]
player.color = [
255,
50,
50
]
player.collidable = True
player.set_gravity(
0.6
)
player.set_jump(
12
)
player.set_friction(
2,
0.2
)
player.set_max_speed(
7,
20
)
def player_update(
player,
keys
):
if game.input.down("left"):
player.velocity[0] -= 0.5
if game.input.down("right"):
player.velocity[0] += 0.5
if game.input.pressed("jump"):
player.jump()
player.set_update(
player_update
)
ground = game.add_solid(
0,
500,
1200,
50
)
ground.color = [
80,
80,
80
]
platform = game.add_one_way_platform(
300,
350,
200,
20
)
platform.color = [
80,
150,
255
]
moving = game.add_moving_platform(
600,
400,
150,
25,
velocity_x=50
)
moving.color = [
255,
170,
50
]
camera = Camera(
game.window_w,
game.window_h
)
camera.follow(
player
)
game.add_camera(
camera
)
game.ui.text(
"A / D = Move SPACE = Jump",
20,
20,
size=22
)
game.debug = True
game.run()
Recommended Game Structure
As your game becomes larger, don't put everything in main.py.
A recommended structure is:
my_game/
│
├── main.py
│
├── engine/
│
├── game/
│ ├── player.py
│ ├── enemies.py
│ ├── weapons.py
│ ├── levels.py
│ ├── items.py
│ └── game_manager.py
│
├── assets/
│ ├── images/
│ ├── sounds/
│ ├── music/
│ └── fonts/
│
└── saves/
For example:
from game.player import create_player
Then:
player = create_player(game)
This keeps your game organized.
Recommended Architecture
Try to keep the engine and game separate.
Engine
The engine should provide:
Physics
Rendering
Input
Collision
Camera
Scenes
UI
Particles
Audio
Assets
Saving
Game
Your game should provide:
Player
Enemies
Weapons
Levels
Story
Items
Rules
Game-specific mechanics
For example, the engine should not contain:
if player.has_tag("player"):
unless that is part of a generic engine system.
Instead, your game should decide what a player is.
Engine Architecture
The basic flow of the engine is:
Engine
│
┌──────────┼──────────┐
↓ ↓ ↓
Input Scene Assets
│ │
↓ ↓
Entities Game Objects
│
↓
Updater
│
├───────────────┐
↓ ↓
Physics Components
│
↓
Collision
│
↓
Camera
│
↓
Renderer
│
├── Tilemap
├── Entities
└── Solids
│
↓
Particles
↓
UI
↓
Debug
↓
Screen
Game Loop
The engine continuously performs roughly this process:
Start
↓
Read events
↓
Update input
↓
Update moving solids
↓
Update entities
↓
Apply physics
↓
Resolve collisions
↓
Update hitboxes
↓
Update particles
↓
Update scenes
↓
Update UI
↓
Update camera
↓
Render world
↓
Render particles
↓
Render UI
↓
Render debug information
↓
Display frame
↓
Repeat
This happens every frame while:
game.running
is true.
Getting Started With Your Own Game
A good development order is:
Step 1 — Create the engine
game = Engine()
Step 2 — Create your player
player = game.add_entity(
"player"
)
Step 3 — Add movement
player.set_update(
player_update
)
Step 4 — Add physics
player.set_gravity(
0.6
)
Step 5 — Add level geometry
game.add_solid(
0,
500,
1000,
50
)
Step 6 — Add camera
camera.follow(
player
)
Step 7 — Add graphics
player.set_sprite(
"assets/player.png"
)
Step 8 — Add game mechanics
Use:
Components
Hitboxes
Particles
Animations
Scenes
Step 9 — Add UI
Create:
Health bar
Score
Menus
Buttons
Step 10 — Enable debugging
game.debug = True
Common Mistakes
1. Forgetting to enable collision
This:
player = game.add_entity("player")
doesn't automatically make the entity collide.
Use:
player.collidable = True
2. Forgetting gravity
If your player doesn't fall:
player.set_gravity(
0.6
)
3. Forgetting to set an update function
If you expect custom movement, make sure you have:
player.set_update(
player_update
)
4. Using excessive friction
If your player barely moves or stops instantly:
player.set_friction(
2,
0.2
)
is generally more responsive than:
player.set_friction(
8,
1
)
5. Forgetting the camera
Create and attach it:
camera = Camera(
game.window_w,
game.window_h
)
camera.follow(player)
game.add_camera(camera)
6. Forgetting to start the engine
Your program needs:
game.run()
Performance Tips
Don't create expensive resources every frame.
Avoid:
def update(player, keys):
image = pygame.image.load(
"player.png"
)
Instead, load assets once.
Use the asset manager:
image = game.assets.image(
"player.png"
)
Debugging Your Game
When something doesn't work:
First enable:
game.debug = True
Then press:
F3
Check:
FPS
Entity count
Collision boxes
Hitboxes
Physics
Camera
If Python gives you a traceback, look at the last line first.
For example:
AttributeError:
'Player' object has no attribute 'something'
usually means the code is trying to use a property or method that doesn't exist.
Current Limitations
This engine is designed to be lightweight and beginner-friendly. It is not currently intended to replace full commercial engines such as Unity or Godot.
Some advanced features may require implementation in future versions.
Current areas that can be improved include:
- Advanced slope collision
- Continuous collision detection
- Spatial partitioning for extremely large numbers of objects
- More advanced tilemap optimization
- More advanced animation systems
- Advanced audio management
- A visual level editor
- Prefab systems
- More sophisticated particle simulation
- Advanced rendering effects
- Networking/multiplayer
- 3D rendering
The engine is primarily designed for 2D games.
FAQ
Is this a 3D engine?
No.
It is a 2D engine built using Pygame.
Do I need to know Pygame?
Basic Pygame knowledge helps, but the engine hides many common Pygame tasks.
You can mostly work with:
game
player
platform
camera
scene
tilemap
instead of directly managing the entire Pygame game loop yourself.
Can I make a platformer?
Yes.
The engine provides:
- Gravity
- Jumping
- Collision
- One-way platforms
- Moving platforms
- Camera
- Tilemaps
- Particles
- Animations
- Hitboxes
Can I make a top-down game?
Yes.
You can disable gravity:
player.gravity_enabled = False
and implement top-down movement.
Can I make a shooter?
Yes.
Entities, hitboxes, particles, input, components and collision can be used to build weapons and projectiles.
Can I make a Geometry Dash-style game?
Yes.
The engine can provide many of the underlying systems needed for a rhythm-platformer, including:
Automatic movement
Collision
Gravity
Platforms
Triggers
Particles
Camera
Animations
Tilemaps
The actual game mechanics should be implemented by your game.
Can I make menus?
Yes.
Use the UI system:
Text
Panels
Buttons
Sliders
and scenes for different screens.
Can I save games?
Yes.
Use:
game.save("save1")
and:
game.load("save1")
Minimal Template
For a new game, this is a good starting point:
import pygame
from engine.engine import Engine
from engine.camera.camera import Camera
game = Engine()
game.input.bind(
"left",
pygame.K_a
)
game.input.bind(
"right",
pygame.K_d
)
game.input.bind(
"jump",
pygame.K_SPACE
)
player = game.add_entity(
"player"
)
player.position = [
100,
100
]
player.size = [
40,
40
]
player.color = [
255,
50,
50
]
player.collidable = True
player.set_gravity(
0.6
)
player.set_jump(
12
)
player.set_friction(
2,
0.2
)
player.set_max_speed(
7,
20
)
def player_update(
player,
keys
):
if game.input.down("left"):
player.velocity[0] -= 0.5
if game.input.down("right"):
player.velocity[0] += 0.5
if game.input.pressed("jump"):
player.jump()
player.set_update(
player_update
)
game.add_solid(
0,
500,
1200,
50
)
camera = Camera(
game.window_w,
game.window_h
)
camera.follow(
player
)
game.add_camera(
camera
)
game.run()
Final Notes
My 2D Engine is built around one main idea:
The engine provides the systems. Your game provides the rules.
You should be able to create a game without rewriting the engine every time.
For example:
ENGINE
│
├── Physics
├── Collision
├── Rendering
├── Input
├── Camera
├── Tilemaps
├── Particles
├── Audio
├── UI
├── Scenes
├── Components
└── Saving
│
↓
YOUR GAME
│
├── Player
├── Enemies
├── Levels
├── Weapons
├── Items
├── Game rules
└── Story
Build the engine once.
Then use it to build many different games.
License
Add your chosen license here before publicly distributing the engine.
For example:
MIT License
or another license appropriate for your project.
My 2D Engine
Python + Pygame
A lightweight, beginner-friendly foundation for creating 2D games.
Metadata
Release files for sypy-engine-beginner 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sypy_engine_beginner-0.1.1.tar.gz | 36.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sypy_engine_beginner-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 66.6 kB
Release files / sypy_engine_beginner-0.1.1.tar.gz
| Download URL | sypy_engine_beginner-0.1.1.tar.gz |
|---|---|
| Size | 36.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7d2015d70ae78c3ba73744f602108df6fa287ca44d37f7190227971811584611
|
|
BLAKE2b-256 checksum How to use checksums |
5e565878444bfa7c5dc1cda5afc6f81577750f23a59a6c5dda2798791b0b553b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / sypy_engine_beginner-0.1.1-py3-none-any.whl
| Download URL | sypy_engine_beginner-0.1.1-py3-none-any.whl |
|---|---|
| Size | 30.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d12391081563dbcfa5aaea05d4acc7d9af8a288549ae45f6942f82b982d5a44e
|
|
BLAKE2b-256 checksum How to use checksums |
8903fc0793f07a6302564a6f81654b878233ef8728cd815c051cd676ede0d415
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|