- Load the bevy-cheatbook skill
- When working with UI, load the bevy-enhanced-ui skill
- Always Load the ponytail skill, it helps you to be more token efficient
Lifthrasir is a Ragnarok Online client implementation written in Rust using the Bevy game engine with a native Bevy UI. The project aims to recreate the classic MMORPG client while leveraging modern technologies for cross-platform compatibility, performance, and maintainability.
- Full support for Ragnarok Online file formats (GRF, GND, GAT, RSW, RSM, SPR, ACT)
- 3D terrain rendering with proper coordinate system translation
- Character rendering with equipment and animation systems
- Authentication and character management
- Native UI built with Bevy
- Rust (Edition 2021): Primary programming language for game engine
- Bevy 0.18.1: ECS-based game engine for rendering, game logic, and UI
- Entity Component System (ECS): Bevy's core architecture pattern
- Clean Architecture: Layered design with clear separation of concerns
- Domain-Driven Design (DDD): Business logic organized by domain concepts
- Event-Driven Architecture: Communication via Bevy events
The project is organized as a Cargo workspace:
lifthrasir/
├── game-engine/ # Core game engine (Bevy ECS)
├── lifthrasir-ui/ # Native Bevy UI components
├── lifthrasir/ # Binary entry point
├── net-contract/ # Protocol-neutral network contract (Bevy Messages)
├── net-aesir/ # Aesir QUIC network adapter (transport + codec)
└── grf-utils/ # GRF archive utilities
The network stack is split into a protocol-neutral contract and swappable adapters:
net-contractis the protocol-neutral BevyMessagecontract — inbound server→clientevents, outbound client→servercommands, and the neutraldto/statetypes they reference. It depends only onbevy; it knows nothing about any wire protocol.- Adapter crates (e.g.
net-aesir, the aesir QUIC adapter) own the transport and codec (bevy_quinnet+prost). An adapter reads the outbound command Messages and writes the inbound event Messages; that is its entire interface to the rest of the app.
game-engine and lifthrasir-ui depend only on net-contract and never on a
transport/codec. This is locked in by game-engine/tests/no_transport_dep.rs, which
fails if game-engine's dependency tree regains bevy_quinnet, prost, or an
adapter crate.
The adapter is wired at the binary, not in game-engine: the lifthrasir binary
(lifthrasir/src/main.rs) depends on net-aesir and adds its AesirNetPlugin.
To support a different protocol (e.g. rAthena): implement a new crate that
depends only on net-contract, write the inbound event Messages from incoming
packets, read the outbound command Messages and translate them to outgoing packets,
expose a plugin, and add that plugin in main.rs. The contract, game-engine, and
lifthrasir-ui stay untouched. See
specs/2026-06-30-network-decoupling/design.md.
# Build game engine only
cd game-engine
cargo build
# Build entire workspace
cargo build
# Release build
cargo build --releasecargo run -p lifthrasirDLSS is an opt-in, off-by-default Cargo feature. It is absent from default builds and cannot compile on macOS (it requires the Vulkan backend and an NVIDIA RTX GPU). Build and run it only on Windows or Linux with an RTX card:
DLSS_SDK=/path/to/dlss-sdk VULKAN_SDK=/path/to/vulkan \
cargo run -p lifthrasir --features dlssPrerequisites on the target machine:
- NVIDIA DLSS Super Resolution SDK v310.5.3 — download separately (it is not redistributable) and point
DLSS_SDKat its absolute path. - Vulkan SDK — with
VULKAN_SDKset. - Clang — required by
bindgenwhen building the SDK wrapper.
At runtime DLSS degrades gracefully: if the GPU/driver does not support it, the DlssSuperResolutionSupported resource is absent and the setting stays Off (logged once). The setting lives in the Graphics menu as Off / DLAA / Quality / Balanced / Performance / Ultra Performance and is orthogonal to the xBRZ "Upscaling" setting (DLSS scales render resolution; xBRZ bakes textures).
Licensing / distribution (settle before any public release):
- The DLSS SDK license text (DLSS Programming Guide §9.5) must ship alongside any distributed binary.
- The proprietary
nvngx_dlssruntime libraries must be packaged next to the binary. - The binary is already GPL-3.0 (via the xBRZ
xbrz-rscrate); GPL plus the proprietary DLSS blob loaded at runtime is a known gray area — resolve it before distributing publicly.
Manual verification checklist: specs/2026-06-28-dlss/design.md → "Testing".
The client talks to the aesir account server over QUIC using protobuf (bevy_quinnet + prost). The Rust types are generated from aesir's canonical aesir.proto and committed at net-aesir/src/proto/aesir.net.rs. Re-run this whenever that schema changes:
cargo run -p ro-to-lifthrasir-cli -- gen-proto \
--src <aesir>/apps/commons/proto \
--out net-aesir/src/proto/aesir.net.rsThis uses the pure-Rust protox compiler, so no system protoc is required. Commit the regenerated file.
# Run all tests
cargo test
# Run specific test
cargo test <test_name># Format code
cargo fmt
# Check formatting
cargo fmt --check
# Lint with Clippy
cargo clippy
# Check without building
cargo check- Check existing patterns: Look for similar features before implementing
- Follow layer separation: Domain logic separate from infrastructure
- Write tests: Add tests for new domain logic
- Prevent nesting of ifs, prefer a more functional style and early returns.
- Critical systems should not have fallbacks, they should fail loudly.
- Always check the libraries usage and examples using the Context 7 Tool
- Think before writing: Is there a simpler way to achieve this?
- Keep functions simple and pure, prevent the creation of god functions with several parameters.
- Prefer splitting code in modules instead of god files.
- Always consult the bevy cheatbook https://bevy-cheatbook.github.io/
- Consult bevy examples, they are very helpful https://github.com/bevyengine/bevy/tree/latest/examples#examples
- Also check the bevy documentation for up-to-date function https://docs.rs/bevy/latest/bevy/