From eb5e1885594abbf82722d5e12c82c81cdac387d0 Mon Sep 17 00:00:00 2001 From: Fritz Date: Sat, 4 Apr 2026 13:09:06 -0700 Subject: [PATCH] add doc comments for all public API and catalog Player/Party --- Sources/DHKit/AdversaryState.swift | 23 ++++++++++++++ Sources/DHKit/Compendium.swift | 2 ++ Sources/DHKit/EncounterSession.swift | 13 ++++++++ Sources/DHKit/EncounterStore.swift | 8 +++++ Sources/DHKit/EnvironmentState.swift | 7 +++++ Sources/DHKit/PlayerState.swift | 30 +++++++++++++++++++ Sources/DHKit/SessionRegistry.swift | 2 ++ .../DaggerheartModels.md | 5 ++++ Sources/DHModels/Party.swift | 8 +++++ Sources/DHModels/Player.swift | 19 ++++++++++++ 10 files changed, 117 insertions(+) diff --git a/Sources/DHKit/AdversaryState.swift b/Sources/DHKit/AdversaryState.swift index 726f200..c3cec0f 100644 --- a/Sources/DHKit/AdversaryState.swift +++ b/Sources/DHKit/AdversaryState.swift @@ -26,6 +26,7 @@ import Foundation /// which replaces values wholesale (copy-with-update pattern). nonisolated public struct AdversaryState: CombatParticipant, Codable, Sendable, Equatable, Hashable { + /// Stable slot identifier unique within the session. public let id: UUID /// The slug that identifies this adversary in the ``Compendium``. public let adversaryID: String @@ -34,17 +35,39 @@ nonisolated public struct AdversaryState: CombatParticipant, Codable, Sendable, public let customName: String? // MARK: Stat Snapshot (from catalog at creation time) + + /// Maximum HP snapshotted from the catalog entry at slot creation time. public let maxHP: Int + /// Maximum Stress snapshotted from the catalog entry at slot creation time. public let maxStress: Int // MARK: Tracked Stats + + /// Current HP; clamped to `0...maxHP` by ``EncounterSession``. public let currentHP: Int + /// Current Stress; clamped to `0...maxStress` by ``EncounterSession``. public let currentStress: Int + /// `true` once HP reaches 0. public let isDefeated: Bool + /// Active conditions on this adversary slot. public let conditions: Set // MARK: - Init + /// Creates an adversary slot with explicit stat values. + /// + /// Prefer ``init(from:customName:)`` when constructing from a catalog entry. + /// + /// - Parameters: + /// - id: Slot identifier; defaults to a new UUID. + /// - adversaryID: Catalog slug for the source adversary. + /// - customName: Optional display name override. + /// - maxHP: Maximum HP (snapshotted from catalog). + /// - maxStress: Maximum Stress (snapshotted from catalog). + /// - currentHP: Starting HP; defaults to `maxHP`. + /// - currentStress: Starting Stress; defaults to `0`. + /// - isDefeated: Whether the slot starts defeated; defaults to `false`. + /// - conditions: Initial condition set; defaults to empty. public init( id: UUID = UUID(), adversaryID: String, diff --git a/Sources/DHKit/Compendium.swift b/Sources/DHKit/Compendium.swift index f27bcea..09ecff4 100644 --- a/Sources/DHKit/Compendium.swift +++ b/Sources/DHKit/Compendium.swift @@ -26,7 +26,9 @@ import Observation /// Errors that can occur while loading compendium data. nonisolated public enum CompendiumError: Error, LocalizedError { + /// The specified bundle resource could not be located. case fileNotFound(resourceName: String) + /// A resource was found but JSON decoding failed. case decodingFailed(resourceName: String, underlying: Error) public var errorDescription: String? { diff --git a/Sources/DHKit/EncounterSession.swift b/Sources/DHKit/EncounterSession.swift index 344a206..ec58807 100644 --- a/Sources/DHKit/EncounterSession.swift +++ b/Sources/DHKit/EncounterSession.swift @@ -57,7 +57,10 @@ public final class EncounterSession: Identifiable, Hashable { private let logger = Logger(label: "EncounterSession") // MARK: Identity + + /// Stable session identifier. public let id: UUID + /// The display name for this encounter. public var name: String /// The ID of the ``EncounterDefinition`` this session was created from. @@ -98,10 +101,16 @@ public final class EncounterSession: Identifiable, Hashable { public var spotlightCount: Int // MARK: Notes + + /// Freeform notes visible to the GM during the encounter. public var gmNotes: String // MARK: - Init + /// Creates an encounter session with the given initial state. + /// + /// Prefer ``make(from:using:)`` for sessions backed by a saved definition. + /// Use this initializer for blank or test sessions. public init( id: UUID = UUID(), name: String, @@ -316,18 +325,22 @@ public final class EncounterSession: Identifiable, Hashable { // MARK: - Fear & Hope + /// Increase the GM's Fear pool by `amount`. public func incrementFear(by amount: Int = 1) { fearPool += amount } + /// Spend from the GM's Fear pool, clamping to zero. public func spendFear(by amount: Int = 1) { fearPool = max(0, fearPool - amount) } + /// Increase the party's Hope pool by `amount`. public func incrementHope(by amount: Int = 1) { hopePool += amount } + /// Spend from the party's Hope pool, clamping to zero. public func spendHope(by amount: Int = 1) { hopePool = max(0, hopePool - amount) } diff --git a/Sources/DHKit/EncounterStore.swift b/Sources/DHKit/EncounterStore.swift index 1b85d8f..935cddd 100644 --- a/Sources/DHKit/EncounterStore.swift +++ b/Sources/DHKit/EncounterStore.swift @@ -27,8 +27,11 @@ import Observation /// Errors thrown by ``EncounterStore`` operations. nonisolated public enum EncounterStoreError: Error, LocalizedError, Sendable { + /// No definition with the given ID exists in the store. case notFound(UUID) + /// Writing the definition's JSON file to disk failed. case saveFailed(UUID, String) + /// Deleting the definition's JSON file from disk failed. case deleteFailed(UUID, String) public var errorDescription: String? { @@ -93,6 +96,11 @@ public final class EncounterStore { // MARK: - Init + /// Creates a store backed by the given directory. + /// + /// The directory is not created automatically; call ``load()`` to read existing + /// files. Use ``defaultDirectory()`` to resolve the preferred iCloud or local + /// path at runtime. public init(directory: URL) { self.directory = directory } diff --git a/Sources/DHKit/EnvironmentState.swift b/Sources/DHKit/EnvironmentState.swift index 04b4206..e48b5e7 100644 --- a/Sources/DHKit/EnvironmentState.swift +++ b/Sources/DHKit/EnvironmentState.swift @@ -21,12 +21,19 @@ import Foundation nonisolated public struct EnvironmentState: EncounterParticipant, Codable, Sendable, Equatable, Hashable { + /// Stable slot identifier unique within the session. public let id: UUID /// The slug identifying this environment in the ``Compendium``. public let environmentID: String /// Whether this environment element is currently active/visible to players. public let isActive: Bool + /// Creates an environment slot. + /// + /// - Parameters: + /// - id: Slot identifier; defaults to a new UUID. + /// - environmentID: Catalog slug for the source environment. + /// - isActive: Whether the element is initially active; defaults to `true`. public init( id: UUID = UUID(), environmentID: String, diff --git a/Sources/DHKit/PlayerState.swift b/Sources/DHKit/PlayerState.swift index 7dcf55c..5379ff1 100644 --- a/Sources/DHKit/PlayerState.swift +++ b/Sources/DHKit/PlayerState.swift @@ -25,18 +25,27 @@ import Foundation /// Tracks combat-relevant PC stats the GM needs to resolve hits and /// track health during play. The full character sheet remains with the player. nonisolated public struct PlayerState: CombatParticipant, Codable, Sendable, Equatable, Hashable { + /// Stable slot identifier unique within the session. public let id: UUID + /// The player character's name. public let name: String // MARK: Hit Points + + /// Maximum hit points. public let maxHP: Int + /// Current HP; clamped to `0...maxHP` by ``EncounterSession``. public let currentHP: Int // MARK: Stress + + /// Maximum stress. public let maxStress: Int + /// Current Stress; clamped to `0...maxStress` by ``EncounterSession``. public let currentStress: Int // MARK: Defense + /// The DC for all rolls made against this PC. public let evasion: Int /// Damage at or above this triggers a Major hit (mark 2 HP). @@ -45,16 +54,37 @@ nonisolated public struct PlayerState: CombatParticipant, Codable, Sendable, Equ public let thresholdSevere: Int // MARK: Armor + /// Total Armor Score (number of Armor Slots available). public let armorSlots: Int /// Remaining unused Armor Slots. public let currentArmorSlots: Int // MARK: Conditions + + /// Active conditions on this player slot. public let conditions: Set // MARK: - Init + /// Creates a player slot with explicit stat values. + /// + /// In most cases prefer creating a ``PlayerConfig`` and letting + /// ``EncounterSession/make(from:using:)`` build the slot automatically. + /// + /// - Parameters: + /// - id: Slot identifier; defaults to a new UUID. + /// - name: The player character's name. + /// - maxHP: Maximum hit points. + /// - currentHP: Starting HP; defaults to `maxHP`. + /// - maxStress: Maximum stress. + /// - currentStress: Starting Stress; defaults to `0`. + /// - evasion: The DC for rolls made against this PC. + /// - thresholdMajor: Damage threshold for a Major hit. + /// - thresholdSevere: Damage threshold for a Severe hit. + /// - armorSlots: Total Armor Score. + /// - currentArmorSlots: Remaining Armor Slots; defaults to `armorSlots`. + /// - conditions: Initial condition set; defaults to empty. public init( id: UUID = UUID(), name: String, diff --git a/Sources/DHKit/SessionRegistry.swift b/Sources/DHKit/SessionRegistry.swift index 47aa4f8..b860850 100644 --- a/Sources/DHKit/SessionRegistry.swift +++ b/Sources/DHKit/SessionRegistry.swift @@ -34,8 +34,10 @@ import Observation @MainActor @Observable public final class SessionRegistry { + /// All live sessions currently held by this registry, keyed by definition ID. public private(set) var sessions: [UUID: EncounterSession] = [:] + /// Creates an empty session registry. public init() {} /// Return the existing session for `definition.id`, or create and store a new one. diff --git a/Sources/DHModels/DaggerheartModels.docc/DaggerheartModels.md b/Sources/DHModels/DaggerheartModels.docc/DaggerheartModels.md index 8858247..63f1e49 100644 --- a/Sources/DHModels/DaggerheartModels.docc/DaggerheartModels.md +++ b/Sources/DHModels/DaggerheartModels.docc/DaggerheartModels.md @@ -27,6 +27,11 @@ ecosystem. - ``DaggerheartEnvironment`` +### Players and Parties + +- ``Player`` +- ``Party`` + ### Encounters - ``EncounterDefinition`` diff --git a/Sources/DHModels/Party.swift b/Sources/DHModels/Party.swift index 1e1aaee..6d8c6f2 100644 --- a/Sources/DHModels/Party.swift +++ b/Sources/DHModels/Party.swift @@ -19,11 +19,19 @@ import Foundation /// from those IDs is the store's responsibility. A player may belong to /// multiple parties. nonisolated public struct Party: Codable, Sendable, Equatable, Hashable, Identifiable { + /// A stable identifier for this party. public let id: UUID + /// The party's display name. public var name: String /// Ordered list of player IDs; order determines display order. public var playerIDs: [UUID] + /// Creates a party. + /// + /// - Parameters: + /// - id: Stable identifier; defaults to a new UUID. + /// - name: The party's display name. + /// - playerIDs: Ordered list of player IDs. Order determines display order. public init( id: UUID = UUID(), name: String, diff --git a/Sources/DHModels/Player.swift b/Sources/DHModels/Player.swift index ffb5850..cba4172 100644 --- a/Sources/DHModels/Player.swift +++ b/Sources/DHModels/Player.swift @@ -22,15 +22,34 @@ import Foundation /// Use ``asConfig()`` to snapshot a `Player` into a ``PlayerConfig`` for /// use in an ``EncounterDefinition``. nonisolated public struct Player: Codable, Sendable, Equatable, Hashable, Identifiable { + /// A stable identifier for this player record. public let id: UUID + /// The player character's name. public var name: String + /// Maximum hit points for this character. public var maxHP: Int + /// Maximum stress for this character. public var maxStress: Int + /// The difficulty class for rolls made against this character. public var evasion: Int + /// Damage threshold for a Major hit (marks 2 HP). public var thresholdMajor: Int + /// Damage threshold for a Severe hit (marks 3 HP). public var thresholdSevere: Int + /// Total number of Armor Slots available to this character. public var armorSlots: Int + /// Creates a player record. + /// + /// - Parameters: + /// - id: Stable identifier; defaults to a new UUID. + /// - name: The player character's name. + /// - maxHP: Maximum hit points. + /// - maxStress: Maximum stress. + /// - evasion: The DC for rolls made against this PC. + /// - thresholdMajor: Damage threshold for a Major hit. + /// - thresholdSevere: Damage threshold for a Severe hit. + /// - armorSlots: Total Armor Score (number of Armor Slots). public init( id: UUID = UUID(), name: String,