https://github.com/skius/teng
A minimal, cross-platform graphical game engine for the terminal in Rust
https://github.com/skius/teng
game-engine rust terminal terminal-game tui
Last synced: 8 days ago
JSON representation
A minimal, cross-platform graphical game engine for the terminal in Rust
- Host: GitHub
- URL: https://github.com/skius/teng
- Owner: skius
- Created: 2025-02-17T13:16:41.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2025-03-21T14:31:13.000Z (about 1 month ago)
- Last Synced: 2025-03-28T13:21:14.356Z (25 days ago)
- Topics: game-engine, rust, terminal, terminal-game, tui
- Language: Rust
- Homepage: https://docs.rs/teng
- Size: 16.2 MB
- Stars: 5
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# teng ๐
[![Crate Badge]][Crate] [![Repo Badge]][Repo] [![Docs Badge]][Docs] [![License Badge]][License] \
[Docs] ยท [Examples]A minimal, cross-platform graphical game engine for the terminal in Rust
## Features
- Fast rendering by only printing changed pixels to the terminal
- Components-based architecture around a simple game loop
- Immediate mode rendering
- Built-in FPS limiter
- Batteries included: Components for common tasks (e.g. input handling, FPS display, mouse interpolation, half block rendering)## Showcase
See below for a clip of an unreleased game built in **teng**:## Getting Started
**teng** uses components as the building blocks. Every frame, each component (optionally):
- Handles received events (mouse, keyboard, resizes, etc.)
- Updates the game state
- Renders its core concept (if any) to the screenHere's a simple example that renders static content to the screen:
```rust ,no_run
use std::io;
use teng::components::Component;
use teng::rendering::pixel::Pixel;
use teng::rendering::render::Render;
use teng::rendering::renderer::Renderer;
use teng::{install_panic_handler, terminal_cleanup, terminal_setup, Game, SharedState};struct MyComponent;
impl Component for MyComponent {
fn render(&self, renderer: &mut dyn Renderer, shared_state: &SharedState, depth_base: i32) {
let width = shared_state.display_info.width();
let height = shared_state.display_info.height();
let x = width / 2;
let y = height / 2;
let pixel = Pixel::new('โ').with_color([0, 255, 0]);
renderer.render_pixel(x, y, pixel, depth_base);"Hello World"
.with_bg_color([255, 0, 0])
.render(renderer, x, y + 1, depth_base);
}
}fn main() -> io::Result<()> {
terminal_setup()?;
install_panic_handler();let mut game = Game::new_with_custom_buf_writer();
// If you don't install the recommended components, you will need to have your own
// component that exits the process, since Ctrl-C does not work in raw mode.
game.install_recommended_components();
game.add_component(Box::new(MyComponent));
game.run()?;terminal_cleanup()?;
Ok(())
}
```
This results in the following:[](examples/simple.rs)
## FAQ
### Why should I use **teng** over other TUI libraries?
**teng** particularly shines when you are not aware of libraries like [ratatui](https://github.com/ratatui/ratatui/), [yeehaw](https://github.com/bogzbonny/yeehaw/), [cursive](https://github.com/gyscos/cursive), and more.Also, if you're looking to just get started with game development in the terminal, **teng** may be a good choice due to its simplicity and focus on traditional, frame-based game loops and pixel-based rendering.
All you need is a single component and you can individually target every pixel on the screen.Realistically, **teng** should be seen as an educational hobby project :)
### Is **teng** an ECS?
Not really. **teng**'s "Components" are quite similar to "Systems" in an ECS, but there is no built-in notion of entities or components in the ECS sense.
However, you can build an ECS inside **teng** quite easily, see [`examples/ecs`](examples/ecs/main.rs) for an example.### Missing features
- Currently, each pixel must be a single unicode scalar value, and its width is assumed to be 1. This means that wide graphemes, and graphemes consisting of multiple unicode scalar values, will most likely not be rendered correctly.
- **teng** makes a few assumptions about the capabilities of the terminal, without providing any fallbacks. For example, colors are RGB.[Repo]: https://github.com/skius/teng
[Docs]: https://docs.rs/teng
[Examples]: https://github.com/skius/teng/tree/main/examples
[Crate]: https://crates.io/crates/teng
[Crate Badge]: https://img.shields.io/crates/v/teng?logo=rust&style=flat-square&color=E05D44
[Repo Badge]: https://img.shields.io/badge/repo-skius/teng-3370D3?style=flat-square&logo=github
[License Badge]: https://img.shields.io/crates/l/teng?style=flat-square&color=1370D3
[Docs Badge]: https://img.shields.io/badge/docs-teng-1370D3?style=flat-square&logo=rust
[License]: ./LICENSE