App Factory
How ideas are scored
Every idea on the list is a search term someone might type into Google Play, such as "mma training". The finder looks at the apps Play shows for that term and gives the idea an opportunity score from 0 to 100. Higher means a better chance for a solo developer to build an app people want and will pay for. All of this is plain code with no AI (stages/finder/score.py).
Step 1: collect the data
For each search term, the finder:
- takes the top 10 apps Google Play shows for it, with installs, star rating, number of ratings, the star breakdown (how many 1 to 5 star ratings), price, in-app purchases, ads and the last update date;
- sets aside games and big brands (Nike, Strava, Garmin, banks, and so on). Games attract a different audience. People stay with brands whatever they think of the app, so we can't win their users;
- picks the 3 biggest remaining apps as "targets", the apps whose unhappy users we could win over, and reads up to 100 of their newest 1 to 3 star reviews;
- has a cheap AI model (Haiku) group those reviews into complaint themes, such as "lost my workouts after the update", and say whether each one is fixable. Every theme must point to real reviews.
Step 2: five sub-scores, each 0 to 100
| Sub-score | Question it answers | Higher when |
|---|---|---|
| Demand | Do people want this? | The apps for this term have many installs |
| Unhappy users (dissatisfaction) | Are current users unhappy? | Ratings are low, there are many 1 to 2 star ratings, apps are abandoned, and one fixable complaint dominates |
| Beatable | Can a newcomer compete? | The leading app is small or poorly rated, and few of the apps are brands |
| Pays (monetization) | Will people pay? | Competitors charge, sell in-app purchases or show ads |
| Evidence | How much data backs this? | The target apps have many ratings and many reviews tied to complaint themes |
Demand
Adds up the installs of the non-game apps. Each app counts only as much as its title matches the specific words of the search term, so a general workout app adds little to "rowing machine workout". Generic words like "workout", "free" and "timer" don't count as a match. The total is placed on a log scale: 1,000 installs gives 0 and 100 million gives 100.
Unhappy users
Looks only at the target apps that have ratings, weighting bigger apps more:
- 50%: average star rating. 4.6 stars or more gives 0 and 3.0 stars gives 100.
- 30%: share of 1 and 2 star ratings. 5% or less gives 0 and 35% or more gives 100.
- 20%: share of apps not updated in over a year.
When complaint themes exist, this blend becomes 80% of the score. The other 20% is complaint focus: how much of an app's low-star reviews fall into its single biggest fixable complaint. One clear, fixable problem is a better opening than scattered noise.
Known weakness: most established Play apps sit at 4.5 to 4.9 stars, so the rating part is often near 0 (lesson L001).
Beatable
Looks at the 5 biggest non-game apps and the "leader", the one with the most ratings:
- 45%: leader size. 1 million ratings gives 0 and 1,000 or fewer gives 100.
- 30%: leader quality. 4.8 stars or more gives 0 and 3.5 stars gives 100. A well-loved leader is hard to pull users from. A brand leader gets 0 here however it's rated.
- 25%: share of the top 5 that aren't brands.
Pays
- 80%: share of competitors that charge or sell in-app purchases. 80% or more of them gives 100.
- 20%: share that show ads.
Evidence
- 50%: total ratings on the target apps. 100 gives 0 and 10,000 gives 100.
- 50%: low-star reviews tied to a complaint theme. 40 or more gives 100.
Step 3: combine into one score
The first four sub-scores are combined with a weighted geometric mean:
| Demand | Unhappy users | Beatable | Pays |
|---|---|---|---|
| 30% | 25% | 25% | 20% |
A geometric mean multiplies instead of adding. A very weak sub-score therefore drags the whole idea down: a huge market with an unbeatable leader still scores low. No sub-score counts as less than 1, so a single zero doesn't wipe out the idea.
Then evidence applies a discount. An idea with full evidence keeps its score, and one with no evidence loses 30%. In between it scales smoothly: score × (0.7 + 0.3 × evidence ÷ 100).
Worked example: "mma training" (9 Nov data, current formula)
Sub-scores: demand 54.3, unhappy users 59.2, beatable 63.8, pays 73.3, evidence 49.4.
- Geometric mean: 0.543^0.30 × 0.592^0.25 × 0.638^0.25 × 0.733^0.20 = 61.3
- Evidence discount: 0.7 + 0.3 × 0.494 = 0.848
- Opportunity: 61.3 × 0.848 = 52.0
Step 4: rank, review, and grow the list
- Ranking. Every idea is re-scored each Monday from fresh Play data, and the list is sorted best first.
- Grouping similar terms. Search terms that show mostly the same apps are one idea, not several. Two terms are grouped when at least 70% of their Play results are the same apps, or at least 50% when one term's words contain the other's ("kettlebell workout" and "kettlebell workout free"). Each group is listed once, under its best-scoring term, with the other terms shown as "similar search terms". Their scores and data are kept. A term is only compared with group leaders, so a chain of loosely similar terms can't merge unrelated ideas. This is plain code with no AI (
stages/finder/group.py). - AI final review. The strongest model (Fable) reads the top 10 distinct ideas (with their similar terms) and the scoring code. It gives each idea a verdict (strong, maybe or weak), its strengths and concerns, and an app concept, and it flags problems in the formula. It never changes a score. Math stays in code.
- New ideas. The finder discovers new search terms from Play's search suggestions, Google's suggestions, phrases shared by competitor titles, and complaint themes. Each run tries up to 30 of them.
- The bar. A tried term is kept if it scores at least the median (middle) score of the ideas already on the list, with a minimum of 20. Otherwise it's dropped and tried again after 90 days. The bar rises as the list improves.
- Your starting terms (
seeds.yaml) always stay on the list. Kept ideas are never removed, though they can slide down the ranking.
History
- 27 Oct 2026: first version (demand, dissatisfaction, beatability, monetization).
- 13 Nov 2026 (PR #5): fixed four problems the final review found. Staleness now counts only once, demand is weighted by title match, beatability now includes the leader's rating, and the evidence discount was added. See lessons L002 to L005.
- 13 Nov 2026: near-duplicate search terms are grouped into one idea, so the top 10 shows 10 different ideas (lesson L007). Scores themselves didn't change. Rank moves in the first run after this compare against the ungrouped list, so some ideas will show a jump.
When you change score.py, update this page too.