Skip to content

Commit

Permalink
Enhance docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
hohav committed Mar 30, 2024
1 parent ca54e61 commit 1410893
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 9 deletions.
12 changes: 12 additions & 0 deletions src/frame/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
//! Frame data representation.
//!
//! Peppi represents frame data using Arrow arrays (i.e. "struct-of-arrays").
//! This allows us to efficiently share frame data with other languages,
//! and enables simple serialization into a highly-compressible disk format.
//!
//! The mutable/immutable distinction is essentially an artifact of the underlying Arrow library.
//! You'll only encounter mutable data if you're parsing live games.
use crate::game::Port;

pub mod immutable;
Expand All @@ -7,12 +16,15 @@ pub mod transpose;
/// Frame indexes start at -123, and reach 0 at "Go!".
pub const FIRST_INDEX: i32 = -123;

/// Port number plus ICs-specific discriminant.
#[derive(Clone, Copy, Debug)]
pub struct PortOccupancy {
pub port: Port,
/// For ICs, distinguishes between Nana and Popo.
pub follower: bool,
}

/// Rollback-aware processing typically ignores all but the first or last rollback for a frame.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Rollbacks {
ExceptFirst,
Expand Down
20 changes: 20 additions & 0 deletions src/game/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//! A single game of Super Smash Brothers Melee.
//!
//! The mutable/immutable distinction is essentially an artifact of the underlying Arrow library.
//! You'll only encounter mutable data if you're parsing live games.
use std::fmt::{self, Debug, Display, Formatter};

use num_enum::{IntoPrimitive, TryFromPrimitive};
Expand All @@ -14,10 +19,16 @@ pub mod immutable;
pub mod mutable;
pub mod shift_jis;

/// How many ports the game supports.
pub const NUM_PORTS: usize = 4;

/// Some modes allow more characters than ports, e.g. Cruel Melee.
pub const MAX_PLAYERS: usize = 6;

/// Since ICs are unique mechanically, sometimes we need to treat them specially.
pub const ICE_CLIMBERS: u8 = 14;

/// A slot that can be occupied by a player.
#[repr(u8)]
#[derive(
Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, IntoPrimitive, TryFromPrimitive,
Expand Down Expand Up @@ -59,6 +70,7 @@ impl Default for Port {
}
}

/// How a player is controlled.
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, TryFromPrimitive)]
pub enum PlayerType {
Expand All @@ -67,26 +79,30 @@ pub enum PlayerType {
Demo = 2,
}

/// Information about the team a player belongs to.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub struct Team {
pub color: u8,
pub shade: u8,
}

/// Dashback fix type.
#[repr(u32)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, TryFromPrimitive)]
pub enum DashBack {
Ucf = 1,
Arduino = 2,
}

/// Shield drop fix type.
#[repr(u32)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, TryFromPrimitive)]
pub enum ShieldDrop {
Ucf = 1,
Arduino = 2,
}

/// The language the game is set to.
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, TryFromPrimitive)]
pub enum Language {
Expand Down Expand Up @@ -158,12 +174,14 @@ pub struct Player {
pub netplay: Option<Netplay>,
}

/// Major & minor scene numbers.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub struct Scene {
pub minor: u8,
pub major: u8,
}

/// Container for raw bytes of `Start` & `End` events.
#[derive(PartialEq, Eq, Clone)]
pub struct Bytes(pub Vec<u8>);

Expand All @@ -173,6 +191,7 @@ impl Debug for Bytes {
}
}

/// Information about the match a game belongs to.
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
pub struct Match {
pub id: String,
Expand Down Expand Up @@ -233,6 +252,7 @@ pub struct Start {
pub r#match: Option<Match>,
}

/// How the game ended.
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, TryFromPrimitive)]
pub enum EndMethod {
Expand Down
2 changes: 2 additions & 0 deletions src/game/shift_jis.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Melee's internal string encoding.
use encoding_rs::SHIFT_JIS;
use serde::Serialize;

Expand Down
5 changes: 5 additions & 0 deletions src/io/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! Serialization and deserialization of replays.
//!
//! Peppi supports reading and writing both `.slp` (Slippi) and `.slpp` (Peppi) replays.
macro_rules! err {
($( $arg: expr ),*) => {
crate::io::Error::InvalidData(format!($( $arg ),*))
Expand All @@ -15,6 +19,7 @@ use std::io::{Read, Seek, SeekFrom};
use thiserror::Error as ThisError;
use xxhash_rust::xxh3::Xxh3;

/// An error encountered while serializing or deserializing a replay.
#[derive(ThisError, Debug)]
pub enum Error {
#[error("invalid data: {0}")]
Expand Down
1 change: 1 addition & 0 deletions src/io/peppi/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ fn read_peppi_gecko_codes<R: Read>(mut r: R) -> Result<game::GeckoCodes> {
})
}

/// Reads a Peppi (`.slpp`) replay from `r`.
pub fn read<R: Read>(r: R, opts: Option<&Opts>) -> Result<Game> {
let mut start: Option<game::Start> = None;
let mut end: Option<game::End> = None;
Expand Down
9 changes: 6 additions & 3 deletions src/io/peppi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ use crate::{
pub use de::read;
pub use ser::write;

/// Current version of the Peppi format
/// Current version of the Peppi format.
pub const CURRENT_VERSION: Version = Version(2, 0, 0);

/// Minimum supported version of the Peppi format for reading
/// Minimum supported version of the Peppi format for reading.
pub const MIN_VERSION: Version = Version(2, 0, 0);

/// Peppi files are TAR archives, guaranteed to start with `peppi.json`
/// Peppi files are TAR archives, guaranteed to start with `peppi.json`.
pub const FILE_SIGNATURE: [u8; 10] = [0x70, 0x65, 0x70, 0x70, 0x69, 0x2e, 0x6a, 0x73, 0x6f, 0x6e];

/// Peppi format version.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
pub struct Version(pub u8, pub u8, pub u8);

Expand Down Expand Up @@ -51,12 +52,14 @@ impl Default for Version {
}
}

/// Compression algorithms supported by Arrow.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub enum Compression {
LZ4,
ZSTD,
}

/// Peppi format options.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Peppi {
pub version: Version,
Expand Down
7 changes: 7 additions & 0 deletions src/io/peppi/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ use crate::{
/// Options for writing Peppi files.
#[derive(Clone, Debug, Default)]
pub struct Opts {
/// Internal compression to use, if any.
///
/// Use this to maximize read speed while saving some disk space (e.g. for machine learning).
/// If you just want maximum compression, compress the entire `.slpp` file instead.
pub compression: Option<Compression>,
}

Expand All @@ -32,6 +36,9 @@ fn tar_append<W: Write, P: AsRef<Path>>(
Ok(())
}

/// Writes a replay to `w` in Peppi (`.slpp`) format.
///
/// Returns an error if the game's version is higher than `MAX_SUPPORTED_VERSION`.
pub fn write<W: Write>(w: W, game: Game, opts: Option<&Opts>) -> Result<(), Box<dyn Error>> {
slippi::assert_max_version(game.start.slippi.version)?;

Expand Down
2 changes: 1 addition & 1 deletion src/io/slippi/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ pub fn parse_metadata<R: Read>(
Ok(())
}

/// Reads a Slippi-format game from `r`.
/// Reads a Slippi (`.slp`) replay from `r`.
pub fn read<R: Read + Seek>(r: R, opts: Option<&Opts>) -> Result<Game> {
let hash = opts.map_or(false, |o| o.compute_hash);
// Wrap so we can hash all the bytes we've read at the end.
Expand Down
10 changes: 6 additions & 4 deletions src/io/slippi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ use crate::io::{parse_u8, Error, Result};
pub use de::read;
pub use ser::write;

/// We can read replays with higher versions than this, but that discards information.
/// We don't support writing these replays as a result, though this restriction may be
/// relaxed in the future.
/// Peppi can read replays with higher versions than this, but that discards information.
/// So we refuse to re-serialze such replays, to avoid inadvertent information loss.
/// This restriction may be removed in the future.
pub const MAX_SUPPORTED_VERSION: Version = Version(3, 16, 0);

/// Every .slp file will start with a UBJSON opening brace, `raw` key & type: "{U\x03raw[$U#l"
/// Every `.slp` file starts with a UBJSON opening brace, "raw" key & type (`{U\x03raw[$U#l`).
pub const FILE_SIGNATURE: [u8; 11] = [
0x7b, 0x55, 0x03, 0x72, 0x61, 0x77, 0x5b, 0x24, 0x55, 0x23, 0x6c,
];

/// Slippi format version.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
pub struct Version(pub u8, pub u8, pub u8);

Expand Down Expand Up @@ -53,6 +54,7 @@ impl fmt::Display for Version {
}
}

/// Slippi format options.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
pub struct Slippi {
pub version: Version,
Expand Down
3 changes: 2 additions & 1 deletion src/io/slippi/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ fn gecko_codes_size(gecko_codes: &GeckoCodes) -> u32 {
num_blocks * (512 + 5)
}

/// Writes a Slippi-format game to `w`.
/// Writes a replay to `w` in Slippi (`.slp`) format.
///
/// Returns an error if the game's version is higher than `MAX_SUPPORTED_VERSION`.
pub fn write<W: Write>(w: &mut W, game: &Game) -> Result<()> {
slippi::assert_max_version(game.start.slippi.version)?;
Expand Down

0 comments on commit 1410893

Please sign in to comment.