Skip to content

Commit bf09675

Browse files
committed
add maths and guides
1 parent ed5ab50 commit bf09675

22 files changed

+3145
-16
lines changed

AGENTS.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ This file applies only to agents working in the `bebe/` repository.
44

55
## Repo Contract
66

7-
- `bebe` is the standalone framework repo for the `@blurengine/bebe` package, its source, tests, docs, and release surface.
8-
- The initial public surface is context-first. Do not widen exports without updating tests, package metadata, and README together.
7+
- `bebe` is the standalone game engine library repo for the `@blurengine/bebe` package, its source, tests, docs, and release surface.
8+
- The package root stays context-first. Additional public subpaths must be introduced intentionally and updated together with tests, package metadata, and README.
9+
- Use [docs/guides/engine-philosophy.md](d:/Users/supah/Documents/programming/go/src/gitlab.com/Blockception/personal/bebe/docs/guides/engine-philosophy.md) as the north-star design guide when evaluating new features, API shape, and architectural tradeoffs.
910
- This file is for authoring `bebe` itself.
1011

1112
## Maintenance Rules
@@ -24,3 +25,17 @@ This file applies only to agents working in the `bebe/` repository.
2425
4. Treat `Context` as lifecycle and resource ownership infrastructure, not a dumping ground for unrelated feature state. New responsibilities should usually become services or standalone primitives before they become `Context` features.
2526
5. If Bedrock is missing an API and `bebe` fills the gap through polling or derived state, design that solution so consumers can reuse the same primitive to build their own higher-level features.
2627
6. When naming similar capabilities, prefer one vocabulary and one implementation path. Avoid sibling APIs that solve the same problem with slightly different names or behavior.
28+
7. In maths APIs, prefer the class types (`Vec2`, `Vec3`, `AABB`) as the primary authored surface. Keep raw structural helpers only for Bedrock interop, scalar queries, and low-allocation edge work; do not mirror the full class algebra in util helpers.
29+
8. Use named exported types instead of repeating anonymous structural shapes in public maths APIs when those shapes appear more than once.
30+
9. Plain utility names should be safe transforms for normal finite inputs. Use `parse...` for fallible conversion that returns `undefined`, and `assert...` for explicit validation that throws.
31+
10. Document exported types the same way you document exported functions. A public type should not force users to reverse-engineer intent from its shape alone.
32+
11. Public docs must describe important edge-case behavior and defensive fallbacks, not just the happy path. If a helper returns `undefined`, ignores invalid data, normalizes inputs, or falls back to a last-resort value, say so explicitly in the doc comment.
33+
12. Keep public documentation scan-first and behavior-first. `README.md` should stay concise and point readers at `docs/`, while longer guides should explain defaults, ownership, and non-obvious behavior instead of trying to mirror the source file symbol-for-symbol.
34+
13. Prefer human-readable notes over code-shaped prose in docs. When documenting a feature, explain what it owns, when it cleans up, what defaults matter, and which edge cases surprise users most.
35+
14. Document the code as it exists today. Avoid historical framing such as "used to", "no longer", or other changelog-style wording in feature guides unless the document is explicitly a migration or changelog document.
36+
15. Describe behavior directly. Do not explain a current contract by contrasting it with an internal implementation history or an alternative contract the user was never promised.
37+
16. Keep guide structure familiar across the repo. Prefer a shared flow such as `Purpose`, `Use It When`, `Core Model`, `Important Behaviours`, and `Choosing The Right API` unless a guide has a strong reason to differ.
38+
17. Keep `docs/README.md` reader-facing. Maintainer guidance, authoring rules, and agent instructions belong in `AGENTS.md` or contributor docs, not in the public docs index.
39+
18. Keep philosophy guides durable. They should express stable principles, tradeoffs, and anti-goals rather than current package layout, feature catalogs, or temporary implementation details.
40+
19. Use British English in reader-facing guides by default. Keep code identifiers, API names, and quoted external names unchanged unless there is a specific reason to adapt them.
41+
20. Use simple American English for code-facing writing by default. Prefer it for identifiers, API names, source comments, and code-adjacent doc comments so authored code stays predictable and easy to scan.

README.md

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,52 @@
11
# BlurEngine Bebe
22

3-
Standalone context and lifecycle utilities for Minecraft Bedrock scripting.
3+
Game engine library for Minecraft Bedrock scripting.
44

5-
## Package
5+
> Warning: `bebe` is still in an early stage of development. Backward compatibility is not guaranteed yet, and breaking changes may happen while the public engine surface is still being shaped.
66
7-
- `@blurengine/bebe`: context and lifecycle layer for Minecraft Bedrock scripting
7+
## Packages
8+
9+
- `@blurengine/bebe`: engine lifecycle, ownership, and runtime primitives
10+
- `@blurengine/bebe/maths`: vectors, AABBs, tweens, and numeric helpers
811
- `npm install @blurengine/bebe @minecraft/server`
9-
- exports: `@blurengine/bebe`
1012

11-
## Usage
13+
## Quick Start
1214

1315
```ts
1416
import { Context } from "@blurengine/bebe";
17+
import { tweenNumber } from "@blurengine/bebe/maths";
1518

1619
const ctx = new Context();
1720

18-
ctx.timeout(20, () => {
19-
// ...
21+
tweenNumber(ctx, {
22+
from: 0,
23+
to: 1,
24+
durationTicks: 20,
25+
onUpdate(value) {
26+
console.warn(`progress: ${Math.round(value * 100)}%`);
27+
},
2028
});
21-
22-
ctx.dispose();
2329
```
2430

25-
## Docs
31+
## What Bebe Is For
32+
33+
- Provide a game engine layer for Bedrock scripting that can own runtime work, compose features, and grow into higher-level engine systems over time.
34+
- Keep timers, subscriptions, spawned feature scopes, and other runtime work owned by one `Context`.
35+
- Provide a separate maths surface for vector, AABB, tween, and scalar helpers without making the root package feel overloaded.
2636

37+
## Documentation
38+
39+
- [Docs Index](./docs/README.md)
40+
- [Context Guide](./docs/guides/context.md)
41+
- [Maths Guide](./docs/guides/maths.md)
2742
- [Changelog](./CHANGELOG.md)
2843

29-
## Local Development
44+
## Development
3045

31-
- `npm install`
32-
- `npm run check`
46+
```bash
47+
npm install
48+
npm run check
49+
```
3350

3451
## License
3552

docs/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# BlurEngine Bebe Docs
2+
3+
These are the canonical guides for `@blurengine/bebe` and its public subpaths.
4+
5+
## Guides
6+
7+
- [Context Guide](./guides/context.md)
8+
- [Context Patterns](./guides/context-patterns.md)
9+
- [Maths Guide](./guides/maths.md)
10+
- [Engine Philosophy](./guides/engine-philosophy.md)
11+
- [Package Structure](./guides/package-structure.md)
12+
13+
## Start Here
14+
15+
- Start with the Context Guide if you are trying to understand ownership, cleanup, and feature lifetimes.
16+
- Read Context Patterns next if you want concrete ways to structure feature scopes and services.
17+
- Start with the Maths Guide if you are working with vectors, AABBs, tweens, or numeric helpers.
18+
- Read Engine Philosophy if you are deciding whether a new feature fits the current direction of `bebe`.
19+
- Read Package Structure if you are choosing imports or navigating the repo.
20+
21+
## Scope
22+
23+
These docs cover:
24+
25+
- lifecycle ownership through `Context`
26+
- timers, subscriptions, child scopes, services, and tracked entities
27+
- the public maths surface under `@blurengine/bebe/maths`
28+
- defaults, edge cases, and behavior notes that matter when using `bebe` in Bedrock runtime code

docs/guides/context-patterns.md

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Context Patterns
2+
3+
## Purpose
4+
5+
This guide shows the main ways to structure feature lifetimes with `Context`.
6+
7+
Use it when you already understand what `Context` is, but you want a clearer sense of how many scopes to create, where services belong, and when `use(...)` is the right tool.
8+
9+
## Use It When
10+
11+
- a feature owns several timers, subscriptions, or tracked entities together
12+
- a feature needs shorter-lived nested work inside a larger lifetime
13+
- you are deciding between direct ownership, a child scope, a service, or explicit teardown
14+
- you want authored code to follow the same ownership shape across the repo
15+
16+
## Core Model
17+
18+
- one feature lifetime -> one `Context`
19+
- one shorter nested lifetime -> one child scope
20+
- one shared runtime helper -> one service on the scope that should own it
21+
- one custom teardown with no dedicated helper -> `use(...)`
22+
23+
The goal is not to create more scopes for their own sake. The goal is to make ownership obvious.
24+
25+
## Important Patterns
26+
27+
### Feature Scope
28+
29+
Use one `Context` for one feature lifetime.
30+
31+
This is the default pattern for:
32+
33+
- a temporary gameplay system
34+
- a feature session
35+
- one controller object that owns several runtime behaviours together
36+
37+
Keep related work on that one context:
38+
39+
- `subscribe(...)`
40+
- `timeout(...)`
41+
- `interval(...)`
42+
- `run(...)`
43+
- `trackEntity(...)`
44+
45+
Dispose the context when the feature ends.
46+
47+
### Child Scope
48+
49+
Use `createScope(...)` when one part of a feature has a shorter lifetime than the parent feature.
50+
51+
Good fits:
52+
53+
- a temporary effect inside a longer-running system
54+
- one spawned entity inside a broader feature
55+
- one branch of logic that should stop without tearing down the whole parent
56+
57+
The child scope should represent a real lifetime boundary. If it does not, keep the work on the parent context.
58+
59+
### Subscription Ownership
60+
61+
Use `subscribe(...)` when the work is event-driven and the subscription should end with the context.
62+
63+
This is the normal pattern for Bedrock events:
64+
65+
- register through `ctx.subscribe(...)`
66+
- keep the returned unsubscribe only when the feature may stop earlier than the context lifetime
67+
68+
If the handler should only run a fixed number of times, use `subscribe({ source, n }, handler)`.
69+
70+
### Service On A Parent Scope
71+
72+
Use a service when several parts of the same feature tree need one shared runtime-owned helper.
73+
74+
Good fits:
75+
76+
- monitors
77+
- registries
78+
- caches tied to one feature lifetime
79+
- helper objects that own both state and behaviour
80+
81+
Put the service on the scope that should own its lifetime.
82+
83+
That usually means:
84+
85+
- feature-wide helper -> parent scope service
86+
- local one-off helper -> local scope value, not a service
87+
88+
### Entity Ownership
89+
90+
Use `trackEntity(...)` when a context owns one or more entities.
91+
92+
This is a good pattern when:
93+
94+
- one feature scope owns several spawned entities that should be removed together
95+
- one scope exists because one specific entity exists
96+
- entities should be removed when the owning context is disposed
97+
- one tracked entity should also be able to end the context lifetime when it disappears
98+
99+
Important defaults:
100+
101+
- `removeOnDispose` defaults to `true`
102+
- `linkRemove` defaults to `false`
103+
104+
The important distinction is:
105+
106+
- `removeOnDispose` makes the context own entity cleanup
107+
- `linkRemove` lets a tracked entity act as a lifetime signal for the context
108+
109+
One entity per scope is a useful pattern, but it is not the only intended use. A single context can own many related entities.
110+
111+
### Explicit Teardown
112+
113+
Use `use(...)` when the feature needs teardown that does not already map to a more specific helper.
114+
115+
This is the lowest-level ownership primitive, so it should stay the exception, not the first thing every feature reaches for.
116+
117+
Reach for it when:
118+
119+
- you have custom teardown logic
120+
- the work is not a service, subscription, timer, or tracked entity
121+
- the more specific helpers would only wrap the same teardown less clearly
122+
123+
## Choosing The Right Pattern
124+
125+
- one feature lifetime -> `new Context()`
126+
- shorter nested lifetime -> `createScope(...)`
127+
- Bedrock event ownership -> `subscribe(...)`
128+
- shared runtime helper -> service
129+
- one or more owned entities -> `trackEntity(...)`
130+
- custom teardown -> `use(...)`
131+
132+
If more than one pattern seems possible, prefer the one that makes lifetime ownership easiest to explain in one sentence.

docs/guides/context.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Context Guide
2+
3+
## Purpose
4+
5+
`Context` is the lifecycle ownership layer in `bebe`.
6+
7+
Use it when a feature creates runtime work that should be cleaned up through one ownership scope.
8+
9+
## Use It When
10+
11+
- a feature owns timers, subscriptions, or tracked entities
12+
- a piece of runtime behaviour needs clear cleanup boundaries
13+
- one feature needs shorter-lived child scopes inside a larger lifetime
14+
- shared runtime helpers should belong to one feature lifetime instead of floating globally
15+
16+
## Core Model
17+
18+
- Create a `Context` for a feature lifetime.
19+
- Register work on that context.
20+
- Create child scopes when part of that feature needs a shorter lifetime.
21+
- Dispose the parent when the feature ends.
22+
23+
The central question is: which context owns this work?
24+
25+
## What Context Owns
26+
27+
A context can own:
28+
29+
- `run`, `timeout`, and `interval` callbacks
30+
- event subscriptions created through `subscribe(...)`
31+
- child scopes created through `createScope(...)`
32+
- services stored through `setService(...)` and `ensureService(...)`
33+
- tracked entities registered through `trackEntity(...)`
34+
- explicit cleanup registered through `use(...)` or `onDispose(...)`
35+
36+
## Important Behaviours
37+
38+
### `new Context()`
39+
40+
Directly constructed contexts join the internal root disposal tree.
41+
42+
### `createScope(...)`
43+
44+
Child scopes inherit service lookup from their parent by default. This is useful for feature-local scopes that need access to long-lived services. If a child should not see parent services, disable inheritance when you create the scope.
45+
46+
### `run(...)`, `timeout(...)`, and `interval(...)`
47+
48+
- `run(fn)` is the next-tick convenience form of `timeout(0, fn)`
49+
- negative tick values are clamped up to `0`
50+
- `interval({ ticks, n }, fn)` can auto-stop after `n` runs
51+
52+
### `subscribe(...)`
53+
54+
`subscribe(...)` returns an unsubscribe function and also registers that teardown with the owning context.
55+
56+
- disposing the context unsubscribes automatically
57+
- `subscribe({ source, n }, handler)` auto-unsubscribes after `n` handler runs
58+
- the returned unsubscribe function is useful when a feature needs to stop earlier than the context lifetime
59+
60+
### `onDispose(...)`
61+
62+
`onDispose(...)` callbacks are scheduled through `system.run(...)` during disposal.
63+
64+
That scheduling matters when teardown order is important.
65+
66+
### Services
67+
68+
Services are lifecycle-owned values stored on a context and looked up by key.
69+
70+
They are a good fit for:
71+
72+
- monitors
73+
- registries
74+
- caches tied to a runtime feature lifetime
75+
- helper objects that expose behaviour and state together
76+
77+
Use services for runtime-owned helpers and shared feature infrastructure. Use ordinary locals for plain local state.
78+
79+
### `trackEntity(...)`
80+
81+
`trackEntity(...)` is useful when a context owns one or more spawned or long-lived entities.
82+
83+
Behaviour to remember:
84+
85+
- `removeOnDispose` defaults to `true`
86+
- `linkRemove` defaults to `false`
87+
- disposing the context attempts to remove every tracked entity owned by that context
88+
- `linkRemove: true` makes the context dispose itself when that tracked entity is removed
89+
90+
## Choosing The Right API
91+
92+
Most authored code should stay inside a small set of patterns:
93+
94+
- feature lifetime -> `Context`
95+
- shorter nested lifetime -> `createScope(...)`
96+
- Bedrock event ownership -> `subscribe(...)`
97+
- shared runtime helper -> service
98+
- custom teardown with no dedicated helper -> `use(...)`
99+
100+
`use(...)` is the lower-level ownership primitive. Reach for it when the more specific helpers do not match the work you need to own.

0 commit comments

Comments
 (0)