《独立开发者的商业指南·资本与退出》13.2 商业健康度评分

指标矩阵回答「有什么」,健康度评分回答「这副身体怎么样」。本节把盈利、增长、现金、结构、可转移性与治理六个维度各赋权重,用同一套 0–100 分制给三个案例打分:LedgerLite 72、Tidecast 58、Nord 48。分数不是评级,而是排序依据;最弱维度往往就是下一笔交易里最先被问住的地方。

以下情境为教学假设,人物与数字不代表经核实的真实案例。

上一节把 16 项指标放进同一张矩阵,回答了「这门生意有什么」。这一节回答另一个问题:把这些指标合起来看,这副身体到底怎么样。

「怎么样」不能靠感觉。感觉会说「增长不错」「利润还行」「客户挺满意」,但说不清哪一项拖了后腿。评分的作用,是强迫你把六个维度各自打一个分,再按权重合成一个总数;合成之后,最弱的那一维会自己浮出来。

六个维度与权重

健康度分六维,每维 0 到 100 分,权重合计 100%。

盈利质量(20%)。看毛利率、SDE 利润率、收入是否含一次性项目。生意首先要能赚钱,否则后面五个维度都是空谈。

增长与留存(15%)。看收入增速、月流失、净收入留存。没有增长,估值只能按资产算;流失太高,增长会被抵消。

现金与韧性(20%)。看现金储备、应收周转、最坏情况下的现金缺口。利润是账面数字,现金才是能撑多久的数字。

收入结构(15%)。看客户集中度、经常性收入占比、平台或渠道依赖。结构决定风险,不决定大小。

可转移性(15%)。看创始人依赖、文档、合同可转让性、代码与账号归属。这一维直接决定生意能不能卖。

治理与合规(15%)。看主体结构、税务、保险、书面协议。治理不是形式,它是交易时尽调的第一站。

权重不是行业标准,是本书的教学设定。盈利与现金各占 20%,因为它们是生存项;其余四维各占 15%,因为它们是交易项。你可以改权重,但要先想清楚:权重一改,排序就可能变;排序变了,结论也跟着变。

三个案例的评分

按六个维度给三个案例打分,得到下面这张表。分数是 0 到 100 的整数,依据是前面各章算过的数字。

维度权重LedgerLiteTidecastNord Studio
盈利质量20%806555
增长与留存15%705045
现金与韧性20%857060
收入结构15%754035
可转移性15%558030
治理与合规15%603555
加权总分100%725848

分数的来源可以逐项追。

LedgerLite 的盈利质量 80,因为毛利 84.2%、SDE 利润率 54.2%;增长与留存 70,因为月流失 1.5% 但增速未知;现金与韧性 85,因为现金 95,000 美元、应收只有 18 天;收入结构 75,因为经常性收入 100%,但前五大客户占 31%;可转移性 55,因为创始人在一线、离开后客户关系会松动;治理 60,因为主体与合同清楚,但期权池与董事会安排还没落地。

Tidecast 的盈利质量 65,因为 SDE 利润率 63.1% 但收入是买断制、没有续费;增长与留存 50,因为新作发布决定收入、老作自然衰减;现金与韧性 70,因为平台月结、没有应收但也没有预收;收入结构 40,因为 Steam 占 80%;可转移性 80,因为代码、美术、音乐授权都能列清单;治理 35,因为没有雇员、没有正式主体安排、账号归属依赖个人。

Nord 的盈利质量 55,因为 SDE 利润率只有 22.2%;增长与留存 45,因为项目制收入逐年重谈;现金与韧性 60,因为应收 11,264 美元、逾期 8%;收入结构 35,因为前 3 家客户占 48%;可转移性 30,因为客户关系在两位合伙人手里;治理 55,因为有合伙协议雏形,但没有买断与继承条款。

把这些分数按权重合成:LedgerLite 72、Tidecast 58、Nord 48。

分数的含义与边界

72 分是 B,58 分是 C,48 分是 D。评级只是标签,真正有用的是两件事:总分排序与最弱维度。

总分排序回答「谁更健康」。LedgerLite 领先 Tidecast 14 分,领先 Nord 24 分;差距主要来自收入结构与可转移性,而不是盈利能力。Tidecast 的盈利质量只比 LedgerLite 低 15 分,但收入结构低 35 分——平台依赖把它的总分拉了下来。

最弱维度回答「先修哪里」。LedgerLite 最弱是可转移性 55,Tidecast 最弱是治理 35,Nord 最弱是可转移性 30。三个案例中有两个的最弱项是同一维,这不是巧合:独立开发者的生意,最难转移的往往就是人本身。

分数也有边界。

第一,权重是教学设定,换一套权重会改变总分;本书用「盈利与现金各 20%」,是因为这两个维度决定生意能不能活到交易那天。

第二,分数依赖输入。输入来自前面各章的计算,如果某一章的口径改了,分数要重算;不要拿三个月前的分数当现在的结论。

第三,分数不预测价格。健康度高的生意不一定卖得贵,估值还取决于买方类型、市场时机与交易结构;健康度只回答「这副身体能不能上手术台」。

与附录 C 的分工

附录 C 也有一张 46 项、92 分的评分表。两张表容易混,分工要说清。

健康度评分(本节)评的是「生意本身」:赚不赚钱、增长快不快、现金够不够、结构稳不稳、能不能交出去、治理清不清楚。它不需要有买方,也不需要准备任何交易材料。

交易准备度评分(附录 C)评的是「交易准备」:融资材料齐不齐、估值桥算没算、尽调能不能自查、交割清单有没有、托管与赔偿谈没谈。它假设交易正在发生。

两者的关系是:健康度决定「值不值得买」,准备度决定「能不能顺利买」。一门健康度 48 分的生意,即使准备度 90 分,也只是「准备得很充分的差生意」;反过来,健康度 85 分、准备度 40 分,则是「好生意但还没准备好卖」。

第 13.3 节会把两个分数放在同一张坐标图上,给出每个案例的下一步。

代码:把评分写成函数

下面的 health-score.ts 把六个维度、权重与三个案例写成数据,scoreCase 返回加权总分、评级与最弱维度。

// file: src/capital/health-score.ts
// tier: L1
// verify: node --test test/capital/health-score.test.ts

export interface Dimension {
  id: string;
  label: string;
  weightBps: number;
}

export interface CaseHealth {
  name: string;
  scores: Record<string, number>;
}

export interface HealthResult {
  name: string;
  total: number;
  grade: "A" | "B" | "C" | "D";
  weakest: Dimension;
  weighted: Array<{ id: string; label: string; contribution: number }>;
}

export const DIMENSIONS: Dimension[] = [
  { id: "profit", label: "盈利质量", weightBps: 2_000 },
  { id: "growth", label: "增长与留存", weightBps: 1_500 },
  { id: "cash", label: "现金与韧性", weightBps: 2_000 },
  { id: "structure", label: "收入结构", weightBps: 1_500 },
  { id: "transfer", label: "可转移性", weightBps: 1_500 },
  { id: "governance", label: "治理与合规", weightBps: 1_500 },
];

export const CASES: CaseHealth[] = [
  {
    name: "LedgerLite",
    scores: { profit: 80, growth: 70, cash: 85, structure: 75, transfer: 55, governance: 60 },
  },
  {
    name: "Tidecast",
    scores: { profit: 65, growth: 50, cash: 70, structure: 40, transfer: 80, governance: 35 },
  },
  {
    name: "Nord Studio",
    scores: { profit: 55, growth: 45, cash: 60, structure: 35, transfer: 30, governance: 55 },
  },
];

function assertScore(value: number): void {
  if (!Number.isFinite(value) || value < 0 || value > 100) {
    throw new Error(`score out of range: ${value}`);
  }
}

export function totalWeightBps(dimensions: Dimension[] = DIMENSIONS): number {
  return dimensions.reduce((sum, item) => sum + item.weightBps, 0);
}

export function gradeOf(total: number): "A" | "B" | "C" | "D" {
  if (total >= 80) return "A";
  if (total >= 65) return "B";
  if (total >= 50) return "C";
  return "D";
}

export function scoreCase(item: CaseHealth, dimensions: Dimension[] = DIMENSIONS): HealthResult {
  if (totalWeightBps(dimensions) !== 10_000) {
    throw new Error("weights must sum to 10000 basis points");
  }
  const weighted = dimensions.map((dimension) => {
    const score = item.scores[dimension.id];
    if (score === undefined) throw new Error(`missing score for ${dimension.id}`);
    assertScore(score);
    return {
      id: dimension.id,
      label: dimension.label,
      contribution: (score * dimension.weightBps) / 10_000,
    };
  });
  const total = Math.round(weighted.reduce((sum, part) => sum + part.contribution, 0));
  let weakest = dimensions[0];
  for (const dimension of dimensions) {
    if (item.scores[dimension.id] < item.scores[weakest.id]) weakest = dimension;
  }
  return { name: item.name, total, grade: gradeOf(total), weakest, weighted };
}

export function rankCases(cases: CaseHealth[] = CASES): HealthResult[] {
  return cases.map((item) => scoreCase(item)).sort((a, b) => b.total - a.total);
}

export function scoreAll(cases: CaseHealth[] = CASES): Array<{ name: string; total: number }> {
  return cases.map((item) => {
    const result = scoreCase(item);
    return { name: result.name, total: result.total };
  });
}

代码里有三个值得说明的选择。

第一,权重用基点(weightBps)而不是小数。2,000 表示 20%,总和必须是 10,000;scoreCase 会检查这一点,权重配错时直接抛错,不会悄悄算出一个错误总分。

第二,分数用 0 到 100 的整数,加权贡献保留小数。LedgerLite 的贡献是 16 + 10.5 + 17 + 11.25 + 8.25 + 9 = 72.0,Tidecast 是 57.75,四舍五入后 58。先加后舍入,避免每项都舍入造成的累积误差。

第三,weakest 用严格小于比较,遇到并列时取靠前的维度。并列不是错误,但要让规则明确,否则同一份数据两次运行可能给出不同的最弱项。

测试会覆盖三案例的总分、评级、最弱维度,以及权重不等于 10,000、分数越界、维度缺失这三种错误输入。

分数怎么用于决策

评分不是终点,是排序工具。

第一步,看总分落在哪一档。80 分以上(A)说明生意健康,可以考虑融资或出售;65 到 79 分(B)说明基本健康,但有明显短板;50 到 64 分(C)说明短板已经影响交易;50 分以下(D)说明先治病,别急着上手术台。

第二步,看最弱维度。总分相同,最弱维度不同,下一步动作也不同:最弱是可转移性,就先写文档、转客户关系、理清合同;最弱是治理,就先补协议、主体与保险;最弱是收入结构,就先降集中度、增加经常性收入。

第三步,看维度之间的差距。如果某一维比其余五维低 30 分以上,它就不是「短板」,而是「结构性缺陷」,需要单独处理,不能靠其他维度的高分弥补。

第四步,隔三个月重算一次。分数变化的方向比绝对值更重要:可转移性从 30 升到 50,说明交接在推进;收入结构从 75 降到 60,说明集中度在恶化。

一次评分的完整记录

评分要留下记录,否则三个月后无法比较。一份最小记录包含五栏:

字段示例
评分日期2026-11-05
数据截止2026-10-31
权重版本v1(20/15/20/15/15/15)
六维分数与依据盈利 80(毛利 84.2%、SDE 利润率 54.2%)
最弱维与下一步可转移性 55,先写运维文档

记录的价值在可比性。权重版本不写,下一次换了权重就无法解释分数变化;数据截止不写,会把跨期数据混在一起;依据不写,分数就退回成感觉。

小结

健康度评分把六个维度合成一个数,但它的价值不在那个数,而在分解。

LedgerLite 72 分、Tidecast 58 分、Nord 48 分,排序说明前者最健康;但真正有用的是最弱维度:LedgerLite 卡在可转移性,Tidecast 卡在治理,Nord 卡在可转移性。三个案例中两个的最弱项相同,说明「人」是独立开发者生意里最难交出去的部分。

评分与附录 C 的交易准备度是两把不同的尺子:一个量身体,一个量手术准备。下一节把两把尺子放在一起,给出每个案例的下一步路径。

阅读导航:上一节:13.1 三卷指标矩阵 · 下一节:13.3 全书评审与后续路径 。

常见错误与边界

  1. 把总分当评级。 72 分和 58 分只说明排序,不说明「好」或「坏」;不同行业的权重本来就不同。
  2. 权重随手改。 改权重会改排序,改排序会改结论;要改就写清理由,并重算三个案例。
  3. 只看总分,不看最弱维。 总分相同的两门生意,下一步动作可能完全相反。
  4. 用健康度预测价格。 健康度回答「能不能上手术台」,价格还取决于买方、时机与结构。
  5. 把分数当一次性的。 分数随业务变化,至少每季度重算一次。
  6. 与附录 C 混用。 健康度评生意,准备度评交易;两张表不能相加,也不能互相替代。

本节的边界是「健康度建模」:六维、权重、分数都是教学设定,依据是本书三个案例的数字;它不构成对任何真实企业的评级,也不预测交易结果。真实使用时,应替换为读者自己的指标与权重,并保留每次评分的记录。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「books」更多文章

  1. 《移动游戏产品的架构·商业化与发行工程》附录 C 商业化与发行评审清单
  2. 《移动游戏产品的架构·商业化与发行工程》附录 B 双案例商业化事实表
  3. 《移动游戏产品的架构·商业化与发行工程》附录 A 商业化与发行术语速查