feat(bt)!: Remove legacy tree definition format

The `LegacyTreeDef` type and its normalization path have been removed.
All tree definitions must now use the factory functions (`leaf`,
`sequential`, `parallel`, `selector`, `random`, `repeat`). The
`TreeDef` type is now simply `TaskEntityDef`.
This commit is contained in:
hyper
2026-06-28 10:19:40 +08:00
parent ddde3f7597
commit 1253bf82d2
5 changed files with 133 additions and 180 deletions
+35 -42
View File
@@ -23,7 +23,13 @@
// npx tsx examples/blackjack/main.ts
import { World } from "../../src/index";
import { buildTree } from "../../src/bt/index";
import {
buildTree,
leaf,
parallel,
repeat,
sequential,
} from "../../src/bt/index";
import { CommandQueue } from "../../src/commands/index";
import {
@@ -63,50 +69,37 @@ const commands = new CommandQueue(world);
registerCommands(world, commands, cards);
// ── Behaviour Tree ───────────────────────────────────
const runner = buildTree(world, {
kind: "parallel",
children: [
{
kind: "leaf",
*run() {
while (true) {
const dt: number = yield;
const phase = world.getSingleton(GamePhase);
if (phase.phase !== "dealerTurn") continue;
const runner = buildTree(
world,
parallel([
leaf(function* dealerPlay() {
while (true) {
yield;
const phase = world.getSingleton(GamePhase);
if (phase.phase !== "dealerTurn") continue;
if (dealerShouldHit(cards.getHand(InDealerHand))) {
const cardEntity = cards.drawCard();
if (cardEntity) {
cards.dealTo(cardEntity, InDealerHand);
}
} else {
resolveRound(world, cards);
if (dealerShouldHit(cards.getHand(InDealerHand))) {
const cardEntity = cards.drawCard();
if (cardEntity) {
cards.dealTo(cardEntity, InDealerHand);
}
} else {
resolveRound(world, cards);
}
},
},
{
kind: "repeat",
child: {
kind: "sequential",
children: [
{
kind: "leaf",
run: () => {
commands.execute();
},
},
{
kind: "leaf",
run: () => {
render(world, ui);
},
},
],
},
},
],
});
}
}),
repeat(
sequential([
leaf(() => {
commands.execute();
}),
leaf(() => {
render(world, ui);
}),
]),
),
]),
);
// ── Input → Command mapping ──────────────────────────
const keyToCommand: Partial<Record<Key, typeof Hit>> = {