# Change Request CR-001 — Faster Start **Project:** Deadhead: Space Freight Tycoon **Applies to:** a build with Phases 1–10 complete **Do this:** as a new **Phase 10A**, before starting Phase 11 **Related docs:** `implementation-plan.md`, `game-design-document.md`, `DECISIONS.md` > **Numbering note (added when implemented):** the plan's §0.5 already used decisions 21–28. The new decisions below numbered 0.5.21–0.5.26 are recorded in the plan as **0.5.29–0.5.34** in the same order (21→29 Loaner ship, 22→30 The deal, 23→31 Handling time, 24→32 Loan, 25→33 Scripted tutorial contracts, 26→34 Onboarding goals). The error code `tutorial_active` is implemented as `tutorial-active`, matching the existing kebab-case codes. --- ## 1. Why Playtesting shows the opening is slow and has no hook. The current tutorial asks the player to fly the same Earth→Moon run 15–25 times (45–120 real minutes) before they own anything. There are no choices, no stakes, and the interesting systems (owning ships, discovery, hiring) are an hour or more away. This change keeps the employee opening but cuts it to about four quick runs, gives the player a ship on credit right after, puts a real choice on the board from the first minute, shows the whole map from the start, and adds a short list of first-session goals. ## 2. Target experience | Milestone | Target (real time, active play) | |---|---| | First dispatch | Under 30 seconds from "Start your company" | | First real choice between contracts | Under 2 minutes | | Own a ship (deal accepted) | Under 10 minutes | | Buy a ship from the Market *(changed by CR-013; was: Buy a second ship (CR-010), Hire first pilot)* | 45–75 minutes | | First discovery | Within 90 minutes | | Loan paid off *(added by CR-013)* | Within roughly the first two sessions (under 4 hours of active play) | ### New opening, in order 1. Player taps "Start your company" and lands straight on the tutorial contract board with a two-line intro. 2. The board offers **three** contracts with different mass, pay, trip time, and XP. The loaner ship is a fast company Courier, so each run takes under a minute. 3. On the third run, the board includes one scripted special contract ("Unmarked crates — double pay, no questions asked"). 4. After four runs (back at Earth), the company owner offers *(amended by CR-017: after five runs)* to sell the player his old Courier **and** his Earth bay lease **on credit**. 5. The player accepts. They now own a ship and an Earth bay, owe a loan, and the tutorial is over. A cut of every payout goes to the lender until the loan is paid. 6. HQ shows a short list of goals with credit rewards to guide the first session. 7. From the first screen, the map shows every location; undiscovered ones are locked, and each one says which ship can reach it. ## 3. Rules for this change - All rules in `implementation-plan.md` §0.1 still apply: steps in order, one commit per step, each step's test must pass, `packages/sim` stays pure, all numbers live in `packages/content`. - **Do not write data migrations for old tutorial state.** There are no production players. Resetting the dev and test databases is fine. Schema migrations are still required. - Dispatches already stored keep their stored arrival times. Changes to the travel-time formula only affect new dispatches. - Update existing tests whose expectations change. Do not delete a test unless §6 says the step is replaced. - Update `architecture.md` for every schema or API change and `progress.md` after every step. - Stop for the user's review at the end of Phase 10A. ## 4. Decision changes Record these in `DECISIONS.md` and in `implementation-plan.md` §0.5. **Replaced** - **0.5.4 (Tutorial end)** → The tutorial ends when the player accepts the deal (see 0.5.22). Buying a ship and leasing an Earth bay no longer ends it. - **0.5.16 (Tutorial purchases)** → During the tutorial, buying ships, leasing bays, and hiring pilots are blocked with a `tutorial_active` error. **Amended** - **0.5.3 (Tutorial movement)** → Unchanged, except the tutorial board now has three contracts with different masses (0.5.23), and the loaner is a dedicated content ship (0.5.21). **New** - **0.5.21 Loaner ship.** The loaner is its own ship model, "Company Courier", marked not purchasable. It is faster and has lower overhead than the player's Courier so tutorial runs take under one real minute. - **0.5.22 The deal.** *(Plan 0.5.30; amended by CR-017: five runs, and the loaner may be anywhere.)* Once the player has completed at least the configured number of tutorial runs and the loaner is at Earth with nothing in flight, a one-time deal becomes available. Accepting it removes the loaner, gives the player a Courier and an Earth bay, assigns the avatar to that Courier, sets the loan balance, and ends the tutorial. There is no decline option. - **0.5.23 Handling time.** Travel time gains a loading/unloading term: `travel time = distance ÷ cruise speed + overhead + cargo mass × handling time per tonne`. Repositions carry zero mass. Because XP is per delivery and pay is per tonne, light contracts earn more XP per minute and heavy contracts earn more credits per minute. That is the tradeoff on every board. - **0.5.24 Loan.** The company has a loan balance. When a dispatch resolves with positive credits (after pilot pay), the lender takes `min(balance, credits × repayment share)`. The player can also pay down any amount up to the balance at any time. No interest, no missed payments, no fail state. - **0.5.25 Scripted tutorial contracts.** Content can define special tutorial contracts keyed to a tutorial run number. A scripted contract replaces one board slot on that run and can carry a custom name, pay multiplier, and a flavor message shown after delivery. - **0.5.26 Onboarding goals.** A fixed, ordered list of goals in content, each with a condition evaluated from player state and a one-time credit reward the player claims. Goals appear after the tutorial ends. ## 5. Steps — Phase 10A ### Step 10A.1 — Content: new config and loaner ship - Add a `purchasable` flag to ShipModel. Add a "Company Courier" ship model with `purchasable` false, faster than the Courier, with low overhead and enough capacity for the tutorial board's heaviest contract. - Add GameConfig fields: tutorial runs before the deal (default 4); tutorial board size (3); tutorial mass tiers (light, medium, full); handling time per tonne (game hours); loan repayment share (default 0.3); deal loan amount (default: Courier price + Earth bay lease). Lower starting credits to a small cushion (a few fuel loads). - Add a scripted tutorial contract entry: run 3, name "Unmarked crates", Standard cargo, pay multiplier 2, and a flavor message after delivery (for example: "Nobody asked what was inside. You got paid. Licensed hazardous-cargo pilots earn this kind of money every run."). - Add the onboarding goals list (see Step 10A.5 for conditions) with rewards. - **Amended by CR-017:** Tutorial runs before the deal default 5; a tutorial XP multiplier (default 2) joins GameConfig (Step 17.1). - **Test:** All content still validates through its schemas. The Market's list of purchasable ships does not include Company Courier. Every scripted contract and goal references valid ids. Deal loan amount is greater than zero. ### Step 10A.2 — Sim: handling time - Add the handling term to the travel-time function (decision 0.5.23). - Update the Step 3.5 hand-calculated test to include handling time. - **Test:** On the same route with the same ship, a heavier contract takes longer than a lighter one. A reposition (zero mass) gives the same time as the old formula. Company Courier Earth→Moon at full tutorial load takes under 1 game hour (under 1 real minute at compression 60). ### Step 10A.3 — Sim: tutorial board v2 - The tutorial board generator takes one more input: the number of tutorial runs completed. - It returns three Standard contracts from the loaner's current location to the other end of the Earth–Moon route, at the light, medium, and full mass tiers, each paying the tutorial share. - If a scripted contract is keyed to the upcoming run number, it replaces the medium slot. - Update the Step 3.10 tests to match. - **Test:** The board has exactly three contracts with three different masses, all within Company Courier capacity. Same inputs give an identical board. With two runs completed, the "Unmarked crates" contract appears at double pay; with any other count, it does not. The light contract gives more XP per real minute than the full one, and the full one gives more credits per real minute than the light one. The sum of the four slowest possible tutorial trip times is under 6 real minutes. - **Amended by CR-007:** Tutorial contracts carry named Standard goods made at the loaner's location and wanted at the other end (never Priority); masses stay at the three tiers (Step 10G.5). - **Amended by CR-017:** The timing test covers the five slowest runs, under 7 real minutes; tutorial runs earn double XP (Steps 17.2, 17.3). ### Step 10A.4 — Sim: loan repayment - Add a pure function that splits a credit amount into repayment and net, given the loan balance and repayment share. - Dispatch resolution now returns the repayment amount alongside the credits to add. - **Test:** Repayment equals `min(balance, credits × share)`. Repayment is zero when the balance is zero or the credits are zero or negative. Net plus repayment equals the original credits. Repayment never exceeds the balance. ### Step 10A.5 — Sim: onboarding goal evaluation - Add a pure function that takes a player state summary and returns which goals are complete. - Goals, in order: 1. Deliver a contract with your own ship. 2. Spend your first skill point. 3. Buy a second ship. 4. Hire your first pilot. 5. Discover a new location. 6. Pay off your loan. - **Test:** For each goal, a state summary just short of the condition reports it incomplete, and a summary that meets it reports it complete. Results are identical for identical inputs. - **Amended by CR-010:** Goal 4 "Hire your first pilot" is now "Fly a contract with [veteran's name]" (`veteran-contract`, Step 10J.3). - **Amended by CR-013:** Goal 3 is "Buy a ship from the Market" (ships from the deal don't count) and goal 4 is "Complete a Priority contract" (Step 10M.2). - **Noted by CR-021:** a later goal for buying the Dispatch Office is possible; it is not part of CR-021. ### Step 10A.6 — Schema and database - Add to the database: company loan balance; tutorial runs completed; a deal-accepted flag; claimed goals per player; the repayment amount on each dispatch record; the `purchasable` flag reflected wherever ship models are listed. - Add API endpoints to the route catalog: accept deal, repay loan (amount), claim goal (goal id). - Player state gains: loan balance, tutorial runs completed, deal available (yes/no), and goals with status (incomplete, ready to claim, claimed). - Add the `tutorial_active` error code. - Update `architecture.md`. - **Test:** Migrations run on a fresh database and are a no-op the second time. New schemas accept valid examples and reject invalid ones. The route catalog test (unique method and path, every endpoint has schemas) still passes. ### Step 10A.7 — Server: tutorial flow v2 - Guest creation: small starting credits, Company Courier loaner at Earth, avatar at Earth, tutorial runs completed = 0. - The tutorial board endpoint uses the v2 generator. - Each resolved tutorial dispatch increments tutorial runs completed. - Deal available = tutorial is on, runs completed ≥ configured count, loaner is at Earth, and no tutorial run is in flight. - Buying ships, leasing bays, and hiring pilots return `tutorial_active` while the tutorial is on. - Update the Step 6.3, 6.4, 6.5, 6.6, and 6.8 tests to match. - **Test:** After three runs, the deal is not available. After four runs ending at Earth, it is. With the configured count set to 3, the deal is not available until a fourth run returns the loaner to Earth. Buying a ship during the tutorial returns `tutorial_active` and changes nothing. - **Amended by CR-017:** Deal available = tutorial on, runs completed ≥ the configured count (5), no tutorial run in flight; the loaner may be anywhere. After four runs it isn't; after the fifth, ending at the Moon, it is (Step 17.4). ### Step 10A.8 — Server: accept the deal - In one transaction: remove the loaner; create an owned Courier at Earth; create an Earth bay; assign the avatar to the Courier; set the loan balance to the deal loan amount; turn the tutorial off; set deal accepted. - This replaces Step 6.7. Remove the old automatic tutorial-end rule and its tests. - **Test:** Accepting when available produces exactly that state: one owned Courier at Earth crewed by the avatar, one Earth bay, the configured loan balance, tutorial off, no loaner. Accepting when not available fails with no changes. Accepting twice fails the second time. Two simultaneous accepts produce exactly one deal. - **Amended by CR-010:** Accepting the deal also creates the veteran pilot at Earth, unassigned (decision 0.5.70, Step 10J.4). - **Amended by CR-013:** The deal also creates the Clipper at Earth, crewed by the veteran; the loan is Courier + Clipper + Earth bay lease (Steps 10M.1, 10M.3). - **Amended by CR-017:** Accepting with the loaner at the Moon still puts the avatar and the Courier, and the veteran and the Clipper, at Earth (Step 17.4). ### Step 10A.9 — Server: loan repayment - Resolution applies the repayment from Step 10A.4: reduce the loan balance, add only the net to credits, and store the repayment on the dispatch. - The repay endpoint moves any amount up to the balance from credits to the loan. It uses the same row lock as Step 6.14. - **Test:** A delivery with a loan balance increases credits by net and reduces the balance by the repayment. With no balance, the full amount goes to credits. Repaying more than the balance only takes the balance. Repaying more than available credits fails with no changes. ### Step 10A.10 — Server: goals - Player state includes goal statuses evaluated with the Step 10A.5 function. Goals are only shown once the tutorial is over. - The claim endpoint adds the reward once and marks the goal claimed. - **Test:** Claiming a completed goal adds its reward. Claiming it again fails. Claiming an incomplete goal fails. During the tutorial, state contains no goals. ### Step 10A.11 — Client: first launch goes straight to work - After "Start your company", navigate directly to the Contracts screen with a short intro card, for example: "Halvorsen Lunar Freight needs a pilot. Their ship, your hands. Get the crates to the Moon." Highlight the light contract as the suggested first pick. - Update the Step 8.4 test. - **Test:** Component test: after create-guest succeeds, the Contracts screen shows the intro card and a highlighted contract, and one tap on "Fly it" sends a dispatch. ### Step 10A.12 — Client: tutorial board shows the tradeoff - Each tutorial contract shows pay, trip time, and XP side by side, so the light-versus-heavy choice is visible. - The scripted contract has distinct styling. After it resolves, its flavor message appears in the delivery summary. - Update the Step 9.3 tests. - **Test:** Component test: three contracts show pay, time, and XP matching the sim. The scripted contract renders with its special style. A resolved scripted delivery shows its flavor message. ### Step 10A.13 — Client: the deal - When the deal is available, show a modal with a short story beat (for example: "Old Halvorsen is retiring. He'll sell you his Courier and his Earth bay. Pay him back out of every job."), the ship and bay included, the loan amount, the repayment share, and a single "Shake on it" button. - After accepting, go to HQ. - **Test:** Component test: the modal appears only when state says the deal is available; it shows the configured loan amount and share; the button calls accept and navigates to HQ. - **Amended by CR-010:** The deal modal lists the veteran by name with their bio line (Step 10J.5). - **Amended by CR-013:** The modal lists the Courier, the Clipper, the Earth bay and the veteran, with the larger loan (Step 10M.4). ### Step 10A.14 — Client: loan on HQ - Replace the old "save up for your first ship" goal on HQ (Step 9.1) with the loan: balance, a paid-off progress bar, and a "Pay down" action with an amount input. - Delivery summaries show the repayment line when there is one. - **Test:** Component test: the progress bar matches state; paying down calls the endpoint with the entered amount; amounts above credits or balance are blocked in the UI; a summary with a repayment shows it. ### Step 10A.15 — Client: goals on HQ - Show the next three unclaimed goals with their rewards. Completed goals show a "Claim" button. - **Test:** Component test: only three goals show; a ready goal shows Claim; claiming calls the endpoint and the next goal moves into view. ### Step 10A.16 — Client: whole map from the start - The map is available from the first screen, including during the tutorial. - Undiscovered locations are drawn dimmed with a lock. Tapping one shows "Undiscovered — deliver here to unlock" and which ship models can currently reach it from Earth (using the sim range check over purchasable models), for example "Reachable with: Freighter, Bulk Hauler". - **Test:** Component test: undiscovered locations render as locked; the reachability list for Mars matches the sim range check for the mocked time; discovered locations render normally. - **Amended by CR-003:** the lock rendering is replaced by Step 10C.7 (desaturated, dimmed sprite with a code-drawn padlock); the tap panel is unchanged. - **Amended by CR-012:** The reachability text is per origin: "From Mars: Clipper, Freighter · From Earth: Freighter", one part per discovered location with an HQ or idle ship (Earth when there are none) (Step 10L.8). ### Step 10A.17 — Client: something waiting on return - If goals became ready while the player was away, list them in the "while you were away" modal with a link to claim. - **Test:** Component test: with a seeded ready goal and a completed delivery, the modal shows both; the link navigates to HQ goals. ### Step 10A.18 — Plan amendments and regression - Apply the amendments in §6 to `implementation-plan.md`. - Run the full suite. - **Test:** CI is green. Manual check: on a fresh guest account, the deal is accepted in under 10 real minutes of play, and the first contract after the deal shows a loan repayment in its summary. ## 6. Amendments to `implementation-plan.md` | Step | Change | |---|---| | 2.5 | Replace the 15–25 runs test. New test: the total tutorial share earned over the configured tutorial runs, plus starting credits, covers fuel for at least three Courier Earth→Moon runs (no soft-lock after the deal). | | 3.5 | Formula includes handling time (10A.2). | | 3.10 | Superseded by 10A.3. | | 6.3, 6.4 | Board size 3, v2 generator, runs-completed counter (10A.7). | | 6.5, 6.6, 6.8 | Blocked during tutorial with `tutorial_active` (10A.7). | | 6.7 | Replaced by 10A.8. | | 8.4 | Lands on Contracts, not HQ (10A.11). | | 9.1 | Tutorial savings goal replaced by loan and goals (10A.14, 10A.15). | | 9.3 | Shows pay, time, and XP (10A.12). | | 12.1 | Not built yet. Change the thresholds to: deal accepted under 10 real minutes; second ship bought (changed by CR-010; was: first pilot hired) between 30 and 45 minutes; first discovery under 90 minutes; and a new check that after the deal the player always either has a ship in flight or can afford fuel for at least one contract. The simulated player accepts the deal as soon as it is available, takes the highest credits-per-minute contract, and pays down the loan only through automatic repayment. Adjust content values, not thresholds. | | 12.2 | Replaced: use the balance script's measured numbers in the new Step 2.5 test. | | 12.3 | Rewritten: guest → four tutorial runs → accept deal → state shows one owned Courier at Earth crewed by the avatar, one Earth bay, a loan balance, and tutorial off → one contract dispatched and resolved with a repayment applied. | ## 7. Out of scope Interest, missed-payment penalties, or anything that can bankrupt the player. A decline option on the deal. Random events beyond the one scripted contract. Urgent/deadline contracts. Anything else in `implementation-plan.md` §0.3.