namespace LivingVillage.Kernel /// Occupation system first slice (design §1/§2, docs/design/occupation-system-design.md). /// Data lives beside the player only — NPCs are never occupied. /// Nothing here runs inside Sim.step; WorldBootstrap stamps the profile onto the /// world's avatar at creation time, which keeps the numeric state path untouched. module Occupation = type Kind = | Farmer | Fisher | Peddler | Scholar /// Chinese labels, shared for a later UI slice (农夫 / 渔夫 / 货郎 / 书生). let nameOf (kind: Kind) : string = match kind with | Farmer -> "农夫" | Fisher -> "渔夫" | Peddler -> "货郎" | Scholar -> "书生" let saveToken (kind: Kind) : string = match kind with | Farmer -> "farmer" | Fisher -> "fisher" | Peddler -> "peddler" | Scholar -> "scholar" let all : Kind list = [ Farmer; Fisher; Peddler; Scholar ] type Profile = { Kind: Kind InitialMoney: int InitialEnergy: float32 InitialInventory: (Sim.ItemKind * int) list } /// Initial values straight from the approved design §1 table. let profileOf (kind: Kind) : Profile = match kind with | Farmer -> { Kind = Farmer; InitialMoney = 60; InitialEnergy = 100.0f; InitialInventory = [ Sim.Food, 12 ] } | Fisher -> { Kind = Fisher; InitialMoney = 45; InitialEnergy = 95.0f; InitialInventory = [ Sim.Food, 8; Sim.Fish, 3 ] } | Peddler -> { Kind = Peddler; InitialMoney = 90; InitialEnergy = 100.0f; InitialInventory = [ Sim.Food, 6; Sim.Spice, 4 ] } | Scholar -> { Kind = Scholar; InitialMoney = 70; InitialEnergy = 100.0f; InitialInventory = [ Sim.Food, 10; Sim.Scroll, 2 ] } /// Placeholder carried in save v3 until the task-system slice lands (design §3). type State = { Profile: Profile TaskToken: int StoryStage: int } let stateOf (kind: Kind) : State = { Profile = profileOf kind; TaskToken = 0; StoryStage = 0 }