ggez v0.8.0 Release Notes

  • The biggest change in this version is the long awaited redo of our graphics stack, which used to be based on gfx-rs ๐Ÿ›  and is now using wgpu. This gives us more reliability going into the future and fixes many bugs, albeit costing us some portability to low-level hardware (looking at you Pi 3; EDIT: and... Pi 4 as well? o_o ).

    Credit goes out to our wonderful contributors, with special thanks to @jazzfool and @aleokdev, for putting so much work and patience into the graphics stack.

    As there are too many changes to simply list them in the usual fashion, let's look at them topic by topic:

    ๐Ÿ”„ Changes in the graphics API

    With the redo of the graphics stack some parts of the API changes with it, most notably canvases and the shader API.


    First of all, each draw call is now explicitly bound to a Canvas. This means instead of "setting" the active canvas and then drawing implicitly on that canvas you now call canvas.draw(...) or drawable.draw(canvas, ...). And then, once you're done drawing on it, you call canvas.finish(ctx). This helps to keep track of the active canvas and gives you more explicit renderpasses to work with, as Canvas is now no longer a special image that you can draw to, but a wrapped wgpu renderpass, operating naturally on whatever image you pass it, or on the screen buffer itself.

    The downside of this is that it's a bit more verbose and that you have to pass around your canvas to be able to draw.


    There's a new struct ShaderParamsallowing you to pass images, samplers and uniforms to shaders. Both ShaderParams and Shaders are now set per Canvas (as well as blend modes and projection matrices).

    Shaders and ShaderParams are created through ShaderBuilder and ShaderParamBuilder respectively, allowing you to only set the parameters you're interested in, without worrying about the rest.

    Uniforms are now no longer created using the gfx! macro. No need to include gfx-rs in your own project, just to be ๐Ÿ‘€ able to create shader uniforms. Now, simply deriving AsStd140 is all you usually need (see the shader examples). At the time of writing you're sadly also required to depend on crevice 0.11 directly, as AsStd140 needs to have it ๐Ÿ‘€ visible globally (and re-exporting it on our side doesn't seem to be enough). If you know a way around this, let us know!


    SpriteBatch and MeshBatch have been replaced by InstanceArray, a more generic "batch" that also features internal z-ordering.


    Before, the order of draws had been determined solely by order of execution. Now DrawParam features an additional field z, to give you control over the order in which draw calls are placed. This works on the global level, but also inside of InstanceArray, when requested.


    ๐Ÿ‘€ Another field that has seen a bit of love is the modularization of contexts. Sub-contexts are now public and can be borrowed and handed around freely. Most module functions used to require Context as a whole. These have, for this reason, now been ๐Ÿ—„ deprecated and directly replaced by methods on the sub-contexts.

    In situations where multiple sub-contexts are needed (one is the creation of audio sources and one the creation of images โ†ช from paths) you can pass the necessary sub-contexts, or instead just pass Context as a whole, just like before, thanks to a little trait-workaround.

    The latter applies to all situations in which you'd need one specific sub-context as well. If you, for some reason, needed or wanted to split the context, then you can pass only the required sub-context. If you didn't split it then you can comfortably hand around and pass the context as a whole, like before.

    โž• Added

    • โž• Added touch event to EventHandler
    • โž• Added access to scancodes in both keyboard events and keyboard context methods, allowing you to make your game portable across the different keyboard letter layouts of different countries
    • Added Canvas::set_scissor_rect allowing you to restrict drawing to a part of your surface
    • Added is_key_just_pressed and is_key_just_released to keyboard context
    • โž• Added an option for transparent windows
    • โž• Added the ability to build your own BlendModes built from the components offered through wgpu's BlendComponent struct
    • ๐Ÿ”ฆ Exposed rodio API for skipping the first part of a sample
    • โž• Added audio and gamepad as crate features, allowing you to disable them if not necessary
    • โž• Added the zip-compression feature (as part of the default features), now allowing the use of zip-files with compression
    • โž• Added Rect::overlaps_circle
    • โž• Added Context::request_quit as a replacement for event::quit
      • Context::request_quit works like event::quit did before, except that instead of directly breaking the game loop it now triggers a quit_event, which allows you to handle all attempts to quit the game in one place.
    • โž• Added a re-export for glam, as ggez is aimed at beginners for whom it's convenient to just have it at hand directly; most people will want/need to use it anyway
    • โž• Added logical_size as optional argument in WindowMode which overrides width/height with a LogicalSize which supports high DPI systems.

    ๐Ÿ”„ Changed

    The following list doesn't repeat the changes already mentioned above.

    • ๐Ÿ˜Œ Relaxed the error type of EventHandler from std::error::Error into std::fmt::Debug, allowing you to use things like anyhow::error as error types as well
    • Made offset on Text relative (I know, I know, we've been changing this around a lot lately, but I hope we're finally done now), as it makes things like centering text on positions easier (see the blend modes example)
    • Also Text is now a first class citizen and can be drawn normally with DrawParam, implementing things like rotation that weren't possible in batched text rendering before
    • ๐Ÿ”„ Changed how bounds on Text work as well as layouting
      • Text::set_bounds now expects width and height of the bounds, but not the destination point, as that's handled through the DrawParam
      • additionally to horizontal alignment vertical alignment is now possible as well
    • ๐Ÿ‘Œ Improved Text performance through better glyph re-use
    • ๐Ÿ”„ Changed the Drawable trait; this will downstream require changes in projects like ggez-egui
    • ๐Ÿ”– Version bumped zip to 0.6, directories to 4.0.1, winit to 0.27.3, image to 0.24 and rodio to 0.16
    • As each Canvas now keeps track of its own projection matrix the screen_coordinates of each Canvas now start out with the same dimensions as the Canvas surface

    ๐Ÿ—„ Deprecated

    • Most of the module level functions, which have been replaced by sub-context methods

    โœ‚ Removed

    • Removed duration_to_f64 and f64_to_duration as the std library now already contains this functionality itself
    • โœ‚ Removed From<tuple> implementations for DrawParam, as they're non-transparent and weird
    • โœ‚ Removed event::quit, as it was replaced by Context::request_quit
    • โœ‚ Removed the ability to update only parts of the DrawParams inside a MeshBatch (now InstanceArray)
      • If you want that ability back let us know! Atm it's staged as "maybe in 0.8.1"

    ๐Ÿ›  Fixed

    ๐Ÿ›  Many graphics bugs that were caused by the use of the discontinued gfx-rs were fixed by the switch to wgpu. The following list is very probably not complete.

    • โ†ช Multisampling on canvases is now no longer based on dirty workarounds, but on the inner workings of wgpu, supporting it naturally
    • ๐Ÿ›  Fixed zip read_dir not working deeper than one level on Windows
    • Fixed a memory leak on set_screen_coordinates on Windows 11
    • ๐Ÿ›  Fixed not being able to take screenshots of anti-aliased targets