Profectus / features/trees/tree
features/trees/tree ​
This feature represents a tree of nodes, which can be used for skill trees, prestige trees, etc.
const tree = createTree(() => ({
nodes: [
[ aNode ],
[ bNode, cNode ]
],
branches: [
{ startNode: aNode, endNode: bNode },
{ startNode: aNode, endNode: cNode }
]
}));
One common use case for this would be including a node for each layer the player can navigate between, and clicking those nodes opens those layers. You can use the createLayerTreeNode
from within each layer to help with that. Just make that if the nodes themselves are already present on the other layer, when defining the tree you'll need to wrap them in noPersist
:
// In `prestige` layer:
const treeNode = createLayerTreeNode(() => ({
layerID: id,
color: "#4BDC13"
}));
// In the main layer:
const tree = createTree(() => ({
nodes: noPersist([
[ prestige.treeNode ]
])
}));
Trees can also handle propagating resets. That is, when certain parts of the game state should reset, and which precise parts are determined by the nodes in the tree. For this to work, you need to include a reset object in each node that represents what content that node controls, and then pick a propagation strategy. The basic ones are to reset everything above or below a certain row, or follow the (directional) branches of the tree:
const treeNode = createLayerTreeNode(() => ({
layerID: id,
color: "#4BDC13",
reset: createReset(() => ({
thingsToReset: (): Record<string, unknown>[] => [layer]
}))
}));
const tree = createTree(() => ({
nodes: noPersist([
[ prestige.treeNode ]
[ generators.treeNode, boosters.treeNode ]
]),
branches: noPersist([
{ startNode: prestige.treeNode, endNode: generators.treeNode },
{ startNode: prestige.treeNode, endNode: boosters.treeNode }
]),
resetPropagation: defaultResetPropagation
}));
You can use the onReset field to reset anything that should always be reset and isn't tied to any specific node. For a game like "The Prestige Tree", this is where you'd reset the "points" currency on the main tab.
const points = createResource<DecimalSource>(0);
const tree = createTree(() => ({
...,
onReset() {
points.value = 10;
}
}));