<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="http://gust.dev/feed.xml" rel="self" type="application/atom+xml" /><link href="http://gust.dev/" rel="alternate" type="text/html" /><updated>2025-07-02T14:01:17+00:00</updated><id>http://gust.dev/feed.xml</id><title type="html">Gust.dev – All Things Data Science</title><subtitle>A collection of analyses written in Python and R focused of deriving valuable insights from data with minimal hand-waving.</subtitle><author><name>Ryan Gust</name><email>MY_FIRST_NAME@MY_LAST_NAME.dev</email></author><entry><title type="html">Pal Analysis</title><link href="http://gust.dev/blog/pal-analysis" rel="alternate" type="text/html" title="Pal Analysis" /><published>2025-05-28T00:00:00+00:00</published><updated>2025-05-28T00:00:00+00:00</updated><id>http://gust.dev/blog/pal-analysis</id><content type="html" xml:base="http://gust.dev/blog/pal-analysis"><![CDATA[<blockquote>
  <p><strong>Note</strong>: I initially intended for this analysis to live and die as a post on <a href="https://www.reddit.com/r/Palworld">reddit</a>…
adjust your expectations accordingly.</p>
</blockquote>

<h1 id="analysis-of-10000-captures---a-deep-dive-on-passive-skill-probabilities-dataset-included">Analysis of 10,000 Captures - A Deep dive on Passive Skill probabilities (Dataset included)</h1>

<details class="notice--info">
   <summary> <em> What on <strong>earth</strong> are you on about?</em> 
      <i class="fa-regular fa-circle-question" style="float: right; font-size: x-large;"></i>
   </summary>
   
<p><a href="https://store.steampowered.com/app/1623730/Palworld/">Palworld</a> is an open-world survival crafting game often caricatured as “Pokémon but with guns”.</p>

<p>Core to the gameplay and indeed its namesake are <strong>pals</strong>. Pals are the creatures that wander about in the world that you as the player can catch.</p>

<p>Captured pals will join your team and assist with all aspects of the game from combat to base-building, resource gathering, and more. Pals typically specialize in one of these areas of gameplay based on the capabilities unique to each pal (work suitability).</p>

<p><a href="https://palworld.wiki.gg/wiki/Passive_Skills">Passive skills</a> are (most often) randomly assigned modifiers that augment certain attributes of a pal. For instance, some change a pal’s damage, some increase movement speed, and some enhance work speed - the rate at which a pal can complete a suitable task.</p>

<p>In the mid-late game, passive skills become a player’s primary focus. The buffs they provide to a pal’s base stats are integral to the player reaching the end-game content.</p>

<p>By the point a player cares about optimizing passive skills, they typically have already encountered all the most desirable passive skills (Rainbow-tier) at least once. Hereafter, a player’s dependence on wild pals is reduced substantially due to the game’s <a href="https://palworld.wiki.gg/wiki/Breeding#How_Breeding_Works">breeding mechanism</a>, which allows passive skills to transfer between pals of different species via inheritance.</p>

<p>Compared to wild capture, breeding is far more efficient at producing desired pal-passive combinations under normal circumstances, earning it the favor of community efforts thus far. Information regarding passive skill assignment in wild pals is far scarcer, limited primarily to anecdotal estimates shared among players.</p>

<p>With this analysis, I hope to help close the knowledge gap between the two means of passive skill acquisition.</p>


</details>

<h2 id="overview">Overview</h2>
<p>While the mechanisms and probabilities behind breeding passives and IVs have been fairly well <a href="https://www.reddit.com/r/Palworld/comments/1af9in7/passive_skill_inheritance_mechanics_in_breeding/">documented</a> and <a href="https://www.reddit.com/r/Palworld/comments/1am7y16/definitive_datamined_guide_to_breeding_for_both/">explored</a>, the same <a href="https://github.com/tylercamp/palcalc/issues/4">cannot be said</a> for wild-caught pals. To the best of my knowledge, this is the first formal analysis of wild-caught pal passive skill mechanisms.</p>

<p>The goal is to answer the following questions:</p>

<ol>
  <li>What is the probability of a wild-caught pal having 0, 1, 2, 3, or 4 passive skills?</li>
  <li>Are all Rainbow passives equally likely?</li>
  <li>Are weak Common passives more likely than strong ones?</li>
  <li>What is the probability of getting a specific Common passive?</li>
  <li>What is the probability of getting a specific/any Rainbow passive?</li>
</ol>

<p>Bonus Topics</p>

<ul>
  <li>Two (potentially) novel discoveries about Yakumo’s partner ability that are <strong>Complete Game Changers That Will Totally Change How You Use Yakumo!™</strong>
    <ul>
      <li>
        <p class="spoiler">Clickbait aside, it does contradict the wisdom/advice often shared in the community.</p>
      </li>
    </ul>
  </li>
  <li>A brief look into random breeding mutations.</li>
</ul>

<h3 id="tldr">TL;DR</h3>

<p>(for the <code class="language-plaintext highlighter-rouge">CoolTimeReduction_Up_2</code>)</p>

<ol>
  <li>
    <p>(assuming 0 innate)</p>

    <table>
      <thead>
        <tr>
          <th style="text-align: left">n-skills</th>
          <th style="text-align: left">p(n-skills)</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td style="text-align: left">0</td>
          <td style="text-align: left">10.5%</td>
        </tr>
        <tr>
          <td style="text-align: left">1</td>
          <td style="text-align: left">76%</td>
        </tr>
        <tr>
          <td style="text-align: left">2</td>
          <td style="text-align: left">9.6%</td>
        </tr>
        <tr>
          <td style="text-align: left">3</td>
          <td style="text-align: left">3%</td>
        </tr>
        <tr>
          <td style="text-align: left">4</td>
          <td style="text-align: left">0.9%</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>
    <p>Probably, it might depend on how you treat Lucky<!-- \*--></p>
  </li>
  <li>
    <p>yes, <a href="https://en.meming.world/images/en/f/f7/Well_Yes%2C_But_Actually_No.jpg">in practice</a></p>
  </li>
  <li>
    <p>~1/60 (1.67%)</p>
  </li>
  <li>
    <p>~1/1110 | ~1/140</p>
  </li>
</ol>

<!-- <sup> * I treat Lucky like the fake Rainbow passive that it is. Ask why = unhinged rant</sup> -->

<h2 id="dataset">Dataset</h2>

<ul>
  <li><a href="https://docs.google.com/spreadsheets/d/1zr5yv-GtoMLN3ehYvwAVMsIFvP9QAyN3M5WhfdsDQuA/edit?usp=sharing">All Datasets - Google Sheets</a></li>
  <li>External data
    <ul>
      <li><a href="https://github.com/EternalWraith/PalEdit/blob/main/palworld_pal_edit/resources/data/passives.json">passive ratings</a></li>
      <li><a href="https://github.com/EternalWraith/PalEdit/blob/main/palworld_pal_edit/resources/data/en-GB/passives.json">passive names</a></li>
    </ul>
  </li>
</ul>

<h3 id="data-collection">Data Collection</h3>

<p>(this was all done prior to the pal box expansion, and yeah… oof)</p>

<!-- <details>
<summary>For capture data,</summary>
* Change world settings to max spawn rate and longest days.
* Create a viewing cage and empty out palbox completely
* Store a backup of the world in this clean state
* Repeat 10x
   * Using Homing Sphere Launcher + Sniper Module II, capture Gobfin from Gobfin's Turf until palbox + 1 viewing cage is entirely filled, yielding a 1000-pal sample.
   * Export `Level.sav` data to `json` via [palworld-save-tools](https://github.com/cheahjs/palworld-save-tools) (note: I have since discovered a [maintained fork](https://github.com/deafdudecomputers/PalWorldSaveTools) that works far better)
   * Reset world by restoring from clean state backup
</details> -->

<p>For capture data,</p>

<ul>
  <li>Change world settings to max spawn rate and longest days.</li>
  <li>Create a viewing cage and empty out palbox completely</li>
  <li>Store a backup of the world in this clean state</li>
  <li>Repeat 10x
    <ul>
      <li>Using Homing Sphere Launcher + Sniper Module II, capture Gobfin from Gobfin’s Turf until palbox + 1 viewing cage is entirely filled, yielding a 1000-pal sample.</li>
      <li>Export <code class="language-plaintext highlighter-rouge">Level.sav</code> data to <code class="language-plaintext highlighter-rouge">json</code> via <a href="https://github.com/cheahjs/palworld-save-tools">palworld-save-tools</a> (note: I have since discovered a <a href="https://github.com/deafdudecomputers/PalWorldSaveTools">maintained fork</a> that works far better)</li>
      <li>Reset world by restoring from clean state backup</li>
    </ul>
  </li>
</ul>

<p>For Yakumo data,</p>

<ul>
  <li>Follow the exact same procedure but instead of using a fast flying mount, keep a max-condensed Yakumo with 4 Rainbow passives out the entire duration.</li>
  <li>Perform this only once because, in stark contrast to Yakumo, life moves quickly.</li>
</ul>

<p>For breeding data,</p>

<ul>
  <li>Create breeding farms and populate with pairs of blank (0-passive) gobfin.</li>
  <li>Allow to run in background, ever so often gathering all the eggs and storing in chests.</li>
  <li>Again use <code class="language-plaintext highlighter-rouge">palworld-save-tools</code> to export data, this time observing <code class="language-plaintext highlighter-rouge">DynamicItemSaveData</code> to view passives on stored eggs.</li>
  <li>(optional) Realize that using the save-export-restore method would have been a far better approach that could have saved you a ton of time in hindsight while writing your data collection procedure.</li>
</ul>

<h2 id="analysis">Analysis</h2>

<p><strong>A note on terminology</strong>: I use “passive skills”, “passives”, “skills”, and “traits” interchangeably.<br />
Which one I use depends solely on how I’m feeling at the time. Partner skills will be called by name or as “partner abilities” to make the distinction clear. Active skills will not be discussed at any point.</p>

<ul>
  <li>“Rainbow” = Rainbow-tier passive skills (Demon God, Swift, etc.) excluding Lucky</li>
  <li>“Common” = everything not Rainbow or Lucky</li>
</ul>

<h3 id="number-of-passive-skills-q1">Number of Passive Skills (Q1)</h3>

<p><img src="/assets/images/postimgs/pal-analysis/0_n_passives.png" alt="Fig 1. Passive Skill Count Frequency" class="align-center" /></p>

<p>This chart shows a basic count of the number of passive skills on each of the 10,000 captured pals. Given results this extreme, it is fairly safe to assume the probability of a pal having 0-4 skills is not uniform. On average, roughly <strong>3 out of every 4 pals captured have 1 passive skill</strong>. This is good news for those who hate breeding off undesirable skills, but also means a higher number of required captures before encountering a particular skill.</p>

<p>Additionally, when hunting for a blank pal for breeding, you can expect it to take ~<strong>19 captures for a 0-passive pal of a particular gender</strong> (assuming an equal gender ratio).</p>

<p>Considering much of the analysis builds off this data, I feel it’s worthwhile to list the confidence interval for these findings.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">n</th>
      <th style="text-align: left">p(n)</th>
      <th style="text-align: left">confidence interval (95%)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">0</td>
      <td style="text-align: left">10.5%</td>
      <td style="text-align: left">(9.91; 11.12)%</td>
    </tr>
    <tr>
      <td style="text-align: left">1</td>
      <td style="text-align: left">76%</td>
      <td style="text-align: left">(75.15; 76.83)%</td>
    </tr>
    <tr>
      <td style="text-align: left">2</td>
      <td style="text-align: left">9.6%</td>
      <td style="text-align: left">(9.03; 10.19)%</td>
    </tr>
    <tr>
      <td style="text-align: left">3</td>
      <td style="text-align: left">3.02%</td>
      <td style="text-align: left">(2.69; 3.37)%</td>
    </tr>
    <tr>
      <td style="text-align: left">4</td>
      <td style="text-align: left">0.88%</td>
      <td style="text-align: left">(0.71; 1.08)%</td>
    </tr>
  </tbody>
</table>

<p>If this means nothing to you, first, congrats on being able to be certain about things; I miss that. Second, just know that it is <em>likely</em> that the true probability of pal having a given number of skills falls within that range*.</p>

<p>These values came into play while entertaining the possibility that, for any number of skills &gt; 1, the probability is equal to <code class="language-plaintext highlighter-rouge">(0.3)^n</code>. It’s a neat and tempting proposal and while possible, these observations render it <em>unlikely</em>.</p>

<p>If you’ll permit some unsubstantiated speculation, however, I do have a theory that the actual skill count distribution is <code class="language-plaintext highlighter-rouge">[0: 10.5%, 1: 76.0%, 2: 13.5%]</code> and, if it rolls 2, it will roll again with some probability, repeating on success.</p>

<p>From playing around a bit, 30% and 20% re-roll probabilities seem to match the 3-4 skill counts reasonably well. This would also mean they wouldn’t have to change the logic for pals with 1-2 innate passives since it would only re-roll up to a max of 2 times.</p>

<p><sup> * to those who know better: save your strength. This is among the <em>least</em> egregious of the oversimplifications to come.</sup></p>

<h3 id="skill-distributions-q2-q3">Skill Distributions (Q2, Q3)</h3>

<p><img src="/assets/images/postimgs/pal-analysis/1_passive_counts_nox.png" alt="Fig 2. Passive Skill Distribution" class="align-center" /></p>

<p>Here we have a flattened count over all skills observed. The keen-eyed among you might notice that there are more skills than pals caught. After taking into account 0 and multiple trait cases, you end up averaging about ~<strong>1.08 passives per wild-caught pal</strong>.</p>

<p>A cursory glance at this data might lead you to believe that <em>Hard Skin</em> is more likely than <em>Runner</em>, and Rating=-1 is more common than Rating=3. I argue however, that the first statement is not true and the second is not only <em>not</em> true, but the <em>opposite</em> is true. In fact, Rating=3 is the second most common skill group after Rating=1.</p>

<p>If you haven’t figured out where I’m going with this yet, I’ll stop burying the lede. The data suggests that for both Common and Rainbow, <strong>all passive skills have an equal probability of being selected within their respective set</strong>.</p>

<p>Said another way, passive skills are drawn uniformly at random without replacement from either the set of Common or the set of Rainbow skills, ostensibly with some “rare event” probability determining which. Consequently, the probability of a skill of a particular Rating is proportional to the number of skills with that Rating.</p>

<p><img src="/assets/images/postimgs/pal-analysis/2_passive_rating_freq.png" alt="Fig 3. Passive Rating Frequency" class="align-center" /></p>

<p>It’ll help to have a small Ratings Table on hand for this explanation. This table shows how many distinct passive skills there are in the game, grouped by passive rating.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Rating</th>
      <th style="text-align: left">1</th>
      <th style="text-align: left">3</th>
      <th style="text-align: left">-1</th>
      <th style="text-align: left">-3</th>
      <th style="text-align: left">-2</th>
      <th style="text-align: left">2</th>
      <th style="text-align: left">Total</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">#skills w/ rating</td>
      <td style="text-align: left">34</td>
      <td style="text-align: left">15</td>
      <td style="text-align: left">9</td>
      <td style="text-align: left">3</td>
      <td style="text-align: left">2</td>
      <td style="text-align: left">1</td>
      <td style="text-align: left"><strong>64</strong></td>
    </tr>
  </tbody>
</table>

<p>The first thing to note is that the plots are just different representations of the <strong>same data</strong>. Specifically, they model the number of Common passives in the 1st skill slot with a particular rating relative to the number we’d expect to see assuming uniformity.</p>

<p>The left plot shows two distinct values: <em>observed</em> and <em>expected</em>. The <em>observed</em> is the number of skills with a particular Rating we saw in the 1st passive slot. The <em>expected</em> is the Ratings Table proportionally scaled up to our n=8878.</p>

<p>For example, there is 1 skill with Rating=2 (<em>Musclehead</em>). Assuming uniformity, 1 in every 64 first-slot skills should have Rating=2, on average. Out of 8,878 skills, we’d <em>expect</em> <code class="language-plaintext highlighter-rouge">8878(1/64) = ~139</code> of them to have Rating=2. What we actually <em>observed</em> was 147 skills. Not far off!</p>

<p>The right plot is simply combines these values (<code class="language-plaintext highlighter-rouge">observed/expected</code>) to show relative differences, rather than absolute. Values &lt; 1 mean we saw proportionally fewer skills with a Rating than we’d expect; values &gt; 1 mean there were proportionally more than expected.</p>

<p>Hopefully that’s enough convincing for the lot of you, but for any stat-stickler holdouts: a χ² test over a proportional uniform distribution produced the following:</p>

<table>
  <thead>
    <tr>
      <th>Passive Subset</th>
      <th>p-value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Common</td>
      <td>0.26868</td>
    </tr>
    <tr>
      <td>Rainbow</td>
      <td>0.77369</td>
    </tr>
    <tr>
      <td>Rainbow (+Lucky)</td>
      <td>0.23167</td>
    </tr>
  </tbody>
</table>

<p>At a significance level of 0.05, we’d fail to reject the null in all cases and therefore have insufficient evidence in favor of the alternative that the relative proportion of skills in each group differs from uniform.<br />
(Word to the wise, this is a blatant misuse of p-values, but if you’re here expecting rigor, you’ll be waiting ‘til mortis.)</p>

<h3 id="common-rainbow-probabilities-q4-q5">Common-Rainbow Probabilities (Q4, Q5)</h3>

<p>Unfortunately, my colored rectangles are on cooldown, so some good ol’ fashion tables and lines will have to do for this section. We’ll start by looking at the data from two perspectives - a per capture basis and a per skill basis.</p>

<p><em>Lucky</em> is begrudgingly included for completeness but is kept separate from the <em>real</em> Rainbow passives and is ignored whenever possible. By questioning this practice, you consent to receive my Lucky rant.<br />
You have been warned.</p>

<p><strong>Per Capture</strong></p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Words</th>
      <th style="text-align: left">Obs. Pal Proportion</th>
      <th style="text-align: left">Approx. probability</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">Blank (0 passives)</td>
      <td style="text-align: left">1050 / 10000</td>
      <td style="text-align: left">10.5%</td>
    </tr>
    <tr>
      <td style="text-align: left">At least 1 passive</td>
      <td style="text-align: left">8950 / 10000</td>
      <td style="text-align: left">89.5%</td>
    </tr>
    <tr>
      <td style="text-align: left">At least 1 Rainbow</td>
      <td style="text-align: left">71 / 10000</td>
      <td style="text-align: left">0.71%</td>
    </tr>
    <tr>
      <td style="text-align: left">At least 1 Common</td>
      <td style="text-align: left">8901 / 10000</td>
      <td style="text-align: left">89.0%</td>
    </tr>
    <tr>
      <td style="text-align: left">Lucky</td>
      <td style="text-align: left">15 / 10000</td>
      <td style="text-align: left"> </td>
    </tr>
  </tbody>
</table>

<p>I won’t hold it against you if you giddy up and go with knowledge that <strong>~1 in 140 wild-caught pals have a Rainbow passive</strong>. Though, if you’re anything like me, this just doesn’t quite scratch the itch.</p>

<p>At best, we can say we have an estimate of the probability that a pal <em>has</em> a Rainbow passive, but this doesn’t tell us the actual probability associated with <em>getting</em> a Rainbow passive. If you’re confused, hold tight. If you think this is overly pedantic — <em>welcome to empirical analysis</em>: the game where the probabilities are made up and the points don’t matter.</p>

<p>The mental framework I choose to follow for passive assignment goes like this:</p>

<ol>
  <li>Decide if the pal is Lucky with some probability we don’t care about.</li>
  <li>Determine the number of skills <strong><em>n</em></strong> by drawing from the number of passive skills distribution in Q1 (clipped at 3 if Lucky).</li>
  <li>For each empty passive slot up to <strong><em>n</em></strong>, pop a passive uniformly at random from the Rainbow set with probability <strong><em>p</em></strong> or the Common set with probability <strong>(1-</strong><strong><em>p</em></strong><strong>)</strong>.</li>
</ol>

<p>Our goal is to estimate a value for <strong><em>p</em></strong> <em>without</em> having to <a href="https://old.reddit.com/r/Palworld/comments/1ajsqk4/lifmunk_effigies_what_do_they_actually_do_800/kp70a6k/">reverse engineer it from byte code</a> because we are but mere mortals.</p>

<p><strong>Per Skill</strong></p>

<p>One key assumption in my mental framework is that <strong><em>p</em></strong> is fixed and Rainbow and Common sets are isolated. If this is not true and instead something like a weighted selection over all possible skills is used, then the independence assumption is violated, <strong><em>p</em></strong> will depend on <strong><em>n</em></strong>, and all my calculations for <strong><em>n</em></strong> &gt; 1 will be wrong. So,… fingers crossed, I guess? …… maybe we should check it.</p>

<p><img src="/assets/images/postimgs/pal-analysis/3_binomial_rainbows.png" alt="Fig 4. Binomial Rainbow Expectations" class="align-center" /></p>

<p>So. It appears as though all my calculations for <strong><em>n</em></strong> &gt; 1 will be wrong, and the independence assumption may be violated. After far too much testing, I am <em>mildly</em> confident that there <em>may</em> be some interaction between the number of passives and Rainbow skills that <em>might</em> not support the isolated skill sets hypothesis. Rousing stuff, ain’t it?</p>

<p>From here, we can either spend the next few paragraphs speculating on possible alternative implementations that better fit the data, all while losing equal parts generality and sanity, or say “RNG do be like that sometimes” and roll with what we got.</p>

<p>… I agree. Roll with it <em>is</em> the morally responsible choice. All that’s left now is to figure out exactly how much like that it do be.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">n</th>
      <th style="text-align: left">Obs. Pal Prop.</th>
      <th style="text-align: left">MLE_p[Binom(n, )]</th>
      <th style="text-align: left">P(X≥1); X ~ Binom(n, p=1/149)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">1</td>
      <td style="text-align: left">46 / 7600 (0.00605)</td>
      <td style="text-align: left">0.006054</td>
      <td style="text-align: left">50.9 / (7600 * 1)</td>
    </tr>
    <tr>
      <td style="text-align: left">2</td>
      <td style="text-align: left">14 / 960 (0.01458)</td>
      <td style="text-align: left">0.007886</td>
      <td style="text-align: left">12.7 / (960 * 2)</td>
    </tr>
    <tr>
      <td style="text-align: left">3</td>
      <td style="text-align: left">6 / 302 (0.01987)</td>
      <td style="text-align: left">0.006689</td>
      <td style="text-align: left">6.0 / (302 * 3)</td>
    </tr>
    <tr>
      <td style="text-align: left">4</td>
      <td style="text-align: left">5 / 88 (0.056818)</td>
      <td style="text-align: left">0.014368</td>
      <td style="text-align: left">2.3 / (88 * 4)</td>
    </tr>
  </tbody>
</table>

<p>We have these <strong>M</strong>aximum <strong>L</strong>ikelihood <strong>E</strong>stimates for <strong><em>p</em></strong> given <strong><em>n</em></strong> that just don’t agree. Considering single-passive pals contribute ~22x the number of skills as 4-passive pals, we may want to give them a bit more credence in our estimate.</p>

<p>A straightforward way to do this is to use the MLE for each <strong><em>n</em></strong> weighted by the proportion of skills contributed. Following this gives us <strong><em>p</em></strong> ≈ <strong>0.0067 (~1/149)</strong> and a worst case binomial test p-value of 0.087. Not great, not terrible. For <strong><em>n</em></strong> = 1, we’re only about 5 Rainbows shy of expected; for <strong><em>n</em></strong> = 4, about 3 more than expected. That’ll do.</p>

<p>At this point, you may be thinking to yourself, “<em>this is all well and good magic man, but your funny words can’t explain why it takes forever to get the passive I want</em>”.<br />
Au contraire, mon ami. Assuming this estimate for <strong><em>p</em></strong> is accurate, you can <a href="https://en.wikipedia.org/wiki/Coupon_collector%27s_problem">expect</a> needing around <strong>3,016 pal captures to collect all 8 unique Rainbows</strong>.</p>

<p>Further, in my case the game decided to provide an excellent demonstration of how expectations ≠ guarantees and <strong>it took 5,365 pals</strong> before I saw a single one with <em>Heart of the Immovable King</em>. Bizarrely, the other 7 Rainbow passives were all collected within the first 669 captures.</p>

<p>Stranger still, would you believe <strong>over half of all the Rainbows collected took at most 80 pal captures</strong>.</p>

<p><img src="/assets/images/postimgs/pal-analysis/4_rbpal_interval.png" alt="Fig 5. Rainbow Pal Interval" class="align-center" /></p>

<p>The <strong>median was 80 captures between Rainbow</strong> pals. The <strong>average was 1 Rainbow every 138.5 captures</strong>. Such a disparity is usually indicative of outliers wreaking havoc on the good, upstanding citizens of the data.</p>

<p>Lo and behold, the longest dry streak I had was <strong>764 captures without a single Rainbow</strong> pal. That’s nearly <em>100 more</em> captures with 0 than it took to originally collect <strong>7</strong> out of 8 <em>unique</em> Rainbows for the first time. It’s Bonkers I tells ya, and can’t nobody prove me otherwise.</p>

<p><strong>Getting Specific</strong></p>

<p><em>Rainbow Passives</em></p>

<p>When it comes to calculating the probability of getting any 1 specific skill, simply dividing the probability of getting any skill in the set by the number of skills in the set will get you pretty close. For Rainbows in particular, this estimate is <em>well</em> within the margin of error, but if we want to be especially obnoxious (and we do) then we’ll need to account for the possibility of getting multiple Rainbows on pal.</p>

<p>Sounds impossible, but get this — exactly 1 out of the 10k pals had a <a href="https://www.youtube.com/watch?v=OQSNhk5ICTI">d</a>ouble Rainbow. Using the Q1 n-skill distribution for <strong><em>n</em></strong> &gt; 1 and the value for <strong><em>p</em></strong> we found, the estimated <strong>probability of getting 2 or more Rainbows on pal is ~0.00107% or ~1 in 93k captures</strong>. Do I regret tossing the one I got? Well, it was Vamp and MoF, so… no.</p>

<p>Change the threshold to 1 or more Rainbows on a pal, and the probability of getting any one specific Rainbow skill can be calculated in almost the same way. The only difference we now need to account for the fact that passive skills are unique.</p>

<p>Technically speaking, we’re playing in hypergeometric land now. Because we’re only interested in 1 skill at a time, however, we can simplify and say it’s the <em>expected</em> number of Rainbows on a pal, divided by the number of Rainbows (8). This amounts to a <strong>probability for any single capture to have a specific Rainbow skill of ~0.09% or ~1 in 1110</strong>.</p>

<p><em>Common Passives</em></p>

<p>In contrast to Rainbows, long-time fans of the game and/or tautologies might know that Common passives are common. As a result, the specific Common passive calculation is influenced far more by the effects of multi-passive pals. Deciding not to ignore this case before means we’re on easy street now.</p>

<p>All we need is the probability associated with getting any Common passive. I bet if we give <strong><em>p</em></strong> a <em>really</em> nice complement, it’ll tell us the probability that a given skill is <em>not</em> Rainbow (aka Common).</p>

<p>Using <strong><em>p</em></strong>-complement (<strong><em>1-p</em></strong>) and the Q1 distribution, we calculate the <em>expected</em> number of Commons on a pal and divide by the number of Commons (64) to get the <strong>single-capture specific Common skill probability of ~1.67% or ~1 in 60</strong>.</p>

<hr />

<h2 id="yakumo-bonus-round">Yakumo (Bonus Round)</h2>

<p>If you managed to read all the way to here, pat yourself on the back; that was a lot of information.<br />
If you read the TL;DR and then scrolled right to here, pat yourself on the back; that was a lot of scrolling. In either case, you’re in for a treat.</p>

<p>We’ll now discuss what I believe to be 2 completely novel (or at least little known) facts about how Yakumo’s partner ability “Birds of a Feather” (BoaF) works under the hood.</p>

<p>Dataset</p>

<ul>
  <li>1000 Gobfin captures with a max-condensed Yakumo out the entire duration. The Yakumo was bred to have 4 Rainbow-tier passives (EE, Swift, DG, RC) to minimize the influence of random skill rolls.</li>
</ul>

<p>Background info</p>

<ul>
  <li>Yakumo’s partner ability makes it “easier to encounter pals with the same Passive Skill as this Pal.” Where “easier” = <a href="https://paldb.cc/en/Yakumo">30% chance for passive sync</a> when max-condensed.</li>
  <li>A pal’s passive skills are determined on <strong>spawn, not capture</strong>. By the time you can see a pal in the wild, its passives have already been determined. This is how <a href="https://www.nexusmods.com/palworld/mods/336">skill-peak mods</a> can exist.</li>
</ul>

<h3 id="its-all-adding-up">It’s All Adding Up</h3>
<p><strong>1. Yakumo’s partner ability</strong> <strong><em>adds</em></strong> <strong>passive skills to a pal. It does not</strong> <strong><em>replace</em></strong> <strong>existing skills</strong></p>

<p>If BoaF were purely <strong>substitutional</strong>, the average skill count would be unchanged, so we’d expect a skill count distribution exactly like the one in Q1.<br />
If it were <strong>additive</strong>, the average skill count would go up, the distribution would spread and shift right, and <em>removing the matches would get us back to the Q1 distribution</em>.<br />
If it were <strong>both</strong>, removing the matching skills from skill counts would result in the majority of pals having 0 passive skills due to many being replaced.</p>

<p>Well, prepare yourself. As far as evidence goes it don’t get much more damning than this —</p>

<p><img src="/assets/images/postimgs/pal-analysis/5_yakumo_n_passives.png" alt="Fig 6. Yakumo Passive Skill Counts" class="align-center" /></p>

<p>The left chart shows the raw skill count frequencies. The right chart shows the skill count frequencies after removing the 4 Rainbows that matched Yakumo’s set.</p>

<p>You’ll notice that <strong>removing the matches recovers a nearly identical distribution to that of Q1</strong>. Seriously, scroll back up, I’ll wait. ….</p>

<p>…. You back? Okay cool.</p>

<p>Aside from a little noise from the dataset being 1/10th the size and the possibility that a couple of RNG’d matches were removed, we are just about bang on. I could run a stat test to formalize it, but at this point, I feel like that’s just rude. <em>Myth Busted</em>.</p>

<p><strong>Practical Application</strong></p>

<p>Whenever I had a specific breed chain in mind but was missing 1 pal, I debated if Yakumo would help the hunt even though other pals in the chain already had all the desired passives. Knowing that BoaF can only add skills gives us the answer.</p>

<p>If you need a breeding match that’s either <strong>blank or has 100% skill overlap, leave the Yakumo at home</strong>. Exclusively being able to add skills means any pal you capture will always have the <strong>same or lower chance</strong> of breeding a desired skill combination.</p>

<h3 id="more-is-more">More is More</h3>

<p><strong>2. Using single-skill Yakumos is</strong> <strong><em>not</em></strong> <strong>optimal, and the probability of getting</strong> <strong><em>m</em></strong> <strong>matches is</strong> <strong><em>not</em></strong> <code class="language-plaintext highlighter-rouge">0.30^m</code></p>

<p>Obvious thing out of the way first. We established that it’s additive and cannot overwrite any existing skills. You might guess that would mean the probability is actually <code class="language-plaintext highlighter-rouge">0.30^min(4-n, m)</code>, where <strong><em>n</em></strong> is the number of skills a pal starts with and <strong><em>m</em></strong> is the number of matching skills.</p>

<p>Although that’s a good guess, and your participation is both noted and appreciated, that’s not quite right. The good news is the devs love us a little more than that. The bad news is the binomial distribution is back. And this time… <em>It’s probable.</em></p>

<p><img src="/assets/images/postimgs/pal-analysis/6_yakumo_PA_map.png" alt="Fig 7. Yakumo Skill Transfer Frequency" class="align-center" /></p>

<p>The heatmap above shows the breakdown of how many skills Yakumo’s partner ability contributed to the total number on each pal. The darkest diagonal corresponds to the most common case where the pal starts with 1 passive skill and then BoaF appends between 0-3 additional skills. Above that diagonal is the 0-initial passives case, and below is the 2-initial passives case, and so on.</p>

<p>These results strongly suggest that <strong>BoaF rolls once for</strong> <strong><em>every</em></strong> <strong>passive skill on Yakumo</strong> while passive slot space remains. <strong>It does not stop</strong> if a skill fails to transfer. This means the probability of transferring <strong><em>m</em></strong> out of <strong><em>M</em></strong> passives is better modeled by <code class="language-plaintext highlighter-rouge">p[X=m]; X~Binom(n=M, p=0.30)</code> rather than <code class="language-plaintext highlighter-rouge">0.30^m</code>.</p>

<p>I’m sure you all remembered to bring in your personal favorite statistical software today, but just in case, here’s a handy-dandy table to take with you on your travels.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">M (#yakumo)  \ m (#hits)</th>
      <th style="text-align: left">0</th>
      <th style="text-align: left">1</th>
      <th style="text-align: left">2</th>
      <th style="text-align: left">3</th>
      <th style="text-align: left">4</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">4</td>
      <td style="text-align: left">24.68%</td>
      <td style="text-align: left">41.85%</td>
      <td style="text-align: left">26.23%</td>
      <td style="text-align: left">7.16%</td>
      <td style="text-align: left">0.085%</td>
    </tr>
    <tr>
      <td style="text-align: left">3</td>
      <td style="text-align: left">34.88%</td>
      <td style="text-align: left">44.36%</td>
      <td style="text-align: left">18.42%</td>
      <td style="text-align: left">2.33%</td>
      <td style="text-align: left"> </td>
    </tr>
    <tr>
      <td style="text-align: left">2</td>
      <td style="text-align: left">49.45%</td>
      <td style="text-align: left">41.90%</td>
      <td style="text-align: left">8.65%</td>
      <td style="text-align: left"> </td>
      <td style="text-align: left"> </td>
    </tr>
    <tr>
      <td style="text-align: left">1</td>
      <td style="text-align: left">70.26%</td>
      <td style="text-align: left">29.74%</td>
      <td style="text-align: left"> </td>
      <td style="text-align: left"> </td>
      <td style="text-align: left"> </td>
    </tr>
  </tbody>
</table>

<p>These are the probabilities for transferring any subset of <strong><em>m</em></strong> out of <strong><em>M</em></strong> total passives from Yakumo to the target pal after adjusting for expected skill capacity (free passive slots).</p>

<p>For all <strong><em>m</em></strong> &lt; 4, the relative difference from <code class="language-plaintext highlighter-rouge">Binom(n=M, p=0.30)</code> is fairly small, but because only 10.5% of pals have 4 free slots (aka start with 0-passives), the odds of a perfect 4/4 match are reduced by nearly an order of magnitude.<br />
This helps explain why there wasn’t a single perfect match out of 1000 captures. Given a probability this low, only about <strong>1 in every 1176 captures would transfer all 4/4 skills</strong> on average.</p>

<p>For completeness’ sake, here’s a brief rundown of the implementations considered</p>

<ul>
  <li>Roll once per Yakumo skill
    <ul>
      <li>The best guess given the data.</li>
    </ul>
  </li>
  <li>Roll once per free slot
    <ul>
      <li>If this were true, distribution would be a lot closer to Binom(p=0.3, n=3), considering 76% of pals have 3 free slots. We’d also expect pals with 1 free slot to only hit 30% of the time compared to 80% shown in the data.</li>
    </ul>
  </li>
  <li>Roll a constant 4x regardless of the number of free slots and skills
    <ul>
      <li>No way to differentiate from the data, but this would mean a 1 passive Yakumo would have a 0.7599 * 0.9912 ≈ 75.3% transfer chance on each capture. Anecdotally speaking, yeah… no.</li>
    </ul>
  </li>
  <li>Roll max(free slots, yakumo passives)
    <ul>
      <li>Again, no way to differentiate from the data, but the single passive Yakumo in this case would still hit about 63.7% of the time, which still seems unrealistic.</li>
    </ul>
  </li>
</ul>

<p><strong>Practical Applications</strong></p>

<p><em>Optimal Setup</em></p>

<p>Let’s assume you want to <strong>transfer 4 passives to a pal</strong>.</p>

<p>The optimal setup is to have 1 max-condensed Yakumo for every unique combination of passive skills. Start with the 4 passive Yakumo. Once you get at least 1 hit, switch to a Yakumo that has all the passives that didn’t transfer. Repeat until all 4 passives are collected and then breed away.<br />
Following this idealized approach, <strong>on average, you’d need to capture 6.5 pals to transfer all 4 passives</strong> to the target.</p>

<p>Despite only ever needing to use at most 4, you’ll have to have 1+4+6+4 = <strong>15 max-condensed Yakumos</strong> in order to achieve full coverage. So if you’re cool making enough puppy mash to make Cruella de Vil look like a level 5 hyper-vegan, that’s the way to do it.</p>

<p>Now, maybe you’re not keen on the idea of making all that dog soup; fear not, you can still reap some benefits with only a fraction of the canine liquefaction.</p>

<p><em>Realistic Setup</em></p>

<p>Once you get to the point in the game where your ability to max-condense multiple copies of the same pal is limited only by the love you have for yourself, there are very few instances in which you’d actually <em>need</em> BoaF to transfer 4 passives to a pal.</p>

<p>When you’re best option is max-condensing Yakumos, it probably means that the pal you’re after cannot be bred into. Excluding pals that randomly fall out of the sky, 4 out of 5 capturable, self-breed-only pals are legendary pals, which typically need at most 3 skills transferred.</p>

<p>Your goal now is to <strong>transfer 3 passives to a legendary pal</strong>, for example [Swift, EE, Runner] on a Jetragon.<sup>1</sup></p>

<p>Just as before, the <em>optimal</em> setup is to have a Yakumo for every unique combination of skills (1+3+3 = 7 Yakumos) and would take an average of <strong>7.71 captures for all 3 to transfer</strong>. But you’re not here for optimal, you’re here because you <del>are lazy</del> care deeply about preserving the solidity of your Yakumos. I respect that and am here to tell you that, contrary to popular belief, your next best option isn’t 3x 1-passive Yakumos, it’s 1x 3-passive Yakumo.</p>

<p>These are the expected number of <strong>captures required to transfer 3 skills to a 2-innate pal</strong> under each of the no-overlapping-skills configurations</p>

<ul>
  <li>1-passive Yakumo → 1-passive Yakumo → 1-passive Yakumo= <strong>11.56 captures</strong></li>
  <li>2-passive Yakumo → 1-passive Yakumo = <strong>10.65 captures</strong></li>
  <li>3-passive Yakumo = <strong>9.68 captures</strong></li>
</ul>

<p>Ultimately, the reason behind this is exactly what you’d expect. When each skill rolls independently, more skills = more rolls = more opportunities to transfer a skill. It also doesn’t hurt that there is a (small) chance to have 2 skills transfer in one capture — a suspiciously rare outcome with 1-passive Yakumos.</p>

<p>Do note, however, that this all is assuming that you are starting from scratch. It’s <strong>always better to switch to a max-condensed Yakumo with a smaller subset of desired skills</strong> if you have one.</p>

<p>For example, if you happen to get EE using your [Swift, EE, Runner] Yakumo and you have a max-condensed [Swift, Runner] Yakumo lying around, you should switch to maximize your chance of completing the set.</p>

<p><sup>1</sup> At most 2 skills can transfer at a time due to innates. This example uses the previously speculated <strong>2-innate passive skill distribution</strong>: <code class="language-plaintext highlighter-rouge">[0: 10.5%, 1: 76.0%, 2: 13.5%]</code>. The table below shows the adjusted n-skill transfer probabilities for a 2-innate pal.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">M (#yakumo) \ m (#hits)</th>
      <th style="text-align: left">0</th>
      <th style="text-align: left">1</th>
      <th style="text-align: left">2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">4</td>
      <td style="text-align: left">34.27%</td>
      <td style="text-align: left">62.07%</td>
      <td style="text-align: left">3.66%</td>
    </tr>
    <tr>
      <td style="text-align: left">3</td>
      <td style="text-align: left">43.17%</td>
      <td style="text-align: left">54.56%</td>
      <td style="text-align: left">2.27%</td>
    </tr>
    <tr>
      <td style="text-align: left">2</td>
      <td style="text-align: left">55.89%</td>
      <td style="text-align: left">43.17%</td>
      <td style="text-align: left">0.945%</td>
    </tr>
    <tr>
      <td style="text-align: left">1</td>
      <td style="text-align: left">74.05%</td>
      <td style="text-align: left">25.95%</td>
      <td style="text-align: left"> </td>
    </tr>
  </tbody>
</table>

<h2 id="breeding-eggs-μbonus">Breeding Eggs (μBonus)</h2>

<p>Initially, this was going to be a fully fleshed out section like Yakumo, but 1) this post is already ungodly long, 2) there isn’t enough data to draw particularly strong conclusions, 3) — and this is key — I don’t really <em>feel</em> like it.<br />
With that ethos in mind, let’s get into it.</p>

<p>Dataset</p>

<ul>
  <li>1237 Gobfin eggs produced by 16 distinct pairs of blank Gobfin parents. No eggs were incubated; all were analyzed pre-hatch.</li>
</ul>

<h3 id="blank-expressions">Blank Expressions</h3>
<p><strong>1. Myth Bustin’ - You absolutely</strong> <strong><em>can</em></strong> <strong>breed a 0-passive pal.</strong></p>

<p>I’ve seen a handful of debates between people on the topic of breeding blank pals. The general consensus seems to be that it’s either not possible or extremely rare. It’s high-time we dispel that rumor. Not only is this <em>possible</em>, in my case, it was by far the <strong>most common outcome</strong>.</p>

<p><img src="/assets/images/postimgs/pal-analysis/7_egg_n_passives.png" alt="Fig 8. Breeding Skill Count Frequency" class="align-center" /></p>

<p>Impressed yet? Because you really shouldn’t be. Remember, both parents have 0-passive skills, so all this really shows is that 40% of the time the <strong>child will draw from the skill pool of the parents, even if that pool is the empty set</strong>. I suppose you could argue this provides some new information, but that slightly depends on your view of words like ‘new’ and ‘information’.</p>

<p>What this does give us, however, is proof that the well-renowned <a href="https://mxtsdev.github.io/PalworldBreedingProbabilities/">Breeding Probabilities Calculator</a> is wrong. Strictly speaking, <code class="language-plaintext highlighter-rouge">[0,0,0]; [0,0,1]; [0,0,2]; [0,0,3]</code> are all valid inputs and should be 40%, 30%, 20%, and 10%, respectively. Is this useful information in 99.997% of cases? Absolutely not. But <em>technically</em>, it <em>is</em> the best kind of correct.</p>

<p>Also, ain’t it cool to see how close the randomly sampled data comes to the known [40,30,20,10], <a href="https://www.reddit.com/r/Palworld/comments/1af9in7/passive_skill_inheritance_mechanics_in_breeding/?rdt=64906">reverse-engineered distribution</a> that our forefather u/mgxts bestowed unto us long ago?</p>

<h3 id="wild-breeding-mutations">Wild Breeding Mutations</h3>

<p><strong>2. Are random breeding mutation and wild-caught passive skills drawn from the same distribution?</strong></p>

<p>¯\_(ツ)_/¯</p>

<p><img src="/assets/images/postimgs/pal-analysis/8_egg_passive_counts.png" alt="Fig 9. Breeding Mutation Skill Distribution" class="align-center" /></p>

<p>More specifically: <em>probably.</em> For Common skills, I can back that up. For Rainbow skills… it’s all <em>v i b e s</em>.</p>

<p>We can play the same game as before and run a goodness-of-fit test over the uniform distribution and first slot Common passive skill counts. This time around, we’ll go with the slightly more robust <a href="https://en.wikipedia.org/wiki/G-test">G-test</a> rather than χ² because these shark kids are all thumbs.</p>

<p>A G-test over the proportional uniform gives a p-value of 0.38828. Just like last time, this doesn’t <em>confirm</em> it’s uniform, but it does hint at the possibility that it’s not-<em>not</em>-uniform! Hmm…Your eyes seem to have glazed over there.. Okay, how about we take a more direct approach.</p>

<p>Using the contingency table formulation, we can directly compare the expected frequencies of the egg-group and wild-group. In doing so, we find a p-value of 0.79464, meaning that we fail to reject the null <em>even harder</em>. You love to see it. The null in this case is that the relative frequencies in the groups are the same, i.e., <strong>Common passives occur with the same frequency in both the case of wild-caught and breeding-mutation skills</strong>.</p>

<p>To put a wrap on it, I’ll say, although there’s insufficient data to make any claims about the breeding Rainbow 🌈⭐, the lazy developer in me says there’s a good chance it’s the same. Why use many number when 1 do trick?</p>

<p>There were a total of 4 Rainbows across the 1237 eggs examined. You can peek at the table below to see which ones, along with my manually-collected, almost-certainly-wrong “data” I gathered while trying to breed a perfect Jetragon a while back.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Rainbow Skill</th>
      <th style="text-align: left">Gobfin Eggs (n=1237)</th>
      <th style="text-align: left">Unreliable Jetragons (n=934)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">Demon God</td>
      <td style="text-align: left">1</td>
      <td style="text-align: left">2</td>
    </tr>
    <tr>
      <td style="text-align: left">Diamond Body</td>
      <td style="text-align: left">2</td>
      <td style="text-align: left">1</td>
    </tr>
    <tr>
      <td style="text-align: left">EE, HotK, MoF</td>
      <td style="text-align: left">-</td>
      <td style="text-align: left">-</td>
    </tr>
    <tr>
      <td style="text-align: left">Remarkable Craftsmanship</td>
      <td style="text-align: left">1</td>
      <td style="text-align: left">1</td>
    </tr>
    <tr>
      <td style="text-align: left">Swift</td>
      <td style="text-align: left">-</td>
      <td style="text-align: left">-</td>
    </tr>
    <tr>
      <td style="text-align: left">Vampiric</td>
      <td style="text-align: left">-</td>
      <td style="text-align: left">1</td>
    </tr>
  </tbody>
</table>]]></content><author><name>Ryan Gust</name><email>MY_FIRST_NAME@MY_LAST_NAME.dev</email></author><category term="analysis" /><summary type="html"><![CDATA[Probing passives probabilities in Palworld. Exploring game mechanisms with empirical data analysis.]]></summary></entry></feed>