Module:MissionaryDeploymentCorum: Difference between revisions

From MicrasWiki
Jump to navigationJump to search
NewZimiaGov (talk | contribs)
Created page with "-- Module: MissionaryDaily -- Purpose: Daily, in-world report of missionary activities (pre-CRH), aligned with guardrails local p = {} ------------------------------------------------------------------------------- -- (A) PSSC DATE ------------------------------------------------------------------------------- local function getPSSCDate() local startDate = os.time({year = 1999, month = 8, day = 6}) local secondsInDay = 86400 local daysPerYear = 183 lo..."
 
NewZimiaGov (talk | contribs)
No edit summary
Line 53: Line 53:
     {name="Nortonian Zones",      kind="GM"},
     {name="Nortonian Zones",      kind="GM"},
     {name="Wallisian Zones",    kind="GM"},
     {name="Wallisian Zones",    kind="GM"},
     {name="Alindan Culture",  kind="GM"},
     {name="Alindan Zones",  kind="GM"},
     {name="Aijiac Zones",                          kind="GM"},
     {name="Aijiac Zones",                          kind="GM"},
}
}

Revision as of 23:06, 9 September 2025

Documentation for this module may be created at Module:MissionaryDeploymentCorum/doc

-- Module: MissionaryDaily
-- Purpose: Daily, in-world report of missionary activities (pre-CRH), aligned with guardrails
local p = {}

-------------------------------------------------------------------------------
-- (A) PSSC DATE
-------------------------------------------------------------------------------
local function getPSSCDate()
    local startDate = os.time({year = 1999, month = 8, day = 6})
    local secondsInDay  = 86400
    local daysPerYear   = 183
    local now           = os.time()
    local totalDays     = math.floor((now - startDate) / secondsInDay)
    local yearFraction  = totalDays / daysPerYear
    local psscYear      = math.floor(yearFraction)
    local dayOfYear     = math.floor((yearFraction - psscYear) * daysPerYear) + 1

    local month, dayOfMonth
    if dayOfYear <= 61 then
        month = 1; dayOfMonth = dayOfYear
    elseif dayOfYear <= 122 then
        month = 2; dayOfMonth = dayOfYear - 61
    else
        month = 3; dayOfMonth = dayOfYear - 122
    end

    local dateString = string.format("%d/%d/%d PSSC", dayOfMonth, month, psscYear)
    return { text = dateString, year = psscYear, dayOfYear = dayOfYear }
end

-------------------------------------------------------------------------------
-- (B) STATIC DATA (pre-CRH deployment model)
-------------------------------------------------------------------------------
-- Units (fixed, as announced 13/1/51 PSSC)
local units = {
    {order="Celestial Harmony Sect",        unit="Kleisthenes", headcount=25, code="CHS-K1"},
    {order="Reverie Nebulous",              unit="Kleisthenes", headcount=25, code="REN-K1"},
    {order="Temple Alabaster",              unit="Kleisthenes", headcount=25, code="ALB-K1"},
    {order="Sanctum Delphica",              unit="Kleisthenes", headcount=25, code="DEL-K1"},
    {order="Order of the Umbral Oracle",    unit="Dodekade",    headcount=12, code="UMO-D1"},
    {order="Order of the Umbral Oracle",    unit="Hetairos",    headcount=6,  code="UMO-H1"},
}

-- Districts (Corum geography; historic New Zimia & Bayen/Gamesman locales only)
-- kind = "NZ" (New Zimian heritage) or "GM" (Bayen/Gamesman heritage)
local districts = {
    {name="Lyvian Zones",        kind="NZ"},
    {name="Lucinarian Zones",                kind="NZ"},
    {name="Brentonian Zones",                 kind="NZ"},
    {name="Brentonian Culture",   kind="NZ"},
    {name="Ossyani Zones",             kind="NZ"},
    {name="Sinclarian Zones",     kind="GM"},
    {name="Nortonian Zones",       kind="GM"},
    {name="Wallisian Zones",    kind="GM"},
    {name="Alindan Zones",  kind="GM"},
    {name="Aijiac Zones",                          kind="GM"},
}

-- Activities (mandated only)
local activities = {
    {name="relief"},         -- medical/aid distribution
    {name="education"},      -- instruction, literacy, catechesis
    {name="reconciliation"}, -- mediation, community dialogues
}

-- Observers (neutral/independent)
local observerPool = {
    {label="Neutral temple auditor",                weight=4},
    {label="Independent port compliance inspector", weight=3},
    {label="Community elder (witness)",             weight=3},
    {label="Straits Convention monitor (civilian)", weight=2},
    {label="No observer (weather delay)",           weight=1},
}

-- Compliance notes (HCE & kit checks)
local kitNotes = {
    "HCE log filed; roster posted; kit verified (no encryption/UAV/sensors)",
    "Kit verified; spot-check passed; HCE reference filed",
    "HCE log filed; minor inventory variance (expiry) corrected same-day",
}

-------------------------------------------------------------------------------
-- (C) HELPERS
-------------------------------------------------------------------------------
local function pick(list, seedRoll)
    local idx = (seedRoll and ((seedRoll % #list) + 1)) or math.random(#list)
    return list[idx]
end

local function pickWeighted(list)
    local total = 0
    for _, item in ipairs(list) do total = total + (item.weight or 1) end
    local roll, cumul = math.random(total), 0
    for _, item in ipairs(list) do
        cumul = cumul + (item.weight or 1)
        if roll <= cumul then return item end
    end
    return list[#list]
end

local function outputsFor(activityName)
    if activityName == "relief" then
        local patients = math.random(18, 64)
        local parcels  = math.random(40, 140)
        return string.format("patients seen: %d; relief parcels: %d", patients, parcels)
    elseif activityName == "education" then
        local classes  = math.random(1, 3)
        local students = math.random(24, 90)
        return string.format("classes: %d; learners served: %d", classes, students)
    else -- reconciliation
        local circles    = math.random(1, 4)
        local agreements = math.random(0, math.min(circles, 3))
        return string.format("mediation circles: %d; agreements reached: %d", circles, agreements)
    end
end

local function observerLine()
    local obs = pickWeighted(observerPool)
    if obs.label == "No observer (weather delay)" then
        return "Observer: n/a (weather delay); affidavits to follow"
    else
        return "Observer present: " .. obs.label
    end
end

local function hceRef(dateInfo, unitCode)
    return string.format("HCE-%03d.%03d-%s", dateInfo.year, dateInfo.dayOfYear, unitCode)
end

local function guardrailsStatus()
    local roll = math.random()
    if roll < 0.08 then
        return "Geofence: route adjusted (+1.6 km buffer); Separation: ✓; No-contact log: signed"
    elseif roll < 0.95 then
        return "Geofence: ✓; Separation: ✓; No-contact log: signed"
    else
        return "Mission deferred (no-go buffer triggered); rescheduled next window"
    end
end

-------------------------------------------------------------------------------
-- (D) MAIN TABLE
-------------------------------------------------------------------------------
function p.makeTable(frame)
    local dateInfo = getPSSCDate()
    math.randomseed(dateInfo.year * 1000 + dateInfo.dayOfYear)
    local rows = tonumber(frame and frame.args and frame.args.rows) or 12

    local out = {}
    table.insert(out, "{| class='wikitable sortable'")
    table.insert(out, "! Date !! District !! Order / Unit (Headcount) !! Activity !! Outputs !! Observer Verification !! HCE / Kit Compliance !! Guardrails / Notes")

    for _ = 1, rows do
        local u   = pick(units)
        local d   = pick(districts)
        local act = pick(activities)
        local outputs = outputsFor(act.name)
        local obsLine = observerLine()
        local hceLine = string.format("%s; %s", hceRef(dateInfo, u.code), pick(kitNotes))
        local guards  = guardrailsStatus()

        if guards:match("deferred") then
            outputs = "n/a (deferred)"
            obsLine = "Observer: n/a (deferred)"
            hceLine = hceRef(dateInfo, u.code) .. "; pre-mission check only"
        end

        local unitStr = string.format("%s — %s (%d) [%s]", u.order, u.unit, u.headcount, u.code)
        table.insert(out, "|-")
        table.insert(out, string.format("| %s || %s || %s || %s || %s || %s || %s || %s",
            dateInfo.text, d.name, unitStr, act.name, outputs, obsLine, hceLine, guards))
    end

    table.insert(out, "|}")
    return table.concat(out, "\n")
end

return p