Pixel-Perfect, 2D Renderer for Bevy that Seamlessly Targets Desktop and Web

Overview

bevy_retro

Crates.io Docs.rs lines of code Katharos License

( Screenshot of Bounty Bros. game made with Bevy Retro and Skip'n Go )

bounty bros game screenshot

Bevy Retro is a 2D, pixel-perfect renderer for Bevy that can target both web and desktop using OpenGL/WebGL.

Bevy Retro is focused on providing an easy and ergonomic way to write 2D, pixel-perfect games. Compared to the out-of-the-box Bevy setup, it has no concept of 3D, and sprites don't even have rotations, scales, or floating point positions. All coordinates are based on real pixel positions.

Bevy Retro replaces almost all of the out-of-the-box Bevy components and Bundles that you would normally use ( Transform, Camera2DBundle, etc. ) and comes with its own Position, Camera, Image, Sprite, etc. components and bundles. Bevy Retro tries to provide a focused 2D-centric experience on top of Bevy that helps take out some of the pitfalls and makes it easier to think about your game when all you need is 2D.

We want to provide a batteries included plugin that comes with everything you need to make a 2D pixel game with Bevy, and over time we will be adding features other than rendering such as sound playing, data saving, etc. While adding these features we will try to maintain full web compatibility, but it can't be guaranteed that all features will be feasible to implement for web.

These extra features will be included as optional cargo featurs that can be disabled if not needed and, where applicable, be packaged a separate Rust crates that can be used even if you don't want to use the rest of Bevy Retro.

License

Bevy Retro LDtk is licensed under the Katharos License which places certain restrictions on what you are allowed to use it for. Please read and understand the terms before using Bevy Retro for your project.

Development Status

Bevy Retro is in very early stages of development, but should still be somewhat usable. Potentially drastic breaking changes are a large possibility, though. Bevy Retro's design will mature as we use it to work on an actual game and we find out what works and what doesn't.

Bevy Retro will most likely track Bevy master as it changes, but we may also be able to make Bevy Retro releases for each Bevy release.

Features

  • Supports web and desktop out-of-the-box
  • Integer pixel coordinates
  • Supports sprites and sprite sheets
  • A super-simple hierarchy system
  • Scaled pixel-perfect rendering with three camera modes: fixed width, fixed height, and letter-boxed
  • An LDtk map loading plugin
  • Pixel-perfect collision detection
  • Custom shaders for post-processing, including a built-in CRT shader
  • Render hooks allowing you to drop down into raw Luminance calls for custom rendering

Examples

Check out the examples folder for more examples, but here's a quick look at using Bevy Retro:

use bevy::prelude::*;
use bevy_retro::*;

fn main() {
    App::build()
        .add_plugins(RetroPlugins)
        .add_startup_system(setup.system())
        .run();
}

struct Player;

fn setup(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    mut scene_graph: ResMut<SceneGraph>,
) {
    // Load our sprites
    let red_radish_image = asset_server.load("redRadish.png");
    let yellow_radish_image = asset_server.load("yellowRadish.png");
    let blue_radish_image = asset_server.load("blueRadish.png");

    // Spawn the camera
    commands.spawn().insert_bundle(CameraBundle {
        camera: Camera {
            // Set our camera to have a fixed height and an auto-resized width
            size: CameraSize::FixedHeight(100),
            background_color: Color::new(0.2, 0.2, 0.2, 1.0),
            ..Default::default()
        },
        position: Position::new(0, 0, 0),
        ..Default::default()
    });

    // Spawn a red radish
    let red_radish = commands
        .spawn()
        .insert_bundle(SpriteBundle {
            image: red_radish_image,
            position: Position::new(0, 0, 0),
            sprite: Sprite {
                flip_x: true,
                flip_y: false,
                ..Default::default()
            },
            ..Default::default()
        })
        // Add our player marker component so we can move it
        .insert(Player)
        .id();

    // Spawn a yellow radish
    let yellow_radish = commands
        .spawn()
        .insert_bundle(SpriteBundle {
            image: yellow_radish_image,
            position: Position::new(-20, 0, 0),
            sprite: Sprite {
                flip_x: true,
                flip_y: false,
                ..Default::default()
            },
            ..Default::default()
        })
        .id();

    // Make the yellow radish a child of the red radish
    scene_graph
        .add_child(red_radish, yellow_radish)
        // This could fail if the child is an ancestor of the parent
        .unwrap();

    // Spawn a blue radish
    commands.spawn().insert_bundle(SpriteBundle {
        image: blue_radish_image,
        // Set the blue radish back a layer so that he shows up under the other two
        position: Position::new(-20, -20, -1),
        sprite: Sprite {
            flip_x: true,
            flip_y: false,
            ..Default::default()
        },
        ..Default::default()
    });
}

Running Examples

We use the just for automating our development tasks and the project justfile includes tasks for running the examples for web or native:

# Run native example
just run-example audio # or any other example name

# Run web example
just run-example-web collisions

When running the web examples it will try to use basic-http-server to host the example on port http://localhost:4000. You can install basic-http-server or you can modify the justfile to use whatever your favorite development http server is.

Comments
  • πŸ—’ Licensing

    πŸ—’ Licensing

    I noticed there was no LICENSE.md on this repo, which makes it very challenging for others to build off of safely.

    This work looks incredible, and I (among many others) would love to be able to use it, contribute to it, promote it and so on. To do so though, it needs a reasonably standard open source license.

    The Katharos license used on your other projects, independent of any planned uses or ethical / religious disagreements, is a complete deal breaker for every interested user I've talked to :( It induces very complex legal risk due to challenges in definition and lack of case law, and even incorporating a library with the license presents a serious barrier to getting downstream users and contributors who may disagree with certain ethical or religious implications contained within the license.

    Promoting good in the world and staying true to your beliefs is the right thing to do, and I admire your devotion to what you believe in. I'm just not convinced that ethical open source licenses are a good tool to get there.

    The intent behind them is twofold:

    1. Prevent your work from being used for objectionable purposes.
    2. Allow others who share your goals to benefit from your work.

    But in effect, the level of uncertainty induced by them is such that only the first goal succeeds at all, leaving these fantastic projects that can't be used by anyone completely stranded.

    Feel free to reach out, either here or by email. I'm happy to talk at length about my perspective on these matters, and see if I can help you come to a solution that helps you share and collaborate in a way that's compatible with your values.

    opened by alice-i-cecile 22
  • how to install?

    how to install?

    I am pretty new to rust, but I added this to my Cargo.toml:

    [dependencies.bevy]
    git = "https://github.com/bevyengine/bevy"
    branch = "main"
    default-features = false
    features = ["bevy_winit", "x11"]
    
    [dependencies.bevy_retro]
    git = "https://github.com/katharostech/bevy_retro"
    branch = "master"
    default-features = true
    

    I get this error when I try to cargo run demo code:

        Updating git repository `https://github.com/bevyengine/bevy`
        Updating git repository `https://github.com/katharostech/bevy_retro`
        Updating crates.io index
        Updating git repository `https://github.com/katharostech/luminance-glow`
        Updating git repository `https://github.com/katharostech/luminance-surfman`
        Updating git repository `https://github.com/GrovesNL/glow.git`
    error: failed to select a version for `web-sys`.
        ... required by package `luminance-glow v0.0.0 (https://github.com/katharostech/luminance-glow?branch=master#ca5a0b62)`
        ... which is depended on by `bevy_retro v0.0.0 (https://github.com/katharostech/bevy_retro?branch=master#1642ef8b)`
        ... which is depended on by `pakemon v0.1.0 (/Users/konsumer/Documents/otherdev/pakemon-rust/crates/pakemon)`
    versions that meet the requirements `^0.3.48` are: 0.3.50, 0.3.49, 0.3.48
    
    all possible versions conflict with previously selected packages.
    
      previously selected package `web-sys v0.3.46`
        ... which is depended on by `bevy_app v0.5.0 (https://github.com/bevyengine/bevy?branch=main#bc13d11c)`
        ... which is depended on by `bevy_asset v0.5.0 (https://github.com/bevyengine/bevy?branch=main#bc13d11c)`
        ... which is depended on by `bevy_internal v0.5.0 (https://github.com/bevyengine/bevy?branch=main#bc13d11c)`
        ... which is depended on by `bevy v0.5.0 (https://github.com/bevyengine/bevy?branch=main#bc13d11c)`
        ... which is depended on by `bevy_retro v0.0.0 (https://github.com/katharostech/bevy_retro?branch=master#1642ef8b)`
        ... which is depended on by `pakemon v0.1.0 (/Users/konsumer/Documents/otherdev/pakemon-rust/crates/pakemon)`
    
    failed to select a version for `web-sys` which could resolve this conflict
    make: *** [pakemon] Error 101
    
    question 
    opened by konsumer 10
  • πŸ–₯ UI System

    πŸ–₯ UI System

    We need the basics necessary for UI:

    • Sprites that can be anchored to different sides of the screen
    • Possibly use a ninepatch system similar to bevy_ninepatch.
    • A sprite-based text and font system.
    enhancement 
    opened by zicklag 7
  • overall polishing needed

    overall polishing needed

    probably 1st thing I've encountered is long compile time of examples in release:

    adsick@pop-os:~/Rust/Crates/bevy_retrograde$ cargo run --features ldtk,epaint --example epaint --release
       Compiling bevy_retrograde v0.1.0 (/home/adsick/Rust/Crates/bevy_retrograde)
        Finished release [optimized] target(s) in 5m 00s
         Running `target/release/examples/epaint`
    

    I'm not kidding, it really takes 5m taking into account that I've already built the bevy_retrograde crate in release mode. yep my hardware is old (4c intel core i5-3330 & 8G DDR3 RAM & 1Tb HDD), but that not seems like an excuse for it (at least I think so)

    2nd text.rs example is not pixel perfect (not sure if it has to be) looks kinda odd to me image

    3rd sprite movement in hello_world is odd too, it is not smooth&looks glitchy 4rd epaint results are not looking pleasant image not awful but not perfect

    opened by adsick 6
  • failed to get `heron` as a dependency of package

    failed to get `heron` as a dependency of package

    adsick@pop-os:~/Rust/Crates/bevy_retrograde$ cargo build

        Updating crates.io index
        Updating git repository `https://github.com/katharostech/heron.git`
    error: failed to get `heron` as a dependency of package `bevy_retrograde_physics v0.1.0 (/home/adsick/Rust/Crates/bevy_retrograde/crates/bevy_retrograde_physics)`
    
    Caused by:
      failed to load source for dependency `heron`
    
    Caused by:
      Unable to update https://github.com/katharostech/heron.git?branch=ktech-patches#c555ad6f
    
    Caused by:
      object not found - no match for id (c555ad6f4f327fe23276df0d87ac8879e5ced744); class=Odb (9); code=NotFound (-3)
    
    opened by adsick 6
  • 🐞 assertion failed: `!gl_dx_interop_device.is_null()`

    🐞 assertion failed: `!gl_dx_interop_device.is_null()`

    $ cargo run --example hello_world Finished dev [optimized] target(s) in 0.38s Running target\debug\examples\hello_world.exe thread 'main' panicked at 'assertion failed: !gl_dx_interop_device.is_null()', D:/rust/.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\surfman-0.4.3\src\platform\windows\wgl\device.rs:159:13 note: run with RUST_BACKTRACE=1 environment variable to display a backtrace error: process didn't exit successfully: target\debug\examples\hello_world.exe (exit code: 101)

    cargo 1.55.0-nightly rustc 1.56.0-nightly Windows 11 Windows Feature Experience Pack 421.18901.0.3

    bug platform:windows 
    opened by get200 4
  • I've tried to compile

    I've tried to compile "Hello, World" example, but "translation" seems to be missing from SpriteBundle. There is a position component, though.

    error[E0560]: struct `bevy_retrograde::prelude::SpriteBundle` has no field named `transform`
      --> src/main.rs:48:13
       |
    48 |             transform: Transform::from_xyz(0., 0., 0.),
       |             ^^^^^^^^^ `bevy_retrograde::prelude::SpriteBundle` does not have this field
       |
       = note: available fields are: `sprite`, `image`, `visible`, `position`, `world_position`
    
    opened by DanielSolmann 4
  • [Merged by Bors] - Add Error For Rotated Sprites

    [Merged by Bors] - Add Error For Rotated Sprites

    We currently don't render sprites with rotations. Add an error log so that users don't get confused about apparently un-rotated sprites with rotations set.

    opened by zicklag 4
  • Integrate Egui UI

    Integrate Egui UI

    We need to integrate Egui instead of RAUI for UI.

    It should be trivial to just re-use the existing bevy egui plugin.

    • [x] Integrate Egui plugin
    • [x] Implement with 9-patch widget for Egui
    • [x] Implement image-themed buttons
    • [x] Implement retro-font handling
    enhancement 
    opened by zicklag 3
  • Problem with the Ldtk loader when running from another project

    Problem with the Ldtk loader when running from another project

    Hi,

    first, thanks for the great work, it looks promising! I'm new to bevy and rust, thanks for your patience. I was trying to adapt the ldtk map loading for my project and I encountered some issues. I think it's a bug, but not 100% sure.

    First, to test it, I ran the actual ldtk_map.rs example from the cloned repo, it works fine. Then, I moved the example to main.rs. It still compiles fine. Then, I also linked to the online crates what I could.

    At this point I have:

    [package]
    ...
    name = "bevy_retrograde"
    ...
    
    [features]
    default = ['ldtk']
    ldtk = ["bevy_retrograde_ldtk"]
    
    [dependencies]
    bevy = {version = "0.5", default-features = false}
    
    bevy_retrograde_core = {version = "0.2"}
    bevy_retrograde_ldtk = {version = "0.2", optional = true}
    bevy_retrograde_macros = {version = "0.2"}
    hex = "0.4.3"
    
    [dev-dependencies]
    hex = "0.4.3"
    rand = "0.8.3"
    
    [profile.dev]
    debug = 0
    opt-level = 1
    

    that I can run with cargo run. This runs fine. The bevy_retrograde is still loaded from the lib.rs !

    Then I copy the exact same code (main.rs and Cargo.toml) to my project. The difference is that the lib.rs is not present, so I add the line: bevy_retrograde = "0.2" in the Cargo.toml file.

    But somehow running the same code from my project, it still compiles fine, but when running it, it panics:

    Finished dev [unoptimized] target(s) in 26.22s Runningtarget/debug/my_projectOct 02 21:25:26.869 WARN bevy_asset::asset_server: noAssetLoaderfound for the following extension: ldtk thread 'Compute Task Pool (4)' panicked at 'Requested resource does not exist: bevy_asset::assets::Assets<bevy_retrograde_ldtk::asset::LdtkMap>', /home/luc/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/system/system_param.rs:244:17 note: run withRUST_BACKTRACE=1environment variable to display a backtrace thread 'main' panicked at 'task has failed', /home/luc/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.0.3/src/task.rs:368:45

    However, if I copy the lib.rs from the repo, it compiles and run fine (all the code is identical, so...yeah, makes sense ^^) if I include the lib:

    [lib]
    name = "bevy_retrograde"
    path = "src/lib.rs"
    
    

    Am I missing something or is there an issue with loading the ldtk plugin from the crate?

    bug compiling-difficulty 
    opened by Lukastos 3
  • Project development

    Project development

    Just wanted to ask whether the owners are intending to continue development on this project! There are no new features as such that I need, more so asking out of curiosity.

    opened by boyswan 3
  • Accessing world coordinates via cursor_position

    Accessing world coordinates via cursor_position

    I'm struggling to access world coords with a mouse click. My current attempt is along the lines of:

    if let Some(pos) = window.cursor_position() {
        if let Ok((camera_transform, camera)) = q_camera.single() {
            let low = camera.get_target_sizes(window).low;
            let size = Vec2::new(low.x as f32, low.y as f32);
       
            let p = pos - size / 2.0;
            let pos_wld = camera_transform.compute_matrix() * p.extend(0.0).extend(1.0);
            let pos = Vec2::new(pos_wld.x, -pos_wld.y);
    
            info!("world xy", pos);
        }
    }
    

    However I can't seem to figure out the correct way to find the coords and am not sure whether bevy_retrograde will require a different calculation (I'm trying to move a sprite to an ldtk tile).

    Apologies for making an issue as I know it's not a bug, but I'm not sure where else to ask and have been stuck on this for a while!

    question 
    opened by boyswan 4
  • πŸ” Alternative Pixel Filtering Modes

    πŸ” Alternative Pixel Filtering Modes

    Related to the text rendering comment in #50.

    There are three different strategies that we know of that Bevy Retrograde could use for pixel rendering. We currently use what we dub here the "Crips Scalable" version, but there are also a couple other versions that we should implement as configurable modes.

    Summary

    | Mode | Implemented | Crisp Edges | Perfect Squares | Any Zoom Level | Doesn't Require Camera Borders | |--|--|--|--|--|--| | Crisp Scalable | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: | | Smooth Scalable | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | Crisp Fixed Scale | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: |

    Crisp Scalable ( Current )

    The crisp scalable model uses simple "nearest" mode filtering for the pixels, which retains the pixels' sharp edges, and we allow scaling the screen to match the camera size to the window size, allowing the game to be played at any zoom.

    The disadvantage of this technique is that at non-integer scales, the in-game pixels will not line up perfectly with the physical pixels of the users screen and the result will be that some rows and columns of pixels may be taller or wider than the others.

    Smooth Scalable

    The smooth scalable model uses an anti-aliased filtering technique that preserves the squareness of pixels at any scale, but results in a blurrier appearance and can lose the crisp edges.

    Crisp Fixed Scale

    The crisp fixed scale model will preserve the sharp edges of the pixels, and make sure that they remain perfect squares, but will restrict the scaling level to integer values such as 1x, 2x, 3x, 4x, etc. This means that when the window size is, for instance, 1.5x the game will render at 1x scale with a border around it.

    enhancement 
    opened by zicklag 0
  • πŸ’Ύ Save Data Handling

    πŸ’Ύ Save Data Handling

    This should be an external crate that is included with a default feature flag into Bevy Retro. We need a plugin that can be used for saving arbitrary data that works with Browser Local Storage or files on your filesystem.

    enhancement 
    opened by zicklag 0
Releases(v0.2.0)
  • v0.2.0(Jul 19, 2021)

    This latest release comes with a few big improvements! πŸŽ‰

    Transform System

    Previously, Bevy retro used it's own transform and hierarchy system. This was done so that we could specify sprite positions as integer pixel positions. We initially thought that this might be helpful, so that you could never represent half-of-a-pixel movement and so that all pixels would be perfectly alligned. After using the system a bit, though, we realized that it was much harder to move objects at variable speeds because we couldn't use floating point positions.

    In light of this, we decided to switch to using Bevy's built-in transform system. This makes positioning things in Bevy Retrograde work just like they do in out-of-the-box Bevy, and now entity movement algorithms are much simpler and sprite positions are still rounded to snap them to the grid and perfectly align them.

    Un-aligned Sprites

    Another big change is the advent of non-perfectly aligned sprites. By default all sprites are snapped to the grid, so to speak, making the pixels of each sprite line up perfectly with all the others, but now there is additionally an option to make individual sprites not aligned. This allows for your characters or enemies, for instance, to move smoothly, if desired, not requring that they snap to the retro-resolution pixels.

    Physics Integration

    physics_map

    We also integrated the Heron physics engine ( powered by Rapier ), along with our own plugin to enable automatically creating convex collision shapes from sprite outlines. This replaces our old, cumbersome collision detection system and enables a lot of new features such as ray-casting and simulation.

    Check out the new examples to learn how to use the new physics system!

    Epaint Integration

    We have also added a work-in-progress epaint integration that can be used for debug drawing. While the rendering is not perfect and text is not supported yet, we hope that it can be useful for certain types of debug visualization that can be used while developing a game. For instance, in our case, we used it to troubleshoot pathfinding algorithms by drawing the navigation mesh and the calculated path of the enemy during the game.

    debug_rendering

    Source code(tar.gz)
    Source code(zip)
Owner
Katharos Technology
Pure Innovation
Katharos Technology
Smooth pixel-perfect camera for Bevy

bevy_smooth_pixel_camera A bevy plugin that adds a simple smooth pixel camera. The smoothing is based on this video from aarthificial which explains h

Doonv 9 Nov 14, 2023
A plugin to use the kajiya renderer with bevy

??️ ?? bevy-kajiya A plugin that enables use of the kajiya renderer in bevy WARNING: This plugin is barebones and supports a limited set of features.

Sebastian Hamel 79 Jan 5, 2023
Sdf 2d shape renderer for Bevy

bevy_smud Sdf 2d shape rendering for Bevy. Bevy smud is a way to conveniently construct and render sdf shapes with Bevy. Given a shape function/expres

Johan Klokkhammer Helsing 85 Jan 2, 2023
Sandbox is a pixel physics simulator inspired by other such like Sandspiel and Noita

Sandbox Sandbox is a pixel physics simulator inspired by other such like Sandspiel and Noita. It's also a precursor for an ongoing game project. Sandb

Okko Hakola 76 Nov 3, 2022
Learning rust with the olc Pixel Game Engine.

olc rust sketches Learning Rust with the olc Pixel Game Engine. This project is based on olcPixelGameEngine-rs, a Rust API by Ivan Sadikov for the olc

Steve Ruiz 10 Oct 24, 2022
Bevy virtual Joystick for mobile games (Works with mouse on desktop)

Bevy Virtual Joystick Create and use a Virtual Joystick in a UI for bevy Game Engine. Versions Aviable and compatible versions bevy VirtualJoystick 0.

Sergio Alejandro Ribera Costa 7 Apr 16, 2023
Text Renderer written in Rust using HarfBuzz for shaping, FreeType for rasterization and OpenGL for rendering.

Provok Text Renderer written in Rust using HarfBuzz for shaping, FreeType for rasterization and OpenGL for rendering. Input Provok is fed with a JSON

Ossama Hjaji 67 Dec 10, 2022
A high-performance renderer to render glTF models that use the `KHR_materials_transmission` and `KHR_materials_volume` extensions.

This is a high-performance renderer designed among other things to render glTF models that use the KHR_materials_transmission and KHR_materials_volume

Ashley 21 Dec 5, 2022
Rust-based replacement for the default Minecraft renderer

wgpu-mc ?? A blazing fast alternative renderer for Minecraft Intro WebGPU is a new web specification designed to provide modern graphics and compute c

Birb 1 Jun 28, 2022
πŸ¦…πŸ¦ Fast, simple 2D text renderer for wgpu

?? glyphon ?? Fast, simple 2D text rendering for wgpu What is this? This crate provides a simple way to render 2D text with wgpu by: rasterizing glyph

Josh Groves 60 Nov 5, 2022
Renderer-agnostic toolkit for Indie Game Developers

Indie Toolkit Renderer-agnostic toolkit for Indie Game Developers Features Not yet implemented: app_kit debug_kit input_kit asset_kit audio_kit Implem

null 2 May 25, 2022
Minecraft using Bevy and Bevy-Meshem

minecraft_bevy Minecraft_bevy was built to showcase bevy_meshem. After a week of developing it has: Chunk loading / unloading each chunk's mesh is bei

Adam 7 Oct 4, 2023
Rapidly iterate and build Bevy UI's with existing web-based technologies

bevy_webview WIP   Rapidly iterate and build Bevy UI's with existing web-based technologies It is currently very early days of this plugin - only Linu

Mika 30 Jan 4, 2023
Minecraft-esque voxel engine prototype made with the bevy game engine. Pending bevy 0.6 release to undergo a full rewrite.

vx_bevy A voxel engine prototype made using the Bevy game engine. Goals and features Very basic worldgen Animated chunk loading (ala cube world) Optim

Lucas Arriesse 125 Dec 31, 2022
bevy-hikari is an implementation of voxel cone tracing global illumination with anisotropic mip-mapping in Bevy

Bevy Voxel Cone Tracing bevy-hikari is an implementation of voxel cone tracing global illumination with anisotropic mip-mapping in Bevy. Bevy Version

η ”η©Άη€ΎδΊ€ 208 Dec 27, 2022
A simple extension for `bevy-editor-pls` to support tilemap editing right inside the bevy app.

What is this This is a simple tilemap editor plugin, that hooks right into bevy_editor_pls to work with bevy_ecs_tilemap. It works completely within i

null 3 May 8, 2023
Bevy Simple Portals is a Bevy game engine plugin aimed to create portals.

Portals for Bevy Bevy Simple Portals is a Bevy game engine plugin aimed to create portals. Those portals are (for now) purely visual and can be used t

Sélène Amanita 11 May 28, 2023
Extreme Bevy is what you end up with by following my tutorial series on how to make a low-latency p2p web game.

Extreme Bevy Extreme Bevy is what you end up with by following my tutorial series on how to make a low-latency p2p web game. There game can be played

Johan Klokkhammer Helsing 39 Jan 5, 2023
🐡 Monkeytype, but for desktop

Monkeytype Desktop Monkeytype desktop is a desktop client for monkeytype.com with various quality-of-life features such as a Discord Rich Presence. Yo

Fuwn 3 Nov 21, 2022