- name
- monetization-analyzer
- description
- Analyze game concepts for monetization potential, willingness-to-pay, viral mechanics, and revenue generation. Ranks concepts by total monetization score and identifies top revenue opportunities.
# Monetization Analyzer Skill
## Purpose
This skill evaluates game concepts to identify the most monetizable opportunities based on:
- **Willingness-to-Pay (WTP)** analysis from market data
- **Viral potential** and organic growth mechanics
- **Revenue model optimization** (premium, F2P, subscription, hybrid)
- **Market demand** and addressable market size
- **Competitive pricing** positioning
- **Lifetime Value (LTV)** projections
**Output**: Ranked list of top 3 most monetizable game concepts with detailed financial projections and go-to-market recommendations.
## When to Use This Skill
Use this skill when you have:
- ✅ Multiple game concepts to evaluate for investment prioritization
- ✅ Market analysis data showing pricing sentiment and willingness-to-pay signals
- ✅ Need to identify which concepts have highest revenue potential
- ✅ Want to optimize monetization models before development
- ✅ Require financial projections for pitch decks or funding proposals
- ✅ Need to validate business model assumptions with market data
## Prerequisites
### Required Input Files
1. **Market Analysis Report** (from `market-analyst` skill)
- Location: `/docs/market-analysis-*.md`
- Must include: Sentiment data on pricing, monetization pain points, willingness-to-pay signals
- Example: `market-analysis-fps-games-2025-10-26.md`
2. **Game Concepts Document** (from brainstorming/design)
- Location: `/docs/*-game-concepts-*.md` or `/docs/plans/*-design.md`
- Must include: Price points, target personas, distribution channels, competitors
- Example: `fps-game-concepts-market-driven-2025-10-26.md`
### Optional Input Files
3. **Competitor Financial Data** (if available)
- Revenue reports, player counts, ARPU data
- Enhances accuracy of projections
## Core Workflow
### Phase 1: Data Extraction and Normalization
**1. Load Market Analysis**
Extract willingness-to-pay signals:
```javascript
WTP_Signals = {
price_sentiment: {
"$0 (F2P)": {positive: X%, negative: Y%, mentions: N},
"$10-20": {positive: X%, negative: Y%, mentions: N},
"$20-30": {positive: X%, negative: Y%, mentions: N},
"$60-70": {positive: X%, negative: Y%, mentions: N},
"$70 + MTX": {positive: X%, negative: Y%, mentions: N}
},
monetization_pain_points: [
{issue: "Premium + battle pass", severity: "CRITICAL", mentions: N},
{issue: "Loot boxes", severity: "HIGH", mentions: N}
],
value_propositions: [
{model: "F2P cosmetic-only", sentiment: X%, examples: []},
{model: "Budget indie ($15-25)", sentiment: X%, examples: []}
]
}
```
**2. Load Game Concepts**
Extract monetization-relevant data for each concept:
```javascript
GameConcept = {
name: string,
price_point: number | "F2P",
monetization_model: string,
target_audience: {
primary_persona: {},
market_size_estimate: number,
spending_behavior: string
},
competitors: [{name, price, model, performance}],
distribution_channels: [{platform, percentage, rationale}],
lifecycle_commitment: string,
development_cost_estimate: number
}
```
### Phase 2: Willingness-to-Pay Analysis
**3. Calculate WTP Score (0-100)**
```javascript
function calculateWTP(concept, marketData) {
const score = {
price_sentiment_alignment: 0, // Does price match positive sentiment tier?
value_perception: 0, // Content/$ ratio vs. market expectations
monetization_model_fit: 0, // Model aligns with audience preferences?
competitive_positioning: 0, // Price competitive advantage?
pain_point_avoidance: 0 // Avoids monetization red flags?
};
// Price Sentiment Alignment (0-30 points)
const priceТier = getPriceTier(concept.price_point);
const sentiment = marketData.price_sentiment[priceTier];
score.price_sentiment_alignment = (sentiment.positive / 100) * 30;
// Value Perception (0-25 points)
const contentHours = estimateContentHours(concept);
const pricePerHour = concept.price_point / contentHours;
const marketAvgPricePerHour = calculateMarketAverage();
if (pricePerHour < marketAvgPricePerHour * 0.8) {
score.value_perception = 25; // Excellent value
} else if (pricePerHour < marketAvgPricePerHour) {
score.value_perception = 18; // Good value
} else if (pricePerHour < marketAvgPricePerHour * 1.2) {
score.value_perception = 10; // Fair value
} else {
score.value_perception = 0; // Poor value
}
// Monetization Model Fit (0-20 points)
const modelSentiment = marketData.value_propositions.find(
vp => vp.model === concept.monetization_model
);
score.monetization_model_fit = (modelSentiment.sentiment / 100) * 20;
// Competitive Positioning (0-15 points)
const competitorPrices = concept.competitors.map(c => c.price);
const avgCompetitorPrice = average(competitorPrices);
if (concept.price_point < avgCompetitorPrice * 0.7) {
score.competitive_positioning = 15; // Undercut leaders
} else if (concept.price_point < avgCompetitorPrice) {
score.competitive_positioning = 10; // Competitive pricing
} else {
score.competitive_positioning = 5; // Premium positioning
}
// Pain Point Avoidance (0-10 points)
const painPoints = marketData.monetization_pain_points;
let violations = 0;
painPoints.forEach(pp => {
if (conceptViolatesPainPoint(concept, pp)) {
violations += (pp.severity === "CRITICAL") ? 5 : 2;
}
});
score.pain_point_avoidance = Math.max(0, 10 - violations);
return {
total: Object.values(score).reduce((a, b) => a + b, 0),
breakdown: score,
confidence: calculateConfidence(marketData.sample_size)
};
}
```
**WTP Score Interpretation:**
- **90-100**: Exceptional WTP, price optimization perfect
- **75-89**: Strong WTP, minor adjustments possible
- **60-74**: Moderate WTP, consider price/model changes
- **Below 60**: Weak WTP, major repositioning needed
### Phase 3: Viral Potential Analysis
**4. Calculate Viral Score (0-100)**
```javascript
function calculateViralPotential(concept, marketData) {
const score = {
shareability: 0, // Content naturally creates shareable moments?
accessibility: 0, // Low barrier to entry?
network_effects: 0, // Benefits from friend invites?
streamer_appeal: 0, // Twitch/YouTube friendly?
novelty_factor: 0, // Unique enough to generate buzz?
social_features: 0 // Built for social play/sharing?
};
// Shareability (0-20 points)
const shareableGenres = ["party game", "asymmetric", "sports hybrid", "roguelike"];
if (shareableGenres.some(g => concept.genre.includes(g))) {
score.shareability = 20;
} else if (concept.genre.includes("competitive") || concept.genre.includes("co-op")) {
score.shareability = 12;
} else {
score.shareability = 5; // Single-player, narrative
}
// Accessibility (0-20 points)
if (concept.price_point === "F2P") {
score.accessibility = 20; // Zero barrier
} else if (concept.price_point <= 15) {
score.accessibility = 15; // Impulse purchase
} else if (concept.price_point <= 25) {
score.accessibility = 10; // Reasonable
} else {
score.accessibility = 5; // Higher barrier
}
// Network Effects (0-20 points)
if (concept.monetization_model.includes("F2P") || concept.monetization_model.includes("viral")) {
score.network_effects = 20;
} else if (concept.description.includes("co-op") || concept.description.includes("multiplayer")) {
score.network_effects = 12;
} else {
score.network_effects = 0;
}
// Streamer Appeal (0-15 points)
const streamerFriendly = [
concept.genre.includes("asymmetric"),
concept.genre.includes("roguelike"),
concept.genre.includes("party"),
concept.description.includes("viral moments"),
concept.description.includes("spectator")
];
score.streamer_appeal = streamerFriendly.filter(Boolean).length * 3;
// Novelty Factor (0-15 points)
const noveltyIndicators = marketData.novelty_successes || [];
if (noveltyIndicators.some(n => concept.description.includes(n.innovation))) {
score.novelty_factor = 15;
} else if (concept.description.includes("unique") || concept.description.includes("first")) {
score.novelty_factor = 10;
} else {
score.novelty_factor = 5;
}
// Social Features (0-10 points)
const socialKeywords = ["co-op", "multiplayer", "friend", "clan", "team", "squad"];
const socialCount = socialKeywords.filter(kw =>
concept.description.toLowerCase().includes(kw)
).length;
score.social_features = Math.min(10, socialCount * 2);
return {
total: Object.values(score).reduce((a, b) => a + b, 0),
breakdown: score,
viral_coefficient: estimateViralCoefficient(score.total)
};
}
function estimateViralCoefficient(viralScore) {
// Viral coefficient: How many new users does each user bring?
// K > 1 = exponential growth, K < 1 = paid acquisition needed
if (viralScore >= 85) return 1.5; // Exceptional viral growth
if (viralScore >= 70) return 1.2; // Strong organic growth
if (viralScore >= 55) return 0.8; // Some viral mechanics
if (viralScore >= 40) return 0.4; // Minimal viral spread
return 0.2; // Requires paid marketing
}
```
**Viral Score Interpretation:**
- **85-100**: Viral hit potential (K > 1.2), minimal marketing spend
- **70-84**: Strong organic growth (K ~1.0), word-of-mouth driven
- **55-69**: Moderate virality (K ~0.8), some paid marketing needed
- **40-54**: Low virality (K ~0.4), heavy marketing investment required
- **Below 40**: No viral mechanics (K ~0.2), paid acquisition only
### Phase 4: Revenue Projection Modeling
**5. Calculate Revenue Potential (Year 1-3 Projections)**
```javascript
function projectRevenue(concept, wtpScore, viralScore, marketData) {
const model = concept.monetization_model;
// Addressable Market Size
const TAM = estimateTotalAddressableMarket(concept, marketData);
const SAM = TAM * 0.15; // Serviceable addressable (15% of TAM realistic)
const SOM = SAM * getMarketShareEstimate(viralScore, concept.competitors.length);
// Player Acquisition Model
const year1Players = calculateYear1Players(concept, viralScore, SOM);
const year2Players = year1Players * getRetentionMultiplier(concept.lifecycle_commitment);
const year3Players = year2Players * getGrowthMultiplier(viralScore);
// Revenue Calculations
if (model.includes("F2P")) {
return projectF2PRevenue(year1Players, year2Players, year3Players, concept);
} else if (model.includes("premium") || typeof concept.price_point === "number") {
return projectPremiumRevenue(year1Players, year2Players, year3Players, concept);
} else {
return projectHybridRevenue(year1Players, year2Players, year3Players, concept);
}
}
function projectF2PRevenue(y1Players, y2Players, y3Players, concept) {
// F2P Model: Base * Conversion Rate * ARPPU
const conversionRate = 0.03; // Industry avg: 3-5% pay
const ARPPU = estimateARPPU(concept); // Average revenue per paying user
const y1Revenue = y1Players * conversionRate * ARPPU;
const y2Revenue = y2Players * (conversionRate * 1.1) * (ARPPU * 1.15); // Improve over time
const y3Revenue = y3Players * (conversionRate * 1.15) * (ARPPU * 1.25);
return {
year1: {players: y1Players, revenue: y1Revenue, ARPU: y1Revenue / y1Players},
year2: {players: y2Players, revenue: y2Revenue, ARPU: y2Revenue / y2Players},
year3: {players: y3Players, revenue: y3Revenue, ARPU: y3Revenue / y3Players},
total_3yr: y1Revenue + y2Revenue + y3Revenue,
LTV: (y1Revenue + y2Revenue + y3Revenue) / y1Players
};
}
function projectPremiumRevenue(y1Players, y2Players, y3Players, concept) {
// Premium Model: Units Sold * Price + Optional DLC
const basePrice = concept.price_point;
const dlcAttachRate = 0.25; // 25% buy DLC
const avgDLCSpend = basePrice * 0.6; // DLC ~60% of base price
const y1Revenue = (y1Players * basePrice) + (y1Players * dlcAttachRate * avgDLCSpend * 0.5);
const y2Revenue = (y2Players * 0.3 * basePrice) + (y2Players * 0.3 * dlcAttachRate * avgDLCSpend);
const y3Revenue = (y3Players * 0.1 * basePrice) + (y3Players * 0.1 * dlcAttachRate * avgDLCSpend);
return {
year1: {players: y1Players, revenue: y1Revenue, ARPU: basePrice},
year2: {players: y2Players * 0.3, revenue: y2Revenue, ARPU: basePrice},
year3: {players: y3Players * 0.1, revenue: y3Revenue, ARPU: basePrice},
total_3yr: y1Revenue + y2Revenue + y3Revenue,
LTV: basePrice + (dlcAttachRate * avgDLCSpend)
};
}
function estimateARPPU(concept) {
// Average Revenue Per Paying User (F2P)
if (concept.genre.includes("competitive")) return 45; // Esports skin buyers spend more
if (concept.genre.includes("party")) return 20; // Casual spenders
Ver no GitHub