diff --git a/Cargo.toml b/Cargo.toml
index a2318e628ba62ff3bdde6314e64da3be196adab3..47e31e64d779ff8f953a7c18d8ba25a7dc3043e8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,7 +8,7 @@ repository = "https://lab.lcr.gr/microhacks/micro_bevy_musicbox"
 description = "Opinionated service interface for bevy_kira_audio"
 
 [features]
-default-features = []
+default = []
 serde = ["dep:serde"]
 
 [dependencies]
diff --git a/src/lib.rs b/src/lib.rs
index 2a52e91f53d8132d9708af96d184dd0be81c2a75..0a68d8c4c1d3b63b2bb35805e5586e669a7c9bc2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,28 @@
+//! micro_musicbox provides a convenience wrapper around bevy_kira_audio, handling all the
+//! setup for the common game audio scenario. This includes channel management, giving you
+//! control of the audio levels for your music, ambiance, sound effects and UI separately
+//! from the start.
+//!
+//! ## Quickstart
+//!
+//! - Implement `SuppliesAudio` for a resource (or use the built-in impl on `AssetServer`)
+//! - Include the MusixBocPlugin plugin, or the CombinedAudioPlugins plugin group in your app, providing your `SuppliesAudio` impl as the generic parameter
+//! - Use `MusicBox<T: SuppliesAudio>` as a parameter on a system
+//! - Call one of the `MusicBox::play_*` methods to play sounds
+//!
+//! ```rust
+//! # use bevy::prelude::*;
+//! # use micro_musicbox::prelude::*;
+//! # use micro_musicbox::CombinedAudioPlugins;
+//! fn main() {
+//!     App::new()
+//!         .add_plugins(CombinedAudioPlugins::<AssetServer>::new())
+//!         .add_startup_system(|mut music_box: MusicBox<AssetServer>| {
+//!             music_box.play_music("music/bing_bong.mp3");
+//!         });
+//! }
+//! ```
+
 use std::marker::PhantomData;
 
 use bevy::app::{App, CoreStage, Plugin, PluginGroup, PluginGroupBuilder};
@@ -9,8 +34,7 @@ use crate::channels::{
 use crate::music_box::MusicBoxState;
 use crate::utilities::{AudioSettings, SuppliesAudio};
 
-/// Musicbox encapsulates the concept of different sound types in a number of preset channels, that
-/// can be used in certain ways
+/// The available channels that you can play audio on
 pub mod channels;
 pub mod music_box;
 pub mod utilities;
@@ -26,6 +50,10 @@ pub mod prelude {
 	pub use super::utilities::AudioSettings;
 }
 
+/// A Bevy plugin that sets up all of the audio channels,
+/// creates the required settings resources, and configures
+/// syncing volume levels for a `MusicBox` that uses the supplied
+/// `T` parameter for fetching audio
 pub struct MusicBoxPlugin<T: SuppliesAudio> {
 	_t: PhantomData<T>,
 }
@@ -39,6 +67,7 @@ impl<T: SuppliesAudio> Default for MusicBoxPlugin<T> {
 }
 
 impl<T: SuppliesAudio> MusicBoxPlugin<T> {
+	/// Create a new MusicBoxPlugin
 	pub fn new() -> MusicBoxPlugin<T> {
 		Default::default()
 	}
@@ -56,6 +85,8 @@ impl<T: SuppliesAudio> Plugin for MusicBoxPlugin<T> {
 	}
 }
 
+/// A Bevy plugin group that adds `bevy_kira_audio` as well as the
+/// plugin required to be able to use a `MusicBox`
 pub struct CombinedAudioPlugins<T: SuppliesAudio> {
 	_t: PhantomData<T>,
 }
diff --git a/src/music_box.rs b/src/music_box.rs
index 7028bf29ee860dd41d263c5c570e63adf3339705..1d7c74824d585d32602f90bc692ba2f9e4336a81 100644
--- a/src/music_box.rs
+++ b/src/music_box.rs
@@ -7,6 +7,7 @@ use bevy_kira_audio::{AudioChannel, AudioControl, AudioInstance, AudioSource, Au
 use crate::utilities::{AudioSettings, SuppliesAudio, TrackType};
 use crate::{AmbianceAudioChannel, MusicAudioChannel, SfxAudioChannel, UiSfxAudioChannel};
 
+/// A wrapper for each of the audio channels created and controlled by MusicBox
 #[derive(SystemParam)]
 pub struct AudioChannels<'w, 's> {
 	pub music_channel: Res<'w, AudioChannel<MusicAudioChannel>>,
@@ -18,6 +19,12 @@ pub struct AudioChannels<'w, 's> {
 	_p: PhantomData<&'s ()>,
 }
 
+/// The service object used to control your game's audio
+///
+/// ## `T: SuppliesAudio`
+///
+/// The particular implementation of `SuppliesAudio` will be used to verify that a music track exists,
+/// and then to retrieve the associated `AudioSource`.
 #[derive(SystemParam)]
 pub struct MusicBox<'w, 's, T: SuppliesAudio> {
 	channels: AudioChannels<'w, 's>,
@@ -36,6 +43,12 @@ pub struct MusicBoxState {
 }
 
 impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
+	/// Start playing a new audio track on the Music channel. The provided tween will be used
+	/// to fade in the new track, and to fade out the old track
+	///
+	/// # Returns
+	///
+	/// A handle for the newly started audio instance, or `None` if the track was not found
 	pub fn cross_fade_music<Name: ToString>(
 		&mut self,
 		name: Name,
@@ -45,6 +58,13 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 		self.fade_in_music(name, fade)
 	}
 
+	/// Start playing a new audio track on the Music channel. The "in_tween" will be used to fade
+	/// in the new audio track, while the "out_tween" will be used to fade out the old audio
+	/// track
+	///
+	/// # Returns
+	///
+	/// A handle for the newly started audio instance, or `None` if the track was not found
 	pub fn in_out_fade_music<Name: ToString>(
 		&mut self,
 		name: Name,
@@ -55,15 +75,24 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 		self.fade_in_music(name, in_tween)
 	}
 
+	/// Start playing a new audio track on the Music channel. If another track is playing, it will
+	/// be immediately stopped
+	///
+	/// # Returns
+	///
+	/// A handle for the newly started audio instance, or `None` if the track was not found
 	pub fn play_music<Name: ToString>(&mut self, name: Name) -> Option<Handle<AudioInstance>> {
 		self.stop_music();
 		self.fade_in_music(name, AudioTween::default())
 	}
 
+	/// Stop playing music on the Music channel
 	pub fn stop_music(&mut self) {
 		self.fade_out_music(AudioTween::default());
 	}
 
+	/// Stop playing music on the music channel. The supplied tween will be used to fade out the track
+	/// before it ends
 	pub fn fade_out_music(&mut self, fade: AudioTween) {
 		let handle = std::mem::replace(&mut self.state.active_music, None)
 			.and_then(|handle| self.audio_instances.get_mut(&handle));
@@ -72,6 +101,12 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 		}
 	}
 
+	/// Start playing a new track on the music channel. If another track is playing, it will be
+	/// immediately stopped. The provided tween will be used to fade in the new track
+	///
+	/// # Returns
+	///
+	/// A handle for the newly started audio instance, or `None` if the track was not found
 	pub fn fade_in_music<Name: ToString>(
 		&mut self,
 		name: Name,
@@ -94,6 +129,12 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 		}
 	}
 
+	/// Start playing a new audio track on the Music channel. The provided tween will be used
+	/// to fade in the new track, and to fade out the old track
+	///
+	/// # Returns
+	///
+	/// A handle for the newly started audio instance, or `None` if the track was not found
 	pub fn cross_fade_ambiance<Name: ToString>(
 		&mut self,
 		name: Name,
@@ -103,6 +144,13 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 		self.fade_in_ambiance(name, fade)
 	}
 
+	/// Start playing a new audio track on the Music channel. The "in_tween" will be used to fade
+	/// in the new audio track, while the "out_tween" will be used to fade out the old audio
+	/// track
+	///
+	/// # Returns
+	///
+	/// A handle for the newly started audio instance, or `None` if the track was not found
 	pub fn in_out_fade_ambiance<Name: ToString>(
 		&mut self,
 		name: Name,
@@ -113,15 +161,24 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 		self.fade_in_ambiance(name, in_tween)
 	}
 
+	/// Start playing a new audio track on the Music channel. If another track is playing, it will
+	/// be immediately stopped
+	///
+	/// # Returns
+	///
+	/// A handle for the newly started audio instance, or `None` if the track was not found
 	pub fn play_ambiance<Name: ToString>(&mut self, name: Name) -> Option<Handle<AudioInstance>> {
 		self.stop_ambiance();
 		self.fade_in_ambiance(name, AudioTween::default())
 	}
 
+	/// Stop playing ambiance on the Music channel
 	pub fn stop_ambiance(&mut self) {
 		self.fade_out_ambiance(AudioTween::default());
 	}
 
+	/// Stop playing ambiance on the ambiance channel. The supplied tween will be used to fade out the track
+	/// before it ends
 	pub fn fade_out_ambiance(&mut self, fade: AudioTween) {
 		let handle = std::mem::replace(&mut self.state.active_ambiance, None)
 			.and_then(|handle| self.audio_instances.get_mut(&handle));
@@ -130,6 +187,12 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 		}
 	}
 
+	/// Start playing a new track on the ambiance channel. If another track is playing, it will be
+	/// immediately stopped. The provided tween will be used to fade in the new track
+	///
+	/// # Returns
+	///
+	/// A handle for the newly started audio instance, or `None` if the track was not found
 	pub fn fade_in_ambiance<Name: ToString>(
 		&mut self,
 		name: Name,
@@ -152,6 +215,11 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 		}
 	}
 
+	/// Play a new sound effect on the SFX channel
+	///
+	/// # Returns
+	///
+	/// A handle for the newly started audio instance, or `None` if the track was not found
 	pub fn play_sfx<Name: ToString>(&mut self, name: Name) -> Option<Handle<AudioInstance>> {
 		match self.map_tracks(name) {
 			TrackType::WithIntro(_, track) | TrackType::Single(track) => {
@@ -161,7 +229,11 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 			TrackType::Missing => None,
 		}
 	}
-
+	/// Play a new sound effect on the UI SFX channel
+	///
+	/// # Returns
+	///
+	/// A handle for the newly started audio instance, or `None` if the track was not found
 	pub fn play_ui_sfx<Name: ToString>(&mut self, name: Name) -> Option<Handle<AudioInstance>> {
 		match self.map_tracks(name) {
 			TrackType::WithIntro(_, track) | TrackType::Single(track) => {
@@ -172,6 +244,8 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 		}
 	}
 
+	/// Sync the actual volumes of each track to their values defined in the `AudioSettings` resource,
+	/// modulated by the master volume setting
 	pub fn sync_settings(&self) {
 		self.channels
 			.music_channel
@@ -187,26 +261,38 @@ impl<'w, 's, T: SuppliesAudio> MusicBox<'w, 's, T> {
 			.set_volume((self.settings.ui_volume * self.settings.master_volume) as f64);
 	}
 
+	/// Get a reference to the settings object
 	pub fn settings(&self) -> &AudioSettings {
 		&self.settings
 	}
 
+	/// Get a mutable reference to the settings object
 	pub fn settings_mut(&mut self) -> &mut AudioSettings {
 		&mut self.settings
 	}
 
+	/// Sets the master volume level, as a percentage between 0-1.
+	/// Master volume is used to adjust all of the other volume levels
 	pub fn set_master_volume(&mut self, level: f32) {
 		self.settings.master_volume = level;
 	}
+
+	/// Sets the music volume level, as a percentage between 0-1.
 	pub fn set_music_volume(&mut self, level: f32) {
 		self.settings.music_volume = level;
 	}
+
+	/// Sets the ambiance volume level, as a percentage between 0-1.
 	pub fn set_ambiance_volume(&mut self, level: f32) {
 		self.settings.ambiance_volume = level;
 	}
+
+	/// Sets the sfx volume level, as a percentage between 0-1.
 	pub fn set_sfx_volume(&mut self, level: f32) {
 		self.settings.sfx_volume = level;
 	}
+
+	/// Sets the ui sfx volume level, as a percentage between 0-1.
 	pub fn set_ui_sfx_volume(&mut self, level: f32) {
 		self.settings.ui_volume = level;
 	}
diff --git a/src/utilities.rs b/src/utilities.rs
index 1c02aa9404439422c19953095a4b73501bab1ed2..24d3a4f03dc21649d24eb912f9210a24db35c7bb 100644
--- a/src/utilities.rs
+++ b/src/utilities.rs
@@ -4,6 +4,29 @@ use bevy_kira_audio::AudioSource;
 
 use crate::music_box::MusicBox;
 
+/// This trait provides a `MusicBox` with a way of resolving a track name
+/// into usable audio resources that is generic over however you implement your
+/// asset loading
+///
+/// # Example
+///
+/// The canonical example is also included in the crate; using the `AssetServer`
+/// as a `SuppliesAudio` extension:
+///
+/// ```rust
+/// # use micro_musicbox::utilities::{TrackType, SuppliesAudio};
+/// # use bevy::prelude::*;
+///
+/// impl SuppliesAudio for AssetServer {
+/// 	fn resolve_track_name<T: ToString>(&self, name: T) -> TrackType<String> {
+/// 		TrackType::Single(name.to_string())
+/// 	}
+///
+/// 	fn get_audio_track<T: ToString>(&self, name: T) -> Option<Handle<AudioSource>> {
+/// 		Some(self.load(&name.to_string()))
+/// 	}
+/// }
+/// ```
 pub trait SuppliesAudio: Resource {
 	fn resolve_track_name<T: ToString>(&self, name: T) -> TrackType<String>;
 	fn get_audio_track<T: ToString>(&self, name: T) -> Option<Handle<AudioSource>>;
@@ -31,9 +54,14 @@ impl Default for AudioSettings {
 	}
 }
 
+/// Defines the type of track that a given name represents
 pub enum TrackType<T> {
+	/// A single audio track that should be played as-is
 	Single(T),
+	/// Represents two tracks; the first is played once as the intro, and the second track will then be looped
+	#[deprecated = "bevy_kira_audio no longer supports this functionality; the first track in the tuple will be ignored"]
 	WithIntro(T, T),
+	/// The requested track could not be found
 	Missing,
 }
 
@@ -47,6 +75,9 @@ impl SuppliesAudio for AssetServer {
 	}
 }
 
+/// A bevy system that triggers the MusicBox to sync its internal channels with
+/// the AudioSettings resource. This is automatically added when you use `MusicBoxPlugin` or
+/// `CombinedAudioPlugins`
 pub fn sync_music_volume<T: SuppliesAudio>(music: MusicBox<T>) {
 	music.sync_settings();
 }