<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aleksei Martiushin</title>
    <description>The latest articles on DEV Community by Aleksei Martiushin (@raisingstoics).</description>
    <link>https://dev.to/raisingstoics</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4205005%2F1e25281f-24dc-4565-862d-4ea3c9c6422c.png</url>
      <title>DEV Community: Aleksei Martiushin</title>
      <link>https://dev.to/raisingstoics</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/raisingstoics"/>
    <language>en</language>
    <item>
      <title>How we built an open dataset of kids' app and game risk flags (CC BY 4.0, DOI)</title>
      <dc:creator>Aleksei Martiushin</dc:creator>
      <pubDate>Sat, 24 Oct 2026 15:36:41 +0000</pubDate>
      <link>https://dev.to/raisingstoics/how-we-built-an-open-dataset-of-kids-app-and-game-risk-flags-cc-by-40-doi-ph3</link>
      <guid>https://dev.to/raisingstoics/how-we-built-an-open-dataset-of-kids-app-and-game-risk-flags-cc-by-40-doi-ph3</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I'm Aleksei Martiushin. I run Raising Stoics, a site for parents of kids ages 4–8, and I built the dataset described below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Parents of young kids keep asking the same question about games, apps, and shows: "Is this OK for my 6-year-old?" The facts that answer it are public, but they are scattered. The ESRB rating sits on one site, PEGI on another, in-app purchases on the store listing, a loot box mechanic in the rating descriptors, and an FTC settlement in a press release.&lt;/p&gt;

&lt;p&gt;We pulled those facts into two small datasets and published them on Zenodo under CC BY 4.0 with DOIs. This post covers how they're structured, how the values were chosen, what a row looks like, and where the data is weak.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two datasets
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Official age ratings, October 2026&lt;/strong&gt; — &lt;a href="https://doi.org/10.5281/zenodo.23619760" rel="noopener noreferrer"&gt;doi.org/10.5281/zenodo.23619760&lt;/a&gt;&lt;br&gt;
461 titles (127 games, 65 apps, 24 YouTube channels, 87 movies, 112 shows, 44 toys) and 1,210 rating records across MPA, US TV Parental Guidelines, ESRB, PEGI, BBFC, FSK/USK, Apple App Store, Google Play (IARC), manufacturer age labels, Roblox content labels, and minimum ages in company terms. 1,136 of those records link to their source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Kids' Media Risk Index, October 2026 edition&lt;/strong&gt; — &lt;a href="https://doi.org/10.5281/zenodo.23619163" rel="noopener noreferrer"&gt;doi.org/10.5281/zenodo.23619163&lt;/a&gt;&lt;br&gt;
259 titles, each checked against six yes/no flags. Data frozen on 2026-10-18; this version won't change.&lt;/p&gt;

&lt;p&gt;Both are snapshots. The per-title pages on the site keep updating, but the files on Zenodo don't, so a number you cite today will still match the file later.&lt;/p&gt;
&lt;h2&gt;
  
  
  File layout
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kids-media-official-age-ratings-2026-10-titles.csv    # one row per title
kids-media-official-age-ratings-2026-10-ratings.csv   # one row per rating record
kids-media-official-age-ratings-2026-10.json          # both tables + metadata

kids-media-risk-index-2026-10.csv                     # one row per title, flags 1–6
kids-media-risk-index-2026-10-evidence.csv            # one row per title × flag (1,554 rows)
kids-media-risk-index-2026-10.json                    # everything + flag definitions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;slug&lt;/code&gt; is the join key across all files. Each slug also maps to a page at &lt;code&gt;https://raisingstoics.com/is-it-good-for-kids/&amp;lt;slug&amp;gt;&lt;/code&gt; that lists the sources for that title.&lt;/p&gt;
&lt;h2&gt;
  
  
  What a row looks like
&lt;/h2&gt;

&lt;p&gt;Ratings file (one title can have many rows, one per rating system):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;slug,name,type,system,official,label_in_guide,rating_as_recorded,source_url,checked
roblox,Roblox,game,ESRB (US &amp;amp; Canada),yes,US &amp;amp; Canada (ESRB),"T for Teen (ages 13 and up) — Diverse Content: Discretion Advised; Users Interact; In-Game Purchases (Includes Random Items)",https://www.esrb.org/news/what-parents-need-to-know-about-roblox,October 2026
roblox,Roblox,game,PEGI (Europe &amp;amp; UK),yes,Europe &amp;amp; UK (PEGI),Parental Guidance Recommended (no age number) — In-game purchases,https://pegi.info/search-pegi?q=roblox,October 2026
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Risk index (one row per title):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;slug,name,type,flag_set,official_rating,rating_source,age_level,flag_1,flag_2,flag_3,flag_4,flag_5,flag_6,flag_count,checked,url
minecraft,Minecraft,game,interactive,10+,ESRB: E10+,3,1,1,1,0,1,0,4,October 2026,https://raisingstoics.com/is-it-good-for-kids/minecraft
bluey,Bluey,show,media,All ages,TV-Y,0,0,0,0,0,0,0,0,October 2026,https://raisingstoics.com/is-it-good-for-kids/bluey
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Evidence (why a flag is 1):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;slug,name,flag_set,flag_number,flag_name,value,evidence
roblox,Roblox,interactive,2,Contact with other players or strangers,1,ESRB: Users Interact
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Design decisions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;One age scale across rating systems.&lt;/strong&gt; ESRB, PEGI, the MPA, and app stores all use different labels. We map every title to a 0–6 &lt;code&gt;age_level&lt;/code&gt; (0 = all ages, 1 = 5–7+, 2 = 7–8+ / PG, 3 = 9–10+, 4 = 12–13+, 5 = 15–16+, 6 = 17–18+). Only official ratings set the level, in a fixed order of precedence for each type. Movies use the MPA, then the BBFC. Games use the ESRB, then the app stores for mobile-only games. Roblox experiences take the platform rating. Toys use the maker's label. When official sources disagree, we use the stricter rating and keep both in the ratings file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common Sense Media is kept but labeled.&lt;/strong&gt; It's a review, not an official rating, so those rows have &lt;code&gt;official = no&lt;/code&gt; and don't set &lt;code&gt;age_level&lt;/code&gt;. The one exception is 17 titles in the risk index that have no official rating at all. For some of them, flag 1 uses Common Sense Media's age guidance, and the README says so.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three flag sets, not one.&lt;/strong&gt; A loot-box flag makes no sense for a movie, and "rated 12+ in the UK or Germany" makes no sense for a toy. So &lt;code&gt;flag_set&lt;/code&gt; is &lt;code&gt;interactive&lt;/code&gt; (games, apps, YouTube channels), &lt;code&gt;media&lt;/code&gt; (movies, shows), or &lt;code&gt;toy&lt;/code&gt;, and each set has its own six flags. If you compare &lt;code&gt;flag_count&lt;/code&gt; across sets, you're mixing different questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Mild" doesn't count.&lt;/strong&gt; When a rating body describes content as "mild" (for example "Mild Fantasy Violence"), it doesn't trigger the violence, scary-content, language, or sex/drugs flags in the media set.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lawsuits are claims.&lt;/strong&gt; Flag 6 for interactive titles and toys counts government lawsuits, fines, and safety warnings, reported as filed rather than proven. Private lawsuits aren't counted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero means "not found".&lt;/strong&gt; A &lt;code&gt;0&lt;/code&gt; says we couldn't document the flag from public sources by the check date. It doesn't prove the thing is absent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick look with pandas
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kids-media-risk-index-2026-10.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;games&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flag_set&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;interactive&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# 157 titles
&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rating &amp;gt; 7&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;purchases&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;loot boxes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;violence/scary&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gov. action&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;games&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;flag_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)]].&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="c1"&gt;# {'rating &amp;gt; 7': 121, 'contact': 107, 'purchases': 122,
#  'loot boxes': 42, 'violence/scary': 104, 'gov. action': 28}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of the 157 games, apps, and YouTube channels, 122 have real-money purchases, and 121 carry an official rating above age 7, even though they're among the titles US parents of 4–8-year-olds search for most.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the data was made
&lt;/h2&gt;

&lt;p&gt;The titles are the ones in our per-title guides, which were picked because parents search for them. That makes them a convenience sample, not a random sample of children's media, so the counts describe this list and nothing more. The guides are drafted with AI assistance, and a separate reviewer then checks each one against its sources. The ratings and flags come from the official sources linked in each row, not from the model's memory. Our editorial standards are at &lt;a href="https://raisingstoics.com/editorial-standards" rel="noopener noreferrer"&gt;raisingstoics.com/editorial-standards&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ratings vary by release (cinema vs. home video, season, edited version), by country, and by platform. &lt;code&gt;rating_as_recorded&lt;/code&gt; names the release where we could.&lt;/li&gt;
&lt;li&gt;Some streaming ratings were read from the service's listing as indexed by search, and are marked that way.&lt;/li&gt;
&lt;li&gt;Store listings and company practices change. This is an October 2026 snapshot.&lt;/li&gt;
&lt;li&gt;The index counts documented facts. It is not a safety score, and it doesn't weight one flag against another.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using it
&lt;/h2&gt;

&lt;p&gt;The license is CC BY 4.0, so you can use the data for anything as long as you credit the source. The citation is in each README. Charts and the method page are at &lt;a href="https://raisingstoics.com/kids-media-risk-index" rel="noopener noreferrer"&gt;raisingstoics.com/kids-media-risk-index&lt;/a&gt;. If you find a wrong rating, email &lt;a href="mailto:hello@raisingstoics.com"&gt;hello@raisingstoics.com&lt;/a&gt; with the source and I'll fix it in the next edition.&lt;/p&gt;

&lt;p&gt;I'd especially like feedback on the age-level mapping. Collapsing ESRB, PEGI, IARC, and the MPA onto one 0–6 scale involves judgment calls, and other people may draw the lines differently.&lt;/p&gt;

</description>
      <category>opendata</category>
      <category>datascience</category>
      <category>datastructures</category>
    </item>
  </channel>
</rss>
