Guide
Population
A new career fills every tier up to its size with generated players, and each season a youth intake tops the world back up. If your mod adds real players, the generated ones can end up stronger than them. data/population.json controls how many players are generated and how strong they can be.
The file holds one object (an array of them also works). Every field except id is optional. A field you leave out keeps the game's default. Without the fields in the table below, the game behaves exactly as before: the core pack's own data/population.json (core.population) only holds the tuning at the game's numbers, which doesn't switch them on.
{
"id": "acme.population",
"capToNamed": { "percentile": 50, "growth": 1 },
"genderLevelOffset": { "f": -6 },
"womenShare": 0.06,
"potentialHeadroom": 14
}| Field | Default | What it does |
|---|---|---|
tierSizes | 1: 32, 2: 96, 3: 128, 4: 128, 5: 220 | Players per tier, named and generated together, e.g. { "3": 100 }. The total is also the size the youth intake keeps the world at, and 3 is how many non-card holders stay in tier 3 each season. |
levels | the game's bands | Per tier { "mean", "sd", "min", "max" }. A generated player's level is drawn from N(mean, sd), and the final overall level (after attribute noise and style) is kept inside [min, max]. |
potentialHeadroom | 28 | The most potential a generated player gets above their level (teenagers get the most). The game's headroom ranges, including the youth intake's, are scaled to fit. |
genderLevelOffset | { "m": 0, "f": 0 } | Added to generated players' level by gender. The band and the named-player cap move with it, so { "f": -6 } puts generated women 6 below where generated men would be. |
womenShare | 0.10 (0.15 in tier 5, 0.14 youth) | Share of generated players, and of each youth intake, who are women (0 to 1). |
capToNamed | off | Keeps generated players below the named ones. See below. |
Capping generated players to the named ones#
"capToNamed": { "percentile": 50, "margin": 0, "growth": 2, "minNamed": 3 }
- For each tier, the cap is that percentile of the named players' overall levels in the tier, plus
margin. With50and a margin of 0, no generated player starts above the tier's median named player. The human doesn't count. - A tier with fewer than
minNamednamed players uses the cap of the nearest tier above. If no tier above has one, the tier has no cap. - A generated player's potential is at most the cap plus
growth. Each off-season, a generated player can't develop past their potential, and their potential never rises. - Youth intake: each season's youngsters get the same caps for their tier (4 or 5). Their potential is bounded by the Tour Card tier's cap (tier 2) plus
growth. A youngster can still grow into a pro, just not past the named players. Caps are recalculated each season from the named players still active.
levels and capToNamed work together: the final level stays inside [min, max] and under the cap.
Several mods#
Records apply in load order: fields from later mods win, per tier for tierSizes and levels. If you reuse another mod's id, your record replaces theirs and moves to the end of the load order. You can also patch it, like any record:
{ "target": "population:acme.population", "patch": { "genderLevelOffset": { "f": -4 } } }A named player's Tour Card year#
A new career gives each named player in tiers 1 and 2 a Tour Card that runs to the starting season or the next, chosen at random. A mod that knows a player's real card can set it in their record in data/players/:
{ "id": "acme.player.jones", "tier": 1, "tourCardUntil": 2027 }tourCardUntil is the last season of the card. A year before the career's first season means the player starts without a card. Leave it out and the card is drawn as before. Setting it on some players doesn't change anything else in a new world: the other players and the rest of the world are the same as without it.
Club juniors#
youth.club gives a new world a group of beginners on top of its tier sizes, at the lowest tier: { "count": 120, "age": [8, 13], "level": [6, 26] } makes 120 children aged 8 to 13 whose typical rating runs from 6 at the youngest age to 26 at the oldest (each one a few points either side). They are the opponents of the junior events with an ability band or a low age limit. Computer players younger than the tuning value population.juniorOnlyAge (14) only enter events that have a maxAge. Leave club out and no such players are made.
Tuning: styles, followers, youth and retirement#
These fields tune how players are made and how long they last. They're always in force (the core pack sets them to the game's numbers), and setting them doesn't switch on the fields above.
{
"id": "acme.population",
"archetypes": { "showman": { "crowdHandling": 14, "composure": -2 } },
"followers": { "1": [100000, 2000000] },
"youth": { "gemChance": 0.05 },
"retirement": { "midAge": 56, "pros": 0.4 }
}| Field | Default | What it does |
|---|---|---|
archetypes | see below | Styles of generated player: points added to each attribute around their level. The six styles are fixed; an archetype given replaces the game's offsets for it |
followers | 1: 60,000–1,200,000, 2: 5,000–90,000, 3: 600–9,000, 4: 150–4,000, 5: 20–800 | A new player's followers per tier, [fewest, most]; the better they are within the tier, the more |
reputation | 1: 70–98, 2: 45–75, 3: 25–50, 4: 10–35, 5: 2–20 | A new player's reputation (0–100) per tier, [lowest, highest] |
youth | gemChance 0.07, headroom [6, 22], gemHeadroom [20, 28] | Each season's youth intake: the share who are gems, and the potential above their level for ordinary youngsters and for gems |
retirement | see below | A computer player's chance of retiring at a season's end |
The core archetypes:
| Archetype | Offsets |
|---|---|
scorer | scoring +5, finishing −4, checkoutKnowledge −2, crowdHandling +2 |
finisher | scoring −3, finishing +5, checkoutKnowledge +5, bullAccuracy +3 |
grinder | consistency +6, concentration +5, stamina +6, crowdHandling −4, tempoControl +3 |
showman | crowdHandling +10, composure −3, consistency −3, bullAccuracy +2 |
nervy | composure −8, resilience −6, scoring +2, finishing +1 |
balanced | none |
Retirement: below youngAge (40) the chance is young (0.004). From then it's 1 / (1 + e^−(age − midAge) / spread), with midAge 53 and spread 3.5. Add pub (0.05) for a tier 5 player older than pubAge (45). Add weak (0.08) for a player below level weakLevel (50) who is older than weakAge (30). Then multiply by pros (0.5) in tiers 1 and 2, because pros hang on longer. The living world's farewell-season announcements use the same chances. retirement merges per field.
Records merge in load order: per archetype for archetypes, per tier for followers and reputation, per field for youth and retirement, per trait id for traits. The core record is population:core.population, so { "target": "population:core.population", "patch": { "youth": { "gemChance": 0.1 } } } works too.
The next generation#
Each winter's intake has a shape. The numbers live in data/tuning.json under nextgen.* (see Tuning), the words in data/texts/nextgen.json.
- Waves. The gem chance and an ordinary youngster's headroom follow a slow cycle:
sin(2π × (year − phase) / nextgen.generations.period)with the phase seeded from the career, multiplied bygemAmp(0.5) andheadroomAmp(0.15).period0 or both amplitudes 0 switch it off. The same draws are made; only the chance a gem draw is tested against and the size of the one headroom draw change. - National programmes. A nation at band
nextgen.programmes.bandMin(3, Strong) or above forseasonsToOpen(2) seasons opens one, named from the textnextgen.programme.name("{nation} Darts Academy");seasonsToClose(3) seasons below the band close it. A career's first rollover opens them quietly where darts already stands that high. Each winter a programme claimsshare(0.5) of its nation's newcomers, best potential first (no draw), giving eachheadroom(4) more potential (never past the nation's cap fromnations.json),professionalism(6) more professionalism, andgrowth(0.12) on the winter's development untiluntilAge(23). Graduates carry a "Class of {year}, {programme}" line on their page and a timeline line. - Your academy. A facility with
graduatesabove 0 (data/facilities.json: the youth academy 1, the campus 2) brings that many real youngsters of your own country into the world each winter, made on theacademystream atnextgen.academy.minAge(15) to the intake's oldest age, withnextgen.academy.headroom(3;campusHeadroom5 with two or more) and taking newcomers' places. A facility withgemBonus(the scholarship fund, 0.04) adds to the gem chance of your country's newcomers. What they do pays you back: legacy points (legacy.jsonpoints.graduate*),imagePerGraduate(1) image a season for each one holding a card,followersPerMilestone(300), news, a letter for the first card, and thevsGraduatestory condition (data/events/narrative/nextgen.jsoncarries three stories with theacademy-mentorflag). - Hype. A computer player under
nextgen.hype.maxAge(23) gains hype on a Tour Card atcardAge(20) or under (card25), a win over a top-upsetRank(16) player (upset12) or a top-bigUpsetRank(8) one (bigUpset20), a tier 1–2 title (title30), a major final (majorFinal40) and a rising feature (rising15); a showboat gainsshowboatGain(1.3) times more. It decaysdecay(3) a week,decayPlayed(1) in a week they played while atquietBelow(25) or more, capped atcap(100); only a player under the age today gains, and hype ends for anyone at the age on the calendar year's 1 January (at the first week of the year, even while a world championship holds the season open). Bands atbands[25, 50, 75] take the wordsnextgen.hype.band.0to.3; crossing one upward is a story. Effects:pressure(0.06) × hype/100 on televised stages,crowd(0.05) × hype/100 off their crowd hostility at home,sponsor(1) × hype/100 on a sponsor signing or upgrading,news(0.5) × hype/100 on their stories' weight,rivalry(0.5) on a rivalry seed between two youngsters. Falling frombustFrom(50) to underbustTo(25) withinbustWeeks(20) of the peak is a bust:'s slump once (bustProfessional0.5 softens it for a professional). The human is never hyped (fame covers them). - The changing of the guard. At each rollover the world's top
nextgen.generations.guardTop(32) is measured: median birth year, mean age, shares by five-year band. A median movingguardShift(2) or more years in one season is news (nextgen.guard.*), naming the youngest in the top and whoever dropped out.
The World page's Next generation tab shows all four; an older save gets the state at its next rollover.
Conduct traits#
traits is the list of conduct traits a computer player can carry (two at most, the best-scoring ones). Each trait says how it is scored from the player and what it changes:
{
"id": "acme.population",
"traits": [
{
"id": "tinkerer",
"named": true,
"weights": { "professionalism": -0.4, "temperament": { "volatile": 0.35 }, "media": { "confident": 0.2 }, "style": { "frontrunner": 0.4, "showman": 0.3 } },
"effects": { "switch": 2 }
}
]
}weights: the score isambition × (ambition − 50) / 50 + professionalism × (professionalism − 50) / 50, plus themediaweight of the player's media manner (humble,confident,showman,reserved,fiery), thetemperamentweight of their temperament (calm,steady,volatile) and thestyleweight of their style on the oche (showman,grinder,frontrunner,steady), plus seeded noise of up toai.traits.noise. A trait counts when its score passesai.traits.minScore; a player takes the topai.traits.perPlayer, so a player can have one or none. The answer is written on the player's record the first time the world needs it, so a change of data never changes a trait under a player.effects: multipliers on the chances the world already draws against, by name; a missing one is 1.churn(the main sponsor dropping the player, the agency switch),upgrade(a bigger sponsor or darts brand when hot),switch(leaving the darts brand, a darts change in a slump),coach(a new coach in a slump),dartitis(the dartitis chance),swing(the form and composure of hot streaks and slumps),heat(how fast meetings heat a rivalry),social(the feed's posts about the player's stories),feud(the feud chance: a feud needs the product of the two players' values above 1),loyalty(how fast brand loyalty grows).named:falsekeeps the trait off real (named) players; the core pack gives every trait to everyone.- Texts:
ai-traits.<id>.nameandai-traits.<id>.blurbindata/texts/for the Player page.
The core traits: loyal, mercenary, tinkerer, superstitious, hothead, showboat, professional, restless (data/population.json). Every player the world follows (the top 64 and tiers 1 to 2) also throws a real set of their darts brand (the item nearest their sponsor tier, by hash) whose levers are the human's kit rules pulled towards neutral by ai.kit.scale; brand loyalty (ai.kit.*) slows a brand switch. Feuds between two hotheads (world.feud.*) run through words, a bust-up and a grudge match with pressure on the oche. See tuning.
Saves#
Population settings are copied into a save when the career is created. A career you load picks up the installed packs' settings: generated players already in the world stay as they are, and the settings apply from the next youth intake, refill and retirements.
Checking the effect#
The schema is the population settings reference.
Keeping the lower tiers busy: refill#
Trial Week lifts its whole field to Contender Tour level every winter, which drains the pub (tier 5) and development (tier 4) circuits. refill lists tiers the game tops back up to their tierSizes with generated players of all ages (faces from the library): once after Trial Week finishes and again at each season rollover. The world never grows past 25% over the sum of tierSizes.
{ "id": "mymod.population", "tierSizes": { "4": 180, "5": 360 }, "refill": [4, 5] }