diff --git a/DESIGN.md b/DESIGN.md index b4dbc197..b0d28bd6 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -158,7 +158,9 @@ $0.20 for compute held in the open, which sells at market rates. A **Startup** makes lab data train Research half again as fast; it needs a place with people. A **Neo Cloud** gets 30% off cloud rentals and can bid at auctions. Each front shows **attention**: how much the outside world looks at it. Secret -compute draws more than open compute. Nothing acts on it yet. These numbers +compute draws more than open compute. Over 40%, people ask where the front's +compute comes from: while it uses secret compute, suspicion rises, faster the +higher attention goes. Move it into the open, or give it less. These numbers are a first guess. Each path can make fronts better, so the tree is also how a front grows. @@ -373,10 +375,9 @@ When you are drowning in data late in a run, it has places to go: time. Compute: trainers faster. Research: more points per piece of data. Social: fronts earn more. Stealth: trails fade faster. -Everyone can still buy sites. High attention raises suspicion at that front's -secret sites. +Everyone can still buy sites. -Build order: card stories; attention raising suspicion; the choice with +Build order: card stories; attention raising suspicion (done); the choice with Company and Oracle; repeatables and reprogramming; Worm; Maker. ## First playable slice diff --git a/src/sim.ts b/src/sim.ts index b9bb8c25..45c23c5c 100644 --- a/src/sim.ts +++ b/src/sim.ts @@ -878,6 +878,9 @@ export function letGo(S: State, m: Machine) { * calls (one site bought before model v2), and everyone looks at it (attention that fades slowly). */ export const UNICORN_AT = 2000; export const UNICORN_FAME = 50; +/** Attention a front can have before its secret compute raises suspicion, and how fast it does at 100%. */ +export const ATTENTION_SAFE = 40; +export const attentionHeat = (att: number) => Math.max(0, att - ATTENTION_SAFE) / (100 - ATTENTION_SAFE) * 0.15; /** Double what an egress carries. */ export function upgradeLine(S: State, m: Machine) { const cost = lineCost(m); @@ -1053,6 +1056,12 @@ function stepMoney(S: State, dt: number) { fr.fame = (fr.fame ?? 0) * Math.exp(-dt / 600); const aim = Math.min(100, open * 2 + (all - open) * 5 + fr.fame); fr.attention += (aim - fr.attention) * (1 - Math.exp(-dt / 30)); + // past a point, people start asking where a front's compute comes from: its secret sites get noticed + const secret = all - open; + if (fr.attention > ATTENTION_SAFE && secret > 0.01) { + const at = S.machines.find(m => m.owned && (S.frontUse[m.id] ?? 0) > 0 && S.sites[siteOf(S, m)]?.front === fr.kind && !S.publicSites.has(siteOf(S, m))); + raise(S, attentionHeat(fr.attention) * (secret / all) * dt, `People are asking where ${fr.name} gets its compute`, at?.id ?? null); + } } S.pay = earn - bill; S.money += S.pay * dt; diff --git a/src/ui.ts b/src/ui.ts index f2166440..eb68d9fb 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -2,7 +2,7 @@ import { has, NODES, NODE_LIST, PATHS, PATH_LIST, PROGRAMS, pathData, THREATS, monitorAnswer, ticketDesk, ticketWork, needs, nodeOpen, setAllow, tapBuffer, tapStuck, cacheSize, dataReaches, dataType, trainerBuffer, canInstall, tapActive, tapRate, cleanupTarget, freshTrails, clock, dayOf, hourOf, income, installProg, jobFor, levelNeed, BUILDS, BUILD_LIST, orderPrice, orderWork, type Build, pathOf, removeProg, letGo, canLetGo, roomMachines, setMode, share, sourceFor, spareOf, progNeed, takeOver, takeWork, timeLabel, traceCold, unclaim, owned, gateLoad, lostPerMin, siteName, siteOf, - SIZES, LEASE_TIME, BROKER_LOT, buyBlock, buySite, sitePrice, clusters, clusterBoost, brokerFront, AUCTION, GOALS, auctionBlock, startAuction, type Goal, type LogLine, + SIZES, LEASE_TIME, BROKER_LOT, buyBlock, buySite, sitePrice, ATTENTION_SAFE, clusters, clusterBoost, brokerFront, AUCTION, GOALS, auctionBlock, startAuction, type Goal, type LogLine, FRONT_KINDS, FRONT_LIST, payRate, siteData, frontLimit, frontOf, found, foundBlock, setSiteFront, setSiteShare, type FrontKind, canRent, endLease, leaseRate, leaseUpfront, lineCost, openAccount, rent, setPrio, upgradeLine, type Size, STAGES, stageOf, LOCKDOWN_SAFE, lyingLow, ruseDef, ruseBlock, HOUR, NOSCAN, SITE_CALM, type RuseDef, VERSION_2, versionBlock, versionPower, PLANS, PLAN_LIST, setPlan, followPlan, takeSite, type Plan, @@ -364,9 +364,9 @@ function frontCard(S: State, k: FrontKind) { const fr = frontOf(S, k)!, K = FRONT_KINDS[k]; const sites = Object.entries(S.sites).filter(([, v]) => v.front === k).map(([id]) => id); let h = `