Skip to main content

lightyear_inputs_native/
lib.rs

1//! Module to handle client inputs
2//!
3//! Client inputs are generated by the user and sent to the server.
4//! They have to be handled separately from other messages, for several reasons:
5//! - the history of inputs might need to be saved on the client to perform rollback and client-prediction
6//! - we not only send the input for tick T, but we also include the inputs for the last N ticks before T. This redundancy helps ensure
7//!   that the server isn't missing any client inputs even if a packet gets lost
8//! - we must provide [`SystemSet`](bevy_ecs::prelude::SystemSet)s so that the user can order their systems before and after the input handling
9//!
10//! ### Adding a new input type
11//!
12//! An input type must be serializable, `Reflect`, `MapEntities`, `Clone`, `PartialEq`, and `Debug`.
13//!
14//! You can then add the input type by adding the [`InputPlugin<InputType>`](prelude::InputPlugin) to your app.
15//!
16//! ```rust
17//! # use bevy_app::App;
18//! # use bevy_ecs::entity::{MapEntities, EntityMapper};
19//! # use serde::{Serialize, Deserialize};
20//! # use bevy_reflect::Reflect;
21//! use lightyear_inputs_native::prelude::*;
22//!
23//! #[derive(Serialize, Deserialize, Clone, PartialEq, Reflect, Debug, Default)]
24//! pub enum MyInput {
25//!     Move { x: f32, y: f32 },
26//!     Jump,
27//!     // we need a variant for "no input", to differentiate between "no input" and "missing input packet"
28//!     #[default]
29//!     None,
30//! }
31//!
32//! // every input must implement MapEntities
33//! impl MapEntities for MyInput {
34//!     fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
35//!     }
36//! }
37//!
38//! let mut app = App::new();
39//! app.add_plugins(InputPlugin::<MyInput>::default());
40//! ```
41//!
42//! ### Sending inputs
43//!
44//! There are several steps to use the `InputPlugin`:
45//! - (optional) read the inputs from an external signal (mouse click or keyboard press, for instance)
46//! - to buffer inputs for each tick. This is done by setting the input value in the [`ActionState`](action_state::ActionState) component.
47//!   That system must run in the [`WriteClientInputs`](lightyear_inputs::prelude::client::InputSystems::WriteClientInputs) system set, in the `FixedPreUpdate` stage.
48//! - handle inputs in your game logic in systems that run in the `FixedUpdate` schedule. These systems
49//!   will read the inputs using the `ActionState` component
50//!
51//! [`FixedUpdate`]: bevy_app::prelude::FixedUpdate
52
53#![no_std]
54
55extern crate alloc;
56extern crate core;
57#[cfg(feature = "std")]
58extern crate std;
59
60pub(crate) mod action_state;
61
62pub(crate) mod input_message;
63
64pub mod plugin;
65
66pub mod prelude {
67    pub use crate::action_state::{ActionState, InputMarker};
68    pub use crate::input_message::NativeBuffer;
69    pub use crate::plugin::InputPlugin;
70}