audio_code/lib.rs
1//! # audio-code
2//!
3//! A simple, high level game engine for **audio games**: games played by ear, without
4//! graphics. Everything a blind or visually impaired player needs is built in:
5//!
6//! * **Speech** through the player's screen reader or system voice ([`speech`], via prism)
7//! * **Sound**: one-line playback, 3D positioned sounds, music with cross fades ([`audio`])
8//! * **Virtual UI**: spoken menus, sliders, checkboxes, text fields and dialogs ([`ui`])
9//! * **Physics**: walls, floors, gravity, triggers and ray casts ([`physics`])
10//! * **Vehicles**: cars and trucks with weight, speed, gears, brakes and fuel ([`vehicle`])
11//! * **Time**: frame timing, a scheduler, timers, cooldowns and intervals ([`time`])
12//! * **Input**: pressed / held / released, custom key repeat, typed text ([`input`])
13//! * **Online play**: host or join games over encrypted WebSockets, send packets, pings and
14//! timeouts built in ([`net`])
15//! * **Translations**: one text file per language, engine texts in English and German ([`lang`])
16//! * Optional **wxWidgets** integration through wxDragon (`audio_code::wx`, feature `wxdragon`)
17//!
18//! ## A complete game in 30 lines
19//!
20//! ```no_run
21//! use audio_code::prelude::*;
22//!
23//! struct Game {
24//! x: f32,
25//! }
26//!
27//! impl Scene for Game {
28//! fn start(&mut self, ctx: &mut Context) {
29//! ctx.speech.speak("Walk with left and right. Find the beacon!");
30//! ctx.audio.play_looped_at("beacon", vec3(10.0, 0.0, 0.0));
31//! }
32//!
33//! fn update(&mut self, ctx: &mut Context) {
34//! if ctx.input.repeating(Key::Left, 0.25, 0.25) {
35//! self.x -= 1.0;
36//! }
37//! if ctx.input.repeating(Key::Right, 0.25, 0.25) {
38//! self.x += 1.0;
39//! }
40//! ctx.audio.set_listener(vec3(self.x, 0.0, 0.0), 0.0);
41//! if self.x == 10.0 {
42//! ctx.speech.speak("You found it!");
43//! ctx.quit();
44//! }
45//! }
46//! }
47//!
48//! fn main() -> audio_code::Result<()> {
49//! Engine::new("Beacon").run(Game { x: 0.0 })
50//! }
51//! ```
52//!
53//! Start with [`Engine`], [`Scene`] and [`Context`], then read the module docs. The `docs`
54//! folder of the repository contains a longer guide.
55
56#![warn(missing_docs)]
57
58pub mod audio;
59mod bundle;
60mod engine;
61mod error;
62pub mod input;
63pub mod lang;
64pub mod level;
65pub mod math;
66pub mod net;
67pub mod physics;
68mod shortcuts;
69pub mod speech;
70pub mod storage;
71pub mod time;
72pub mod ui;
73pub mod vehicle;
74mod window;
75#[cfg(feature = "wxdragon")]
76pub mod wx;
77
78pub use engine::{Context, Engine, Runner, Scene};
79
80// Compiles the code blocks in the README as doc tests, so they cannot go stale.
81#[cfg(doctest)]
82#[doc = include_str!("../README.md")]
83struct ReadmeDoctests;
84pub use error::{Error, Result};
85
86/// The quickest way to start: a whole game as one closure that runs every frame.
87///
88/// ```no_run
89/// use audio_code::prelude::*;
90///
91/// fn main() -> audio_code::Result<()> {
92/// let mut score = 0;
93/// audio_code::run("Clicker", move |ctx| {
94/// if ctx.once("intro") {
95/// ctx.speak("Press space as often as you can. Escape quits.");
96/// }
97/// if ctx.pressed(Key::Space) {
98/// score += 1;
99/// ctx.audio.play_tone(400.0 + score as f32 * 10.0, 0.05);
100/// }
101/// if ctx.pressed(Key::Escape) {
102/// ctx.speak(format!("Your score: {score}"));
103/// ctx.quit();
104/// }
105/// })
106/// }
107/// ```
108///
109/// When the game grows, move to [`Scene`]s.
110pub fn run(title: &str, update: impl FnMut(&mut Context) + 'static) -> Result<()> {
111 Engine::new(title).run_fn(update)
112}
113
114/// Everything you normally need: `use audio_code::prelude::*;`
115pub mod prelude {
116 pub use crate::audio::{Audio, Group, Sound, SoundData, Synth, Wave};
117 pub use crate::engine::{Context, Engine, Scene};
118 pub use crate::input::{Input, Key, Modifiers};
119 pub use crate::lang::Lang;
120 pub use crate::level::Level;
121 pub use crate::math::{self, Vec2, Vec3, random, vec2, vec3};
122 pub use crate::net::{self, Net, NetEvent, Packet, PeerId, Reason};
123 pub use crate::physics::{Body, BodyId, BodyKind, EARTH_GRAVITY, MoveResult, PhysicsEvent, RayHit, Shape, World};
124 pub use crate::speech::{Speech, Voice};
125 pub use crate::storage::Storage;
126 pub use crate::time::{Cooldown, Interval, Time, Timer};
127 pub use crate::ui::{Confirm, Menu, Message, TextInput, Ui, UiEvent, UiSound, UiSounds, Value, Widget};
128 pub use crate::vehicle::Vehicle;
129}