Wiki under construction. Many concepts here are from alpha 0.2 and may still change. The wiki will be finalised for version 1.0 — for now it's here to help closed testers and, later, early-access players find their way around. For the most up-to-date and accurate info, join the Discord — that's where changes are announced first and where you can ask directly.

Join the Discord for the latest info

PFS Mail

The career inbox and action queue — action mails, decision mails, and the mailbox gate that can block the next race.

Work in progress. First draft is here, but content may evolve and screenshots are still being added. Spotted something wrong? Tell us on Discord.
On this page

PFS Mail is the career’s inbox and, more importantly, its action queue. Contract confirmations, delivered parts, scouting reports, design comparisons, calendar changes and loan offers all land here — and two kinds of mail can actively stop you starting a race weekend until you deal with them. This page covers the folders, the markers, the interactive mails and the one-season purge.

How to open it

  • Sidebar → Email (the entry is suffixed (N) when there is unread mail).
  • Hub → the INBOX panel’s View button, or click any mail row there to open Mail at that message.
  • Automatically from a deep link: several mails have in-body buttons that jump to another app and back.
  • Escape closes the app (or, if the search field is focused, just unfocuses it).

Folders

Eight entries down the left. Seven are real categories; one is computed.

FolderContents
AllEverything
ImportantComputed view — every mail where email_needs_action is true. Not a category
InboxGeneral PFS Commission / management mail
RaceWeekend reports
SponsorsSponsor negotiation, unlocks, expiries
DriversContracts, retirements, scouting, academy loans
SuppliersSupplier deals, emergency contracts, expiries
CalendarRound announcements, venue changes

Each folder shows its total count, an asterisk when it holds unread mail, and turns navy when it does. Switching folder resets the selection and the scroll.

The list is 8 rows tall and scrolls with the wheel (the markup list is not clipped, so a taller window would bleed into the preview pane below). A search box filters on sender and subject only — not on body text — and applies on top of the folder filter.

Reading the list markers

Each row carries one indicator in front of the subject. Order of precedence:

MarkerColourMeaning
(blank)This row is selected
greenA decision mail you have answered — the offer stays as the record
!redAction required — stays even after the mail is read
*redUnread
(blank)Read, nothing outstanding

Unread rows are bold navy; the selected row is white on dark blue. A small coloured phase badge on the right shows which phase the mail arrived in (phase 1 amber, 2 cyan, 3 green, 4 orange, 5 violet, in-season red).

email_needs_action is exactly three cases:

  1. The body starts with @rdx — a trait-fix redesign is ready to be manufactured and fitted.
  2. The body contains email_goto_inventory — a part has been delivered and is waiting to be fitted.
  3. The mail is a pending decision (below).

ACTION mails

These do not block anything, but the red ! persists until you act, and the Hub’s inbox panel mirrors it.

Part delivered

Carries an in-body button that jumps straight to R&D → Inventory, where you Equip the part onto a car. Leaving it unfitted is what the Next-GP race-ready gate will catch: a fitted part that is destroyed means DNS, and a car with a missing spare cannot be repaired at the track.

Trait-fix redesign (@rdx)

The body’s first line is @rdx <kind> <old-level> <new-level|solved>. It is stripped before display and rendered instead as a before → after trait chip pair — the same icons the Car app uses — so you can see at a glance whether the redesign downgraded the flaw or removed it entirely (solved shows only the “before” chip). Its button opens R&D → Production to manufacture the fixed part. See Car Traits.

The other in-body buttons

Button targetOpens
email_goto_productionR&D → Production
email_goto_inventoryR&D → Inventory
email_goto_scoutingScouting → Missions
email_goto_financeFinance
email_goto_academyDriver Academy
email_goto_marketing_missionsMarketing → Missions

DECISION mails and the Next-GP gate

A decision mail is one whose body starts with a registered marker. Today there is exactly one registered kind:

DECISION_MARKERS = ["@loan"]

Everything downstream follows automatically from that list: the inbox !, the answered ↩ glyph, the marker stripping at display time, and the Next-GP gate.

The academy-loan offer

Rolled once per GP in the post-race pass, with a 25 % chance when your Driver Academy holds at least one prospect not already out on loan. A random eligible prospect (one whose age falls inside a dev series’ age_min..age_max band) is matched to a random team in that series, and the fee is computed as:

fee = weighted_rating × (600 if PF2 else 250)     $ per Grand Prix

The body carries the payload @loan <code> <series> <fee> <team name> — team name last, because it contains spaces — followed by the offer text and two buttons: Accept the loan (green) / Decline (red). The pitch is honest about the upside: “Real racing is the best school there is: a prospect with a race seat develops noticeably faster (+5 %).”

Accepting seats the prospect in that dev team — taking a vacant race seat if there is one, otherwise pushing the weakest incumbent down to reserve — adds them to the series standings, and registers the loan so the fee is credited after every Grand Prix. income_per_gp() includes active loan fees, so the Hub and Finance projections both see it immediately.

Either answer resolves in place. The marker flips to @loan_done yes|no, the button block is cut from the body, and an outcome line is appended:

  • Accepted → ”↩ You accepted — races for for the rest of the season. The $ contribution lands after every Grand Prix. Follow the season in World Data → Series.”
  • Declined → ”↩ You declined the offer — stays with your academy.”

The mail stays in the inbox as the record, marked read, and its list row shows the green ↩ glyph. There is no undo.

The gate

When you press Next GP, the game collects every mail where email_pending_decision is true and, if any exist, refuses the advance and shows their subjects. It is checked before the race-ready (DNS) warning specifically so the two dialogs never stack. You can acknowledge and go anyway — the acknowledgement is one-shot, so the gate returns next weekend if the mail is still unanswered.

The preview pane

The right pane shows sender, subject, phase badge and the body. Bodies are HTML when they open with a real block tag (<p, <div, <table, <span, <h, <img, <ul, <b>); anything else is treated as plain text and each line is wrapped in a paragraph. That heuristic is deliberately narrow so a bare < or > in prose (“margin <5% >target”) cannot trip it into broken markup.

Leading markers are parsed and stripped in this order: @rdx@loan@<kind>_done@cal@circ. You never see them.

Embedded widgets

WidgetTriggerWhat it draws
Trait iconthe subject/body names a known traitThe trait’s icon next to the subject, with a hover tooltip
Before → after chips@rdxTwo trait chips showing the redesign’s effect
Circuit mini-map@cal <gp>That round’s layout, looked up on the calendar by GP number
Circuit mini-map@circ <turns> <distance_m> <seed>A layout drawn from the payload itself
Part icon<img src="picon_N">The component’s item icon in design-comparison mails
Driver portrait carddriver_portrait_<code>The full face+suit figure, composited live, clickableDriver Profile
Helmet / flaghelmet_<code> / flag_<code>Small header images next to a driver’s name

The @circ variant exists for one specific reason: the contract-review mail (the Commission declining to renew a venue) talks about a round that is still occupied by the outgoing venue until the rollover. A lookup by GP number would draw the wrong track — and a circuit still sitting in the world pool has no round number at all — so that mail carries the geometry with it. See Circuit Profile.

Driver portraits are built lazily, and only when the open mail actually references them. Your own drivers wear the team suit with sponsors baked on; pool and rival drivers wear a plain suit in their own colours; academy prospects wear the team kit.

Toolbar

ButtonEffect
Delete (or the Delete key)Removes the selected mail permanently
Mark readMarks the selected mail read
Mark all readMarks read only the mails in the current folder/filter, not the whole inbox

Up/Down navigate and mark-as-read as you go. The status bar reads N messages, M unread | Up/Down: Navigate | Del: Delete | Esc: Back.

The one-season purge

At the season rollover, the entire inbox is cleared — read and unread, action mails included — before the new season’s review and summary mails are pushed. The reasoning: every action window a mail refers to is season-scoped anyway, and the save pipeline rewrites the emails table from this list on every save, so the purge reaches the database at the next transition save.

Two consequences worth planning around:

  • Nothing survives the rollover. If a mail contains information you want (a contract’s exact terms, a scouting report, a venue-change notice), read it before the final GP or copy the numbers somewhere.
  • The News feed is pruned on the same one-season rule but is not wiped, so calendar and transfer stories dated to the new season survive. See News.

Advanced

  • The ! outlives read. Marking a mail read does not clear an action marker — only fitting the part or answering the offer does. Use the Important folder as your to-do list.
  • Mark-all-read is folder-scoped. Sitting in “Sponsors” and hitting it leaves everything else unread. That is intentional, and it is the fast way to clear one noisy category.
  • Search does not read bodies. Looking for the mail that mentioned a specific part will fail unless the part is in the subject line.
  • An answered decision mail is not deletable-safe. Deleting it removes the record of what you agreed to; the loan itself survives (it lives on the save, not on the mail), but the terms are gone.
  • Adding a new decision type is a one-line registry. The convention is: offer bodies start with @<kind> <payload>, answering flips them to @<kind>_done yes|no. Registering the marker in DECISION_MARKERS automatically wires the inbox !, the ↩ glyph, the display-time strip and the Next-GP gate. Useful to know when reading a mod’s mail.
  • The gate acknowledgement is per-press. Pressing “go anyway” does not permanently dismiss the mail; it blocks again at the next weekend.
  • Loan fees are counted in projections. income_per_gp() sums academy_loans[].fee_per_gp, so an accepted loan visibly moves the Hub’s net/GP and Finance’s projection.
  • Emergency supplier contracts arrive as mail, not as a dialog. If you let the negotiation window close without an engine, tyre or fuel deal, management signs the worst available option for you and tells you here.

Common mistakes

  • Treating the red ! as decoration. It is the only surface that tells you a delivered part is still in the crate — and the DNS gate will not be as polite.
  • Pressing Next GP with an unanswered loan offer. It hard-blocks. Answer it (either way) or acknowledge the warning.
  • Assuming Decline is reversible. Both answers are final and rewrite the mail in place.
  • Filtering by folder and then wondering where a mail went. “Important” is a computed view across categories, so a mail can be visible there and in Sponsors but nowhere else you were looking.
  • Relying on the inbox as an archive. It is wiped completely at every rollover.
  • Searching for body text. Only sender and subject are matched.

See also