The format is based on Keep a Changelog, and this project adheres to Semantic Versioning when possible.
[1.7.3] - TBA
Added
tilemap.Mapconstructor now accepts an optional path to load on creation.- Camera rotation is now supported by modifying its
transform.angleproperty. - Added two camera move helpers:
move_worldandmove_screen. - Added
storage_buffer_sizestoShaderconstructor. - New
Shader.set_storage_buffer_datamethod for uploading data to a storage buffer binding.
Changed
- Instead of the highly confusing camera
world_posandlocal_posproperties, position has been moved to atransformproperty.
Fixed
- Improved UI context management.
- Improved Texture move semantics.
- Fixed segfault relating to shaders by correcting backend move semantics.
- Fixed bug with
mouse.is_pressedfunction where left clicks counted as both left and right clicks.
[1.7.2] - 2026-04-20
Added
- New
shaders.Samplerclass. - New
WrapModeenum for shader sampler addressing modes. - New
TextureUsageflag enum for specifying how a texture is intended to be used. Textureread-only.usageproperty for checking a texture’s usage flags and.has_usage(usage)helper method for checking specific usage flags.camera.get_active_angle()function for getting the angle of the active camera.- Tilemap
drawAPIs now accept optionalangleandpivotparameters. - Added
angleproperty to theCameraclass. - New
Shader.set_texture_samplermethod for sampling multiple textures in a binded shader. logsubmodule now has explicitenableanddisablefunctions.- More cli tools:
initfor quickstarting a pykraken projectdocsfor opening the documentation in the default web browser.
Polygon.set_centroidmethod for setting an exact position of a polygon.
Changed
- All
Textureconstructors now useFilterModeand have an additionalusageparameter. PixelArrayconstructor accepting aVec2size parameter changed to accept separatewidthandheightinteger parameters for type safety.- Camera API was refactored to explicit world/local semantics (
world_pos,local_pos) with new local/world movement helpers. renderer.draw(texture, dst)now supports optionalangleandpivotparameters for screen-space rectangle drawing.renderer.set_default_scale_mode/renderer.get_default_scale_moderenamed torenderer.set_default_filter_mode/renderer.get_default_filter_mode.- Shader creation now uses the
Shaderconstructor directly rather than a factory function. - Renamed
TextureScaleModetoFilterModefor ambiguity with the shader API. - UI drawing is now unaffected by any active world camera.
- “kraken-clean” font renamed to “kraken-modern”
Polygonrotation and scaling methods use its centroid now instead of a specified pivot point.
Removed
- Removed
pykraken.shader_uniformhelper module and itsShaderUniformclass in favor of native buffer-like data. - Removed
Cameraconstructor asking for a default position as they’d be ambiguous.
Fixed
- Fixed tilemap tileset GID range handling by avoiding TMXLite
getLastGID()for tileset bounds resolution. - Fixed shader baker error handling for failed SPIR-V/MSL compilation.
- A lot of UI stuff now has docstrings.
[1.7.1] - 2026-04-15
Added
- New
renderer.draw_9slicefunction for drawing 9-slice textures. - New
uisubmodule for designing and rendering user interfaces:Directionenum for specifying layout direction.Alignenum for specifying alignment within containers.Styleclass for defining reusable style properties.root,stack,row, andcolumncontainer functions for structuring UI elements.button,label, andimagefunctions for common UI elements.
- Physics
Worldclass now has adebug_drawmethod with extra configurable options for visualizing physics bodies and joints. - New
Polygonconstructor for creating regular polygons by specifying the number of sides and radius. - Added
restartmethod to theTimerclass for resetting and starting the timer in one call. Tweenhas a newcurrent_posread-only property for getting the current interpolated position.fx.Effectclass now has aclonemethod for creating a copy of an effect with the same properties.- The
pykrakenpackage now comes with a cli tool for:- Building exe files from Python scripts (with PyInstaller as a dependency).
- Baking HLSL scripts into SPV, MSL, and DXIL shaders.
renderersubmodule now has aset_render_backendfunction for manually setting the rendering backend instead of relying on automatic selection.- New
RenderBackendenum for specifying rendering backends. camera.unset()function for unsetting the active camera.- New
fx.scale_byfunction for scaling an effect by a factor instead of to a specific size. - New
gamepad.get_typefunction for getting the type of a connected gamepad. - Loading a shader moved from
Shaderconstructor to a newshaders.loadfunction that returns aShaderobject.
Changed
- Renamed
Alignenum toTextAlignfor specificity. - Physics
Worldconstructor’s gravity parameter is now optional and defaults to zero gravity. fx.Effectobjects are now stateful, single-use objects to be consumed by anOrchestratortimeline, rather than reusable templates.- Rename
ShaderStateclass toShaderfor simplicity. Orchestratorconstructor only acceptsTransformobjects now.fx.scale_tofunction’sscaleproperty enforces theVec2type for type safety.
Removed
- Physics
Bodytypes no longer have adebug_drawmethod. Tweenclass no longer has astepmethod as timing is handled by the engine.
Fixed
Orchestratorobjects were copied upon callingparallelandthenmethods, causing effects to not be added to the original orchestrator timeline. Now returns reference to the original orchestrator.- Some images wouldn’t render when drawn while a shader was binded. This was due to unpredictable pixel formats when loading images that shaders didn’t like. Solved by forcing an RGBA32 format on all loaded images.
- PyInstaller builds were broken since moving to Nanobind due to different naming conventions. They’ve been fixed and tested to work again.
- Fixed bug with tilemaps regarding tile id’s not being mapped correctly to their tileset, causing wrong tiles to be drawn.
- Isometric, hexagonal, and staggered maps render correctly now.
- Tile rotation and flipping bug fixed.
- Fixed colorkeyed PixelArray → Texture sometimes not retaining the colorkey transparency.
[1.7.0] - 2026-04-07
Added
- New
diameterand edge position properties for theCircleclass;left,right,top, andbottom. - More
Linemethods:movedfor non-mutating version ofmove.get_midpointfor the line’s midpoint.get_perpendicularfor a line’s perpendicular bisector.get_anglefor the line’s angle in radians.get_closest_pointfor finding the closest point on the line to a given point.
- More
Polygonmethods:rotatedfor non-mutating version ofrotate.scaled_byfor non-mutating version ofscale_by.
- More
Rectmethods and properties:posproperty as a clearer alias fortop_left.movedfor non-mutating version ofmove.clampedfor a non-mutating version ofclamp.scaled_byfor non-mutating version ofscale_by.scaled_tofor non-mutating version ofscale_to.get_cornersfor getting the positions of all four corners as a list ofVec2objects.get_edgesfor getting the edges of the rectangle as a list ofLineobjects.
- New
rendererfunctions for more advanced configuration:unset_virtual_resolution()for unsetting a previously set virtual resolution and returning to using the actual render target resolution.get_virtual_resolution()for getting the currently set virtual resolution.get_output_resolution()for getting the actual output resolution of the renderer.
Changed
Polygon’stransformmethod renamed tomoveandscalemethods renamed toscale_byfor consistency with other shapes.renderersubmodule’sset_present_resolutionfunction renamed toset_virtual_resolutionfor clarity.on_floor,on_ceiling, andon_wallproperties ofCharacterBodychanged from read-only properties to regular methods:is_on_floor(),is_on_ceiling(), andis_on_wall().
Removed
lineandrectsubmodules removed in favor of non-mutating methods in theLineandRectclasses.
[1.6.5] - 2026-03-31
Added
- New
renderer.Batcherclass for batch draw memory preallocation and management. - When
debugmode is enabled, the engine now attempts to provide more detailed error messages and stack traces for segfaults using thefaulthandlermodule. - Log warning about excessive texture swapping in a single frame when using Direct3D 12.
- The list-based
renderer.draw_batchfunction now accepts an optional list ofRectobjects for per-instance clipping. - About the ndarray-based
renderer.draw_batchfunction:- 9-column arrays now accepted for per-instance clipping (x, y, width, height).
- Optional
Batcherparameter for using preallocated memory for batch drawing, significantly improving performance. - Manually batch draw all transformed textures instead of relying on SDL’s backend, improving performance.
Changed
- Vulkan is now the default rendering backend on all platforms, falling back to the system’s default graphics API if Vulkan is not supported.
- Functions with parameters for file or directory paths now accept
PathLikeobjects in addition to strings for improved flexibility and type safety.
Fixed
- When drawing multiple different textures excessively within a single frame (swapping) on Windows, the engine would segfault likely due to descriptor heap exhaustion on Direct3D 12. The engine now uses Vulkan on Windows by default, if available, which in turn also improves performance.
- MP3 files were not loading due to a missing decoder in the backend. Fix should also encompass FLAC and OGG files.
[1.6.4] - 2026-03-23
Added
CharacterBodyadditions:MotionModeenum (GROUNDED,FLOATING) and correspondingmotion_modeproperty.- Movement properties:
max_speed,acceleration,friction,stop_speed, andair_steer. - Collision state properties:
on_floor,on_ceiling, andon_wall. - Shape property:
capsule_shape.
- Math & Vectors:
math.move_toward(current, target, max_delta)function.Vec2: Added in-place rounding methods (floor,ceil,round) and surface sliding methods (slide,slid).
Changed
MapandPixelArrayset_at/get_atmethods now require two integers (x, y) instead of aVec2for improved type safety.
Fixed
- Passing an empty rect to
renderer.read_pixelsnow correctly reads the entire render target instead of crashing. CharacterBody.move_and_slidenow uses Box2D’s Mover API, utilizing a geometric solver to eliminate snagging on floor seams and provide smoother sliding along complex surfaces.Event.typenow returns anEventTypeenum type instead of an integer (for built-in event types; user events still return integers).
Removed
CharacterBodyremovals:floor_max_angleandfloor_snap_distanceproperties.is_on_floor(),is_on_ceiling(), andis_on_wall()methods (replaced by the new properties mentioned in “Added”).
[1.6.3] - 2026-03-17
Fixed
- Tilemap objects with polygon shapes were not being transformed to their correct world positions, causing them to render and collide in the wrong place.
[1.6.2] - 2026-03-17
Added
- New
Vec2non-mutating methods:.floored(),.ceiled(), and.rounded()for coordinate manipulation. Rectconstructor for accepting only aVec2size parameter.- New
draw_batchfunction for efficiently drawing a texture with many varying transforms.- Comes with an override for passing an ndarray of transforms for even faster drawing - good for particle sims.
Texture.get_rect()method for getting the dimensions of a texture as aRectobject.- Debug info messages now show GPU driver information.
- Some more pytest scripts for important functions and objects.
- New
renderer.set_present_resolutionfunction for setting the resolution at which the final rendered image is presented to the screen. math.DEG2RADandmath.RAD2DEGconstants for converting between degrees and radians.- Added optional
handle_closeparameter towindow.createfor whether the window should handle the window quit event and close itself, or leave it to the user to handle.
Changed
- Migrated the Python binding layer from
pybind11tonanobindfor improved performance and smaller binary sizes.- In my testing, migrating the same engine API from pybind11 to nanobind increased transform-heavy sprite throughput by about 8–9× under the same Python script and workload.
- Wheels now build against the Python 3.12 stable ABI, allowing a single binary to work across future Python versions.
- Renamed
EasingAnimationclass toTweento follow common terminology. renderer.get_target_resolutionfunction renamed torenderer.get_current_resolutionfor clarity.
Removed
math.to_deg()andmath.to_rad()functions have been removed in favor ofmath.DEG2RADandmath.RAD2DEGconstants for conversion.- Removed lesser used
renderer.clearfunction that accepted 4 separate color components.
Fixed
input.get_direction()no longer stacks redundant bindings on the same axis, which caused biased directions after normalization. It also now preserves partial analog stick deflection instead of always normalizing to a unit vector.input.get_axis()no longer double-negates analog values for negative-direction bindings.input.is_pressed(),input.is_just_pressed(), andinput.is_just_released()now respect the gamepad slot specified in eachInputAction.- A lot of physics bindings didn’t have docstrings, now they do.
Color.hexproperty getter was writing raw int bytes instead of hex-formatted integers, producing invalid UTF-8 strings.logsubmodule functions were still logging even when disabled.
[1.6.1] - 2026-02-15
Added
- New
mixersubmodule for advanced audio management. AudioPriorityenum for managing hardware track acquisition (MUSIC, UI, SFX).- Support for polyphonic sound effects via the
Sampleclass andmax_polyphonyattribute. - Priority-based track stealing: high-priority sounds can now interrupt lower-priority ones if the 64-track limit is reached.
- Global master volume control via
mixer.set_master_volume. draw.ellipsesanddraw.linesfunctions for drawing multiple ellipses or lines in a single call.- Added
is_convexandis_concavemethods to thePolygonclass for checking polygon convexity. - Added
Circledefault constructor and another accepting just a radius. - New
physicssubmodule with aWorldclass, bodies, and joints for basic 2D physics simulation.Bodyabstract class for physics bodies:RigidBodyfor simulating solid objects with mass, velocity, and forces.CharacterBodyfor simulating character-like movement with floor detection and snapping.StaticBodyfor immovable objects that can still collide with other bodies.
Jointabstract class for the following joint types:DistanceJointfor maintaining a fixed distance between two bodies.FilterJointfor filtering collisions between two bodies.MotorJointfor applying a motor force to maintain a relative position between two bodies.PrismaticJointfor allowing relative movement along a specified axis between two bodies.RevoluteJointfor allowing relative rotation between two bodies.MouseJointfor dragging a body with the mouse cursor.WeldJointfor rigidly connecting two bodies together.WheelJointfor allowing relative rotation and translation along a specified axis between two bodies.
Collisionclass for representing collision information between two bodies. Provided viaWorld.get_collisions()method.CastHitclass for representing the result of a ray or shape cast in the physics world.- Added
Capsuleshape class for physics bodies, defined by a line segment and a radius. - Added
draw.capsuleanddraw.capsulesfunctions for drawing capsules. get/set_fixed_deltaandget/set_max_substepsfunctions for managing physics stepping parameters.add_fixed_updateandclear_fixed_updatesfunctions andfixed_callbackdecorator for registering functions to be called at a fixed interval during the automatic physics update loop.- Add
Map.tile_layers,Map.object_groups, andMap.image_layersproperties for easier access to specific layer types. - Add
Map.get_layer(name)method for retrieving a layer by name. - Add
World.from_map_layer(world, layer)method for creating physics bodies from a tilemap layer. Vec2can be divided by anotherVec2element-wise using the/operator.- New
draw.bezieranddraw.sectorfunctions for drawing Bezier curves and circular sectors. - Added
draw.polylinefor drawing connected line segments. world_to_screenandscreen_to_worldfunctions/methods for converting between world and screen coordinates.camera.get_active_posfunction for getting the position of the currently active camera.
Changed
- Refactored the audio backend to use SDL3_mixer.
- Renamed
Audioclass toSample(for short sound effects). - Renamed
AudioStreamclass toStream(for long music files).
- Renamed
- Audio loading functions moved to
mixer.load_sampleandmixer.load_stream. Stream.loopingis now an RW property instead of just a setter method.Streamplayback position renamed fromcurrent_timetoplayback_pos.- Circle drawing (and now ellipses) default segment count reduced from 36 to 24.
- Line drawing thickness can now be a float.
- Rename
Map.layerstoMap.all_layers Textureconstructor involving aVec2size parameter changed to accept separatewidthandheightinteger parameters for type safety.AnimationController.add_sheetmethodVec2frame size parameter changed to separateframe_widthandframe_heightinteger parameters for type safety.draw.rectanddraw.rectsfunctions now have parameters for corner radii.
Fixed
- Fixed a bug where textures wouldn’t render at all (hopefully). Likely related to the internal SDL2->SDL3 transition.
Removed
- Removed
rewindmethod from audio stream class (useseek(0)or restart playback). - Removed
miniaudiodependency. - Removed
SGL_gfxdependency. - Due to the new CharacterBody class, I’ve decided to remove the
Spriteclass as it become redundant.
[1.6.0] - 2026-01-29
Added
- Added
Vec2.ZERO,Vec2.UP,Vec2.DOWN,Vec2.LEFT, andVec2.RIGHTconstants for common vector directions. - Added the ability to multiply two
Vec2objects element-wise using the*operator. - New
transformsubmodule withcomposeandcompose_chainfunctions for parenting transforms. - New
draw.circlesfunction for drawing multiple circles in a single call (~3.5x faster than multipledraw.circlecalls in testing). - New
draw.polygonsfunction for drawing multiple polygons in a single call. - Added
texture.clip_areaproperty for getting/setting the texture’s clipping area. - Added
draw.geometryfunction for drawing arbitrary vertex geometry, optionally with a texture. - New
Vertexclass representing a single vertex with position, color, and texture coordinate attributes.
Changed
Vec2boolean conversion now checks for both components being exactly zero, rather than using a tolerance.fx.move_tofunction now requires aVec2for theposparameter instead of accepting an optional argument of any object type.- Greatly improved quality and performance of
draw.circleanddraw.polygonby switching to a GPU-based rendering approach. - Animation controller’s
load_sprite_sheetmethod renamed toadd_sheetandclipproperty renamed toframe_area. renderer.drawfunction now accepts optionalanchorandpivotparameters for specifying the drawing anchor and pivot points, both ofVec2type.- Both text and pixel array drawing functions now accept an optional
anchorparameter ofVec2type for specifying the drawing anchor point. Anchorenum changed to a class with static constants for common anchor points represented asVec2objects.- Renamed tilemap layer
rendermethods todrawfor consistency with other drawing functions.
Removed
- Implicit conversians from sequences to
Vec2,Rect,Line,Color, andPolarCoordinatehave been removed for better type safety. Use explicit constructors instead. - Removed
srcparameter fromrenderer.drawfunction. - Removed
clipattribute fromSpriteclass. Transformclass no longer containspivot,size, oranchorattributes.- Removed most opaque list types except for tilemap related ones due to… uselessness.