Skip to content

Commit ac90e29

Browse files
committed
wip: readme and dx
1 parent 80a22ac commit ac90e29

File tree

6 files changed

+117
-16
lines changed

6 files changed

+117
-16
lines changed

README.md

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,100 @@
11

2-
# @benev/marduk
2+
# MARDUK
3+
4+
**Marduk** is a [BabylonJS](https://www.babylonjs.com/) framework for rendering good web games.
5+
- 🧵 **Multithreaded** — rendering happens in its own thread
6+
- 🎳 **Smart architecture** — logic and rendering happen on separate threads
7+
8+
<br/>
9+
10+
## Install Marduk
11+
12+
```sh
13+
npm install @benev/marduk
14+
```
15+
16+
<br/>
17+
18+
## Theater
19+
20+
The theater coordinates your rendering thread and displays the results onto a canvas.
21+
22+
The theater is split into two main parts. Each will live in its own separate bundle.
23+
- *The Frontstage* hosts the visible canvas in the dom. It doesn't import Babylon, and will be lean in filesize.
24+
- *The Backstage* run inside a web worker, and performs rendering work. It imports Babylon, and will be fat in filesize.
25+
26+
### Theater project setup
27+
1. Write your `spec.ts` type, which describes your renderable world
28+
```ts
29+
export type MySpec = AsFigmentSpec<{
30+
31+
// Describe all the renderable objects in your world,
32+
// in terms of serializable data.
33+
hippo: {hungry: boolean}
34+
}>
35+
```
36+
1. Establish your `backstage.ts` module (this will be a web worker)
37+
```ts
38+
import {MySpec} from "./spec.js"
39+
import {theaterWorker, babylonBackstage} from "@benev/marduk"
40+
41+
void async function() {
42+
await theaterWorker(
43+
await babylonBackstage<MySpec>(async stagecraft => ({
44+
45+
// now we define a renderer for this object
46+
hippo: (id, data) => {
47+
console.log("spawn", id, data)
48+
return {
49+
update: data => console.log("update", id, data),
50+
dispose: () => console.log("dispose", id, data),
51+
}
52+
},
53+
}))
54+
)
55+
}()
56+
```
57+
- now bundle this module as `backstage.bundle.js` using `rollup`, `esbuild`, `parcel`, `vite`, or whatever
58+
1. Establish your `frontstage.ts` module (this will be your app's main entrypoint)
59+
```ts
60+
import {MySpec} from "./spec.js"
61+
import {theaterHost, Frontstage, theaterElement, register} from "@benev/marduk/x/theater/index.js"
62+
63+
void async function() {
64+
65+
// relative url to the backstage web worker bundle
66+
const workerUrl = new URL("./backstage.bundle.js", import.meta.url)
67+
68+
// setup the frontstage
69+
const frontstage = new Frontstage(
70+
await theaterHost<MySpec>({workerUrl})
71+
)
72+
73+
// create the <marduk-theater> web component
74+
const MardukTheater = theaterElement(frontstage)
75+
76+
// register to the dom
77+
register({MardukTheater})
78+
79+
// okay, now you're ready to manipulate your world
80+
81+
// spawn a hippo
82+
await theater.backstage.setFigments([[0, ["hippo", {hungry: false}]]])
83+
84+
// update the hippo
85+
await theater.backstage.setFigments([[0, ["hippo", {hungry: true}]]])
86+
87+
// delete the hippo
88+
await theater.backstage.setFigments([[0, undefined]])
89+
}()
90+
```
91+
- now bundle this module as `frontstage.bundle.js`
92+
1. Load the frontstage onto your web page
93+
```html
94+
<script type=module src="./frontstage.bundle.js"></script>
95+
```
96+
1. Place the `<marduk-theater>` element in your html body
97+
```html
98+
<marduk-theater></marduk-theater>
99+
```
3100

s/demo/theater/front.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ export async function demoFrontstage() {
1111
})
1212

1313
// test full lifecycle
14-
await theater.thread.work.setFigments([[0, ["hippo", {hungry: false}]]])
15-
await theater.thread.work.setFigments([[0, ["hippo", {hungry: true}]]])
16-
await theater.thread.work.setFigments([[0, undefined]])
14+
await theater.backstage.setFigments([[0, ["hippo", {hungry: false}]]])
15+
await theater.backstage.setFigments([[0, ["hippo", {hungry: true}]]])
16+
await theater.backstage.setFigments([[0, undefined]])
1717

1818
return new Frontstage(theater)
1919
}

s/demo/theater/worker.bundle.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,15 @@ import {DemoFigmentSpec} from "./spec.js"
33
import {theaterWorker} from "../../theater/theater-worker.js"
44
import {babylonBackstage} from "../../theater/babylon-backstage.js"
55

6-
const backstage = await babylonBackstage<DemoFigmentSpec>(async stagecraft => {
7-
stagecraft.gameloop.start()
8-
return {
9-
hippo: (id, data) => {
10-
console.log("spawn", id, data)
11-
return {
12-
update: data => console.log("update", id, data),
13-
dispose: () => console.log("dispose", id, data),
14-
}
15-
},
16-
}
17-
})
6+
const backstage = await babylonBackstage<DemoFigmentSpec>(async stagecraft => ({
7+
hippo: (id, data) => {
8+
console.log("spawn", id, data)
9+
return {
10+
update: data => console.log("update", id, data),
11+
dispose: () => console.log("dispose", id, data),
12+
}
13+
},
14+
}))
1815

1916
theaterWorker(backstage)
2017

s/theater/babylon-backstage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export async function babylonBackstage<Fs extends FigmentSpec>(
4444
}
4545

4646
const spawners = await establish(stagecraft)
47+
stagecraft.gameloop.start()
4748

4849
return {
4950
...stagecraft,

s/theater/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11

2+
export {register} from "@benev/slate/x/base/helpers/register.js"
3+
24
export * from "./parts/types.js"
35
export {theaterHost} from "./theater-host.js"
46
export {theaterWorker} from "./theater-worker.js"
7+
export {Frontstage} from "./parts/frontstage.js"
8+
export {theaterElement} from "./element/element.js"
59

s/theater/parts/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
import {Sub} from "@e280/stz"
3+
import {Remote} from "@e280/renraku"
34
import {Vec2Array} from "@benev/math"
45
import {Spawn} from "../../tools/lifecycler.js"
56
import {AsSchematic, Comrade} from "@e280/comrade"
@@ -11,6 +12,7 @@ export type TheaterHostOptions = {
1112
export type Theater<Fs extends FigmentSpec = any> = {
1213
onFrame: Sub<[frame: Frame]>
1314
thread: Comrade.Thread<TheaterSchematic<Fs>>
15+
backstage: Remote<TheaterSchematic<Fs>["work"]>
1416
}
1517

1618
export type TheaterSchematic<Fs extends FigmentSpec> = AsSchematic<{

0 commit comments

Comments
 (0)