1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
//! ! //! //! This crate provides a [Bevy](https://bevyengine.org/) plugin for integrating with //! the Steamworks SDK. //! //! ## Installation //! Add the following to your `Cargo.toml`: //! //! ```toml //! [dependencies] //! bevy-steamworks = "0.1.0" //! ``` //! //! Ensure that your computer has all the needed //! [requirements](https://rust-lang.github.io/rust-bindgen/requirements.html) to use //! [bindgen](https://github.com/rust-lang/rust-bindgen). //! //! Download and install the [steamworks sdk](https://partner.steamgames.com/doc/sdk) //! and set the environment variable `STEAM_SDK_LOCATION` to point to it. //! //! At runtime, a "steam_appid.txt" file with the registered Steam App ID of the game //! is required in the same directory as the executable. //! //! ## Usage //! //! To add the plugin to your game, simply add the `SteamworksPlugin` to your //! `AppBuilder`. //! //! ```rust //! use bevy::prelude::*; //! use bevy_steamworks::SteamworksPlugin; //! //! fn main() { //! App::build() //! .add_plugins(DefaultPlugins) //! .add_plugin(SteamworksPlugin) //! .run() //! } //! ``` //! //! The plugin adds `steamworks::Client` as a Bevy ECS resource, which can be //! accessed like any other resource in Bevy. The client implements `Send` and `Sync` //! and can be used to make requests via the SDK from any of Bevy's threads. However, //! any asynchronous callbacks from Steam will only run on the main thread. //! //! The plugin will automatically call `SingleClient::run_callbacks` on the Bevy //! main thread every frame, so there is no need to run it manually. //! //! **NOTE**: If the plugin fails to initialize (i.e. `Client::init()` fails and //! returns an error, an error wil lbe logged (via `bevy_log`), but it will not //! panic. In this case, it may be necessary to use `Option<Res<Client>>` instead. //! //! ```rust //! use bevy_steamworks::{Client, FriendFlags}; //! //! fn steam_system(steam_client: Res<Client>) { //! for friend in client.friends().get_friends(FriendFlags::IMMEDIATE) { //! println!("Friend: {:?} - {}({:?})", friend.id(), friend.name(), friend.state()); //! } //! } //! //! fn main() { //! App::build() //! .add_plugins(DefaultPlugins) //! .add_plugin(SteamworksPlugin) //! .add_startup_system(steam_system.system()) //! .run() //! } //! ``` use bevy_app::{AppBuilder, Plugin}; use bevy_ecs::system::{IntoSystem, NonSend}; use bevy_log::error; pub use steamworks::*; fn run_steam_callbacks(client: NonSend<SingleClient>) { client.run_callbacks(); } pub struct SteamworksPlugin; impl Plugin for SteamworksPlugin { fn build(&self, app: &mut AppBuilder) { match Client::init() { Err(err) => error!("Failed to initialize Steamworks client: {}", err), Ok((client, single)) => { app.insert_resource(client) .insert_non_send_resource(single) .add_system(run_steam_callbacks.system()); } } } }