Gameplay content

Pay and payday

How jobs are paid, how to set a job's pay schedule in mod data, and how a mod marks a day unpaid.

A job's salary (Game:setSalary, read with Game:getSalary) is a monthly amount in US dollars. The game pays it by itself: never pay wages from your mod, or the player is paid twice.

  • Shift by shift. Each worked shift adds the salary divided by the days of that month, times 7 / the shifts in a week, so a full week pays the whole salary. A day off adds nothing; a missed shift is unpaid (see Jobs). A job with no hours or nowhere to be is paid every day, as before. Starting or leaving mid-period, a raise, a cut or a new job are all counted by the day.
  • Payday depends on the job (below). The period's sum goes to cash once, through the ledger (key payroll:<period>), with a notification. A long sleep pays every period in it, in order; a load never pays one again.
  • If the cash cannot hold it (the money stat's cap), the pay waits and is tried again each day.
  • The wallet on the map's rail shows the job, how it is paid, what has been earned so far, the next payday and the last payslip.
  • Rent and tuition are stored values that nothing charges; payroll does not charge them either.

Pay schedules are mod data

Payroll/*.ulpay in any mod says when a job is paid:

lua-- ynl_Nightlife/Payroll/nightlife.ulpay
return {
    titles = {
        ["Bartender"] = { every = "weekly", weekday = 5 },   -- paid every Friday
        ["Promoter"] = "daily",
    },
    workplaces = {
        nightclub = { every = "biweekly", weekday = 4 },    -- any job whose workplace is a nightclub
    },
}
every Paid
"monthly" On the 1st, for the month before. The default.
"biweekly" Every other weekday (0 = Sunday ... 6 = Saturday), counted from the start of the game.
"weekly" Every weekday.
"daily" After each day.

A job's title (as Actor:setJob wrote it) is looked up first, then its workplace's venue tag, then default. Later mods override entries one by one. ul_Base ships Payroll/schedules.ulpay with the default (monthly).

From Lua

Call Does
Payroll:status() { salary, title, workplace, schedule, period, accrued, daysWorked, daysUnpaid, nextPayday, lastPaid }
Payroll:unpaid(mod, atHours) The game day containing atHours is not paid: a missed shift your mod knows about. false for a day already counted. Paid leave needs nothing: a day off still counts.
Payroll:history() The payslips kept, oldest first: period, label, daysWorked, daysUnpaid, accrued, paid, settled, payday.
Payroll:version() The API version, 1.