Pawn Generation Process
Last updated for: 1.6.4871 rev591
This guide explains the pawn generation process of RimWorld and its individual steps.
WARNING[edit]
This guide is intended to be used to reference the order in which sections of pawn data is generated in order to diagnose issues with mod code running too early or too late. You should avoid Harmony patching these methods if there are existing mechanisms for affecting that particular aspect, as pawn generation is a very performance-sensitive system in RimWorld. If you have any questions regarding pawn generation mechanisms, please make use of online resources such as the #mod-development channel on the RimWorld Discord.
Entry Point[edit]
The root method that services pawn generation requests is Verse.PawnGenerator.GeneratePawn(PawnGenerationRequest), which is called from dozens of external methods.
This then calls Verse.PawnGenerator.GenerateOrRedressPawnInternal(PawnGenerationRequest) after validating the request conditions, which will then call RedressPawn(Pawn, PawnGenerationRequest) if it decides to redress (recycle) an existing pawn or GenerateNewPawnInternal(ref PawnGenerationRequest) if it decides to generate a fresh pawn.
Existing Pawn Redressing[edit]
(Placeholder)
New Pawn Generation[edit]
New pawn generation begins in Verse.PawnGenerator.GenerateNewPawnInternal(ref PawnGenerationRequest). This method's primary purpose is to call TryGenerateNewPawnInternal(ref PawnGenerationRequest, out string, bool, bool) and retry if the attempt fails. After 70 failed attempts the pawn generator will log an error and begin ignoring scenario requirements. After 100 attempts the pawn generator will begin ignoring validators. After 120 failed attempts the pawn generator will give up and return null.
| # | Description | Called Method(s) |
|---|---|---|
| 1 | Create the Pawn object | Verse.ThingMaker.MakeThing(ThingDef) |
| 2 | Set the new pawn's faction | Verse.Pawn.SetFactionDirect(Faction) |
| 3 | Initialize the pawn's internal components and trackers | Rimworld.PawnComponentsUtility.CreateInitialComponents(Pawn); |
| 4 | (inline) | |
| 5 | Set gender (PawnGenerationRequest > PawnKindDef > random roll) | (inline) |
| 6 | Set age | Verse.PawnGenerator.GenerateRandomAge(Pawn, PawnGenerationRequest) |
| 7 | Set initial needs levels | pawn.needs.SetInitialLevels() |
| 8 | Adjust food and rest need levels if the pawn is a newborn | (inline) |
| 9 | Apply humanlike pawn overrides | (inline) |
| a. Apply randomized faction if none was specified in the request | (inline) | |
| b. Apply request skin color override if applicable | (inline) | |
| c. Select head type - can be randomized or one forced by pawn genes | pawn.story.TryGetRandomHeadFromSet(IEnumerable<HeadTypeDef>) | |
| d. |
(inline) | |
| e. |
GetXenotypeForGeneratedPawn(PawnGenerationRequest) AdjustXenotypeForFactionlessPawn(Pawn, ref PawnGenerationRequest, ref XenotypeDef) | |
| f. Pick a solid or random bio (name and backstories) | RimWorld.PawnBioAndNameGenerator.GiveAppropriateBioAndNameTo(Pawn, FactionDef, PawnGenerationRequest, XenotypeDef) | |
| g. Override name from request if applicable (such as for children) | (inline) | |
| h. Apply traits | GenerateTraits(Pawn, PawnGenerationRequest) | |
| i. Apply body type | GenerateBodyType(Pawn, PawnGenerationRequest) | |
| j. Generate genes | GenerateGenes(Pawn, XenotypeDef, PawnGenerationRequest) | |
| k. Generate skill passions and levels | GenerateSkills(Pawn, PawnGenerationRequest) | |
| 10 | Generate random pawn relations if pawn is not a newborn | GeneratePawnRelations(Pawn, ref PawnGenerationRequest) |
| 11 | If the pawn is a player animal, make it tamed and enable Tameness training | (inline) |
| 12 | Generate an appropriate RoyalTitleDef for the pawn, if applicable - Note that RoyalTitleDefs are not locked to |
(inline) |
| 13 | (inline) | |
| 14 | pawn.guest.RandomizeJoinStatus() | |
| 15 | Initialize work assignments for player-controlled pawns with a work settings tracker | pawn.workSettings.EnableAndInitialize() |
| 16 | Generate an appropriate name for faction-controlled animals and mechs - Only applicable to mechs if |
pawn.GenerateNecessaryName() |
| 17 | (inline) | |
| 18 | pawn.mindState.SetupLastHumanMeatTick() | |
| 19 | If the pawn has a SurroundingsTracker, clear its state | pawn.surroundings.Clear() |
| 20 | Generate initial hediffs | GenerateInitialHediffs(Pawn, PawnGenerationRequest) |
| 21 | If the request asked for a dead pawn and the pawn is not dead, kill it | pawn.Kill() |
| 22 | Humanlike style item setup | (inline) |
| a. Choose a random hair style | PawnStyleItemChooser.RandomHairFor(Pawn) | |
| b. Choose a random beard style | PawnStyleItemChooser.RandomBeardFor(Pawn) | |
| c. |
PawnStyleItemChooser.RandomTattooFor(Pawn) - for both face and body | |
| 23 | Apply all AbilityDefs specified in the PawnKindDef if provided | (inline) |
| 24 | Notify all Scenario parts that a new pawn has been generated - This is where forced traits and hediffs from the scenario are applied | Find.Scenario.Notify_NewPawnGenerating(Pawn, PawnGenerationContext) |
| 25 | Run validation checks for the generated pawn and discard if any fail - Any failures will immediately return a null from this attempt | (inline) |
| a. If the pawn is dead and the request did not allow for dead pawns, discard it | (inline) | |
| b. If the request does not allow dead or downed pawns and the pawn is downed, discard it | (inline) | |
| c. If the request requires the capability for violence and the pawn is incapable, discard it | (inline) | |
| d. If the PawnKind requires capability in specific skills and this pawn is incapable, discard it | (inline) | |
| e. If the PawnKind requires any minimum skill levels and this pawn does not meet those requirements, discard it | (inline) | |
| f. If the PawnKind requires a mimimum combined skill level and the pawn does not meet that requirement, discard it | (inline) | |
| g. If the request is for a player starting pawn, the pawn does not meet the scenario requirements, and the pawn generator has not hit the threshold for ignoring scenario requirements, discard it | (inline) | |
| h. If the request provided a special pre-gear validator, the pawn does not pass the validator, and the pawn generator has not hit the threshold for ignoring the validator, discard it | (inline) | |
| 26 | Generate pawn gear - Does not apply for newborns, mechanoids, or if the request forces no gear (naked brutality) | GenerateGearFor(Pawn, PawnGenerationRequest) |
| a. Generate starting apparel | PawnApparelGenerator.GenerateStartingApparelFor(Pawn, PawnGenerationRequest) | |
| b. Generate inventory items | PawnInventoryGenerator.GenerateInventoryFor(Pawn, PawnGenerationRequest) | |
| c. Generate equipped weapon (can be disabled by request) | PawnWeaponGenerator.TryGenerateWeaponFor(Pawn, PawnGenerationRequest) | |
| 27 | If pawn is dead, notify PawnApparelTracker that the pawn died - This is what causes clothing to be tainted | pawn.apparel.Notify_PawnKilled() |
| 28 | Run post-gear pawn validator, if provided - As with pre-gear validator, if the pawn does not pass this validator and the pawn generator has not reached the threshold for ignoring validators then the pawn will be discarded | (inline) |
| 29 | MutantUtility.SetFreshPawnAsMutant(Pawn, MutantDef) | |
| 30 | Add the pawn to the static list of pawns being generated | (inline) |
| 31 | If the pawn has a faction, notify the faction of a new member joining | pawn.Faction.Notify_PawnJoined(Pawn); |
| 32 | Apply existingDamage entries from PawnKindDef - Used by |
ApplyMiscDamage(Pawn, PawnKindDef) |
| 33 | Flag pawn's renderer as dirty - Forces a regeneration of its render tree | pawn.Drawer?.renderer?.SetAllGraphicsDirty() |
| 34 | Remove the pawn from the static list of pawns being generated - Run in a finally block, even if an above step returns early or causes an error
|
(inline) |