Do theatrical adaptations of stage musicals make money?
A practical introduction to using comparable past cases when evaluating a new proposal—and to keeping the resulting evidence honest, inspectable, and useful.
What Flyvbjerg adds
A spreadsheet can calculate a median. The harder problem is deciding which historical cases belong in the comparison, finding the same measurement for each case, preserving disagreements and missing values, and showing which conclusions change when reasonable assumptions change.
A disciplined comparison
Define what counts as comparable before looking at success or failure. This prevents a memorable hit, notorious failure, or convenient data source from quietly determining the sample.
Evidence with a memory
Keep the source, candidate value, review decision, missing-data state, and metric definition attached to every case. A later correction does not erase what was previously believed.
An honest outside view
Summarize the full historical distribution rather than selecting a flattering average. Preserve ranges, skew, downside frequency, and dependence among related cases.
Conclusions that can be challenged
Compare reasonable analytical choices and identify exactly which cases switch classifications. Decision-makers can see what is robust and what depends on an assumption.
This tutorial follows one question from beginning to end: if a producer is considering another film adaptation of a stage musical, what should the history of similar films contribute to the greenlight decision?
1Why use an outside view?
Imagine a producer considering a film version of a successful stage musical. The proposal may emphasize a known title, proven songs, awards, stars, and an existing audience. Those details matter—but almost every proposal has a persuasive story about why this case is special.
An outside view begins elsewhere. It identifies past projects that faced the same basic decision, records what happened across the whole group, and asks where the new proposal sits in that distribution. It does not replace project-specific judgment. It supplies a historical baseline that the project-specific story must explain and, when appropriate, overcome.
Here, one comparable case is one film adaptation. The common outcome is worldwide theatrical gross relative to reported production budget. That measurement is available for many films and reveals downside and upside—but it is not the same thing as studio profit. A useful system should help maintain that distinction rather than bury it.
What the package does: it gives a coding agent a structured place to assemble comparable cases, record evidence, make review decisions, preserve unknowns, freeze a historical distribution, and test whether the decision changes under reasonable alternative assumptions.
2Describe the decision before gathering evidence
Start by telling Flyvbjerg what decision the historical evidence is meant to inform. This keeps the research anchored to a real choice rather than becoming a collection of interesting film facts.
mkdir theatrical-musicals
cd theatrical-musicals
flyvbjerg init
cat > target.json <<'JSON'
{
"decision": "What base-rate range and downside allowance should a producer or financier use for a new theatrically released stage-musical adaptation?",
"thresholds_gross_multiple": [1.0, 2.0, 2.5],
"unknown": [
"production budget range",
"marketing spend",
"distributor and exhibitor shares",
"ancillary revenue",
"participations",
"release strategy",
"pandemic effects"
]
}
JSON
flyvbjerg target create theatrical_musical \
--name "Theatrical musical adaptation economics" \
--from target.json
flyvbjerg collection new theatrical_musicals \
"US theatrical stage-musical film adaptations, 2006–2025 seed cohort"
flyvbjerg next
target.json is created in the command block; it is not supplied by Flyvbjerg. The CLI combines its decision context with the stable target ID and display name given on the command line.
See what the target command creates
{
"target_id": "theatrical_musical",
"name": "Theatrical musical adaptation economics",
"version": 1,
"decision": "What base-rate range and downside allowance should a producer or financier use for a new theatrically released stage-musical adaptation?",
"thresholds_gross_multiple": [1.0, 2.0, 2.5],
"unknown": ["production budget range", "marketing spend", "... five more"]
}Show representative next step
{
"command": "flyvbjerg next",
"status": "ok",
"data": {"target_count": 1, "collection_count": 1, "unresolved_intake_count": 0},
"next_steps": [{
"id": "register_evidence",
"command": "flyvbjerg source add theatrical_musicals --url URL"
}]
}The target records the proposed decision and its unresolved questions. The collection is the working set of historical evidence. At this point it is exploratory: calling a group “comparable” does not yet make it defensible.
3Decide what counts as comparable
Include English-language feature films directly adapted from a previously produced stage musical, released theatrically in the United States from 2006 through 2025 by an established distributor. Exclude original screen musicals, animation, concert and television films, streaming-first releases, and sequels that do not directly adapt the stage work.
Included
Hairspray, Les Misérables, Cats, In the Heights, Wicked, and other films satisfying stage provenance and release rules.
Excluded
La La Land is an original screen musical. Mamma Mia! Here We Go Again is a sequel rather than a direct adaptation of the stage book.
Keep a record of every title considered, including exclusions. Here we considered 20 candidates before collecting financial results: 18 qualified and two did not. La La Land remains in the audit trail with the reason it was excluded; it does not simply disappear. Notice that the excluded record needs no budget or box-office result—the decision is based only on whether the film fits the definition.
flyvbjerg intake add theatrical_musicals wiki_la_la_land \
membership_candidate \
"Original screen musical rather than an adaptation" \
--proposed-name "La La Land"
See the generated intake identifier
{
"item_id": "item_7b8f...",
"kind": "membership_candidate",
"proposed_names": ["La La Land"],
"status": "untriaged"
}Copy the returned item_id into the decision command. In the command below, item_7b8f... means the identifier emitted immediately above:
flyvbjerg intake defer theatrical_musicals item_7b8f... \
--reason original_screen_musical
flyvbjerg next
4Find the comparable cases and their histories
A coding agent searches and reads Wikipedia film histories using its research tools. Flyvbjerg is the evidence ledger, not the researcher: it does not follow URLs or silently convert whatever a search happens to return into data.
| Agent action | Flyvbjerg action |
|---|---|
| Find candidate adaptations | None |
| Check stage provenance and US theatrical release | Store a case identity |
| Read budget bounds and worldwide gross | Store candidates linked to the source |
| Find conflict or omission | Keep unresolved or record an absence state |
| Calculate gross multiples | Preserve candidates and evidence decisions |
Wikipedia is good best-available evidence for this first pass. A high-stakes investment should verify contested financial values with studio records, trade reporting, and commercial box-office data.
5Record where every fact came from
flyvbjerg source add theatrical_musicals \
--url "https://en.wikipedia.org/wiki/Mamma_Mia!_(film)" \
--title "Mamma Mia! — Wikipedia" \
--kind encyclopedia --source-id wiki_mamma_mia
flyvbjerg source add theatrical_musicals \
--url "https://en.wikipedia.org/wiki/Cats_(2019_film)" \
--title "Cats — Wikipedia" \
--kind encyclopedia --source-id wiki_cats
Show one source identity
{
"source_id": "wiki_mamma_mia",
"url": "https://en.wikipedia.org/wiki/Mamma_Mia!_(film)",
"title": "Mamma Mia! — Wikipedia",
"kind": "encyclopedia",
"retrieved": "2026-08-14T02:36:45Z"
}These are two examples, not the entire source set. Each of the 20 rows in cohort.json contains the exact Wikipedia URL used for that candidate; the rebuild registers all 20 using this command.
flyvbjerg capture add can hash and preserve it. Flyvbjerg still never downloads it.6Give every historical case a stable identity
flyvbjerg case add theatrical_musicals \
--id mamma_mia --name "Mamma Mia!" --type theatrical_film
flyvbjerg case add theatrical_musicals \
--id cats --name "Cats" --type theatrical_film
flyvbjerg case add theatrical_musicals \
--id wicked --name "Wicked" --type theatrical_film
The seed has 18 film cases, from Dreamgirls through Wicked. Identity is separate from measurement: a later source correction updates evidence attached to a film, not the film itself.
7Use the same measurements across cases
Five versioned metrics preserve reported ranges instead of inventing midpoints:
budget_low_musdLower production-budget bound, nominal $m.
budget_high_musdUpper production-budget bound, nominal $m.
worldwide_gross_musdReported worldwide theatrical gross, nominal $m.
gross_multiple_lowConservative multiple: gross ÷ high budget.
gross_multiple_highOptimistic multiple: gross ÷ low budget.
Construct all five definitions directly. Nothing in this block depends on a pre-existing file:
flyvbjerg metric add theatrical_musicals budget_low_musd \
--kind numeric --role input --unit million_usd --subject-kind case \
--label "Reported production budget lower bound" \
--definition "Lower reported production-budget bound, nominal USD millions." \
--zero-policy "Missing or malformed budget data remain missing and are never zero."
flyvbjerg metric add theatrical_musicals budget_high_musd \
--kind numeric --role input --unit million_usd --subject-kind case \
--label "Reported production budget upper bound" \
--definition "Upper reported production-budget bound, nominal USD millions." \
--zero-policy "Missing or malformed budget data remain missing and are never zero."
flyvbjerg metric add theatrical_musicals worldwide_gross_musd \
--kind numeric --role outcome --unit million_usd --subject-kind case \
--label "Worldwide theatrical box-office gross" \
--definition "Reported worldwide theatrical gross, nominal USD millions." \
--zero-policy "Missing or malformed box-office data remain missing and are never zero."
flyvbjerg metric add theatrical_musicals gross_multiple_low \
--kind ratio --role outcome --unit x --subject-kind case \
--label "Conservative worldwide gross multiple" \
--definition "Worldwide gross divided by the upper production-budget bound." \
--zero-policy "Missing inputs remain missing; a failed calculation is never zero."
flyvbjerg metric add theatrical_musicals gross_multiple_high \
--kind ratio --role outcome --unit x --subject-kind case \
--label "Optimistic worldwide gross multiple" \
--definition "Worldwide gross divided by the lower production-budget bound." \
--zero-policy "Missing inputs remain missing; a failed calculation is never zero."
flyvbjerg next
8Record possible values without treating them as truth
Cats has an $80–100m reported budget and $75.5m worldwide gross. Store the range and both resulting multiples:
flyvbjerg observation add theatrical_musicals \
--subject-kind case --subject cats --metric budget_low_musd \
--value 80 --source wiki_cats --period 2019 --method reported
flyvbjerg observation add theatrical_musicals \
--subject-kind case --subject cats --metric budget_high_musd \
--value 100 --source wiki_cats --period 2019 --method reported
flyvbjerg observation add theatrical_musicals \
--subject-kind case --subject cats --metric worldwide_gross_musd \
--value 75.5 --source wiki_cats --period 2019 --method reported
flyvbjerg observation add theatrical_musicals \
--subject-kind case --subject cats --metric gross_multiple_low \
--value 0.755 --source wiki_cats --period 2019 --method calculated
flyvbjerg observation add theatrical_musicals \
--subject-kind case --subject cats --metric gross_multiple_high \
--value 0.9437 --source wiki_cats --period 2019 --method calculated
See how an observation ID is created
{
"observation_id": "obs_cats_multiple_low...",
"subject": {"kind": "case", "id": "cats"},
"metric": {"id": "gross_multiple_low", "version": 1},
"value": 0.755,
"method": "calculated",
"status": "candidate"
}All five remain candidates. Deterministic arithmetic can still use the wrong source, units, bound, or formula. Cats demonstrates the complete five-observation pattern. The canonical cohort input exposes the three reported financial fields for every included film; the rebuild calculates both bounds and submits the same five commands for all 18 films, producing the 90 observations used below.
9Review the evidence explicitly
Each observation add response contains an observation_id. Use that returned value—not a name guessed from the film or metric—in the review command:
flyvbjerg observation decide theatrical_musicals obs_reported_value... \
--accept \
--reason "Reported field supported by the registered page; range bounds preserved separately."
flyvbjerg observation decide theatrical_musicals obs_cats_multiple_low... \
--accept \
--reason "Inspected calculation from reported gross and the upper budget bound."
Show representative decision
{
"subject_kind": "observation",
"subject_id": "obs_...",
"decision": "accepted",
"reason": "Inspected calculation from reported gross and the upper budget bound."
}The workspace has 90 observations—five per film—and an explicit review decision for each. A rejection would preserve the candidate and its exclusion reason.
10Preserve what is missing or unknown
flyvbjerg coverage set theatrical_musicals \
--subject-kind case --subject cats --metric gross_multiple_low \
--state observed \
--reason "Accepted multiple with complete reported inputs."
All 18 seed films have observed ratio bounds. That does not prove every eligible film would. An expanded enumeration may produce not_found, conflicted, or other explicit absence states.
11Turn the accepted history into an outside view
flyvbjerg analysis create theatrical_musicals \
--name "Conservative worldwide gross multiple" \
--metric gross_multiple_low \
--target theatrical_musical --target-version 1
flyvbjerg analysis create theatrical_musicals \
--name "Optimistic worldwide gross multiple" \
--metric gross_multiple_high \
--target theatrical_musical --target-version 1
Show the locked distribution
{
"analysis_id": "analysis_bca59aad72a74ac3",
"n_subjects": 18,
"dependence_status": "not_assessed",
"n_clusters": null,
"distribution": {
"min": 0.2133,
"median": 1.45435,
"max": 13.5846,
"mean": 2.7269,
"quantiles": {"0.25": 0.755, "0.5": 1.1536, "0.75": 3.068},
"quantile_convention": "nearest_rank"
}
}See the second generated analysis identifier
{
"analysis_id": "analysis_02e3bebcf0b44753",
"name": "Optimistic worldwide gross multiple",
"n_subjects": 18,
"distribution": {"median": 1.881, "mean": 2.7995}
}These two returned IDs identify immutable snapshots. Later threshold, plot, and comparison commands refer to those exact snapshots.
The 2.73x mean is pulled upward by Mamma Mia! at 13.58x. The conventional median and nearest-rank P50 are both visible; neither is silently substituted for the other.
12Stress-test the decision conclusion
Below 1.0x is a strong theatrical downside signal. From 1.0x to under 2.5x is economically indeterminate. At least 2.5x is a strong theatrical-recovery proxy—not audited profit.
flyvbjerg threshold analysis_bca59aad72a74ac3 \
--operator lt --value 1.0
flyvbjerg threshold analysis_bca59aad72a74ac3 \
--operator ge --value 2.5
flyvbjerg locate analysis_bca59aad72a74ac3 \
--value 2.5 --label "Strong theatrical-recovery proxy"
| Zone | Observed films | Meaning |
|---|---|---|
| Below 1.0x | 8/18 (44.4%) | Gross did not match production budget. |
| 1.0x–2.5x | 3/18 (16.7%) | Profit unresolved by common fields. |
| At least 2.5x | 7/18 (38.9%) | Strong theatrical recovery proxy. |
At a looser 2.0x boundary, budget ranges move the count from 7/18 to 9/18. At 1.0x and 2.5x, the classifications are unchanged by budget uncertainty.
Make that sensitivity auditable
Create separate frozen analyses for the conservative and optimistic bounds, then compare them. The comparison never rewrites either analysis.
flyvbjerg comparison create theatrical_musicals \
--name "Production-budget bound sensitivity" \
--analysis analysis_bca59aad72a74ac3 \
--analysis analysis_02e3bebcf0b44753
See the generated comparison identifier
{
"comparison_id": "comparison_f2eceafbb79647db",
"analysis_ids": [
"analysis_bca59aad72a74ac3",
"analysis_02e3bebcf0b44753"
],
"subject_sets_equal": true,
"targets_equal": true,
"metrics_equal": false
}Use the returned comparison_id for both sensitivity calculations and the plot:
flyvbjerg comparison threshold comparison_f2eceafbb79647db \
--operator ge --value 2.0 --value 2.5
flyvbjerg comparison plot comparison_f2eceafbb79647db \
--output plots/budget-bound-comparison.svg
flyvbjerg next
| Threshold | Conservative | Optimistic | Package conclusion |
|---|---|---|---|
| At least 2.0x | 7/18 | 9/18 | Assumption-sensitive: Annie and Dreamgirls switch. |
| At least 2.5x | 7/18 | 7/18 | Robust across budget bounds. |
The comparison receipt also states that both analyses use the same 18 subjects, target version, and quantile convention; the metric IDs differ because they encode opposite budget bounds. This is the distinction a decision-maker needs: the 2.5x conclusion survives the reported budget uncertainty, while the 2.0x conclusion does not.
13See the full distribution—not just an average
flyvbjerg plot analysis_bca59aad72a74ac3 \
--kind ordered --threshold 2.5 \
--output plots/conservative-multiple-ordered.svg
flyvbjerg plot analysis_bca59aad72a74ac3 \
--kind ecdf --threshold 2.5 \
--output plots/conservative-multiple-ecdf.svg
The chart exposes the barbell: eight cases below 1.0x and a long upper tail reaching 13.58x. Each SVG has a JSON receipt recording the analysis ID, parameters, timestamp, and content hash.
14Reproduce and audit the work
The analytical story above is the user-facing result. Underneath it, Flyvbjerg preserves enough structure to answer practical challenges: Which source supported this value? Was it reviewed? Which films were excluded, and why? Did a corrected budget change the conclusion?
The checked-in cohort.json is the canonical input for this worked example. A maintainer or skeptical reviewer can reconstruct the entire workspace from the root of a Flyvbjerg repository checkout. This is a separate location from the temporary theatrical-musicals workspace created in chapter 2:
cd /path/to/flyvbjerg
python simulations/theatrical-musicals/rebuild.py \
/tmp/theatrical-musicals-audit
The rebuild performs no browsing or paid model execution. It replays the public Flyvbjerg commands, checks the workflow after each material stage, validates the resulting ledger, and regenerates the comparison artifacts.
flyvbjerg validate
flyvbjerg next
Show validation result
{
"command": "flyvbjerg validate",
"status": "ok",
"data": {"valid": true, "json_records": 362}
}15Use the outside view in the actual decision
| Analytical danger | Design response |
|---|---|
| Remembering only hits and notorious bombs | Freeze membership from provenance and release facts. |
| Calling box-office gross studio profit | Name the proxy and use transparent thresholds. |
| Choosing a favorable budget midpoint | Preserve both bounds and analyze both. |
| Letting blockbusters define the typical case | Show ordered values, medians, and empirical quantiles. |
| Deleting pandemic films after weak outcomes | Retain eligible cases; show release period as sensitivity. |
| Interpreting absent data as failure | Use coverage states; missing is never zero. |
| Calling a seed list a population base rate | Carry the enumeration limitation into the decision. |
A greenlight model should add distributor rentals, marketing, financing, participations, ancillary revenue, and cash-flow timing. The historical distribution challenges an inside-view forecast; it does not provide audited probabilities of net profit.