@dcl-regenesislabs/web-editor 0.3.20 → 0.3.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,26 @@
1
+ {
2
+ "id": "3dd512ef-86ba-4ca2-8974-dc7629ded037",
3
+ "name": "Pickup Item",
4
+ "description": "Something players pick up with E (or the phone's action button), carry in the right hand, drop and throw. The Multiplayer Server decides who holds it, and the player sees it in hand at once. Works with: Work Station.",
5
+ "category": "custom",
6
+ "tags": [
7
+ "pickup",
8
+ "carry",
9
+ "hold",
10
+ "item",
11
+ "ingredient",
12
+ "throw",
13
+ "multiplayer"
14
+ ],
15
+ "requiresSdk": "auth-server",
16
+ "version": "1.0.0",
17
+ "changelog": [
18
+ {
19
+ "version": "1.0.0",
20
+ "notes": "Initial release: one holder at a time decided by the Multiplayer Server, held in the right hand and shown at once, a floating prompt with the device's own control, drop, optional throw, endless supply crates, and a script API to read, give and take what players carry."
21
+ }
22
+ ],
23
+ "origin": {
24
+ "source": "builtin"
25
+ }
26
+ }
@@ -0,0 +1,43 @@
1
+ import type { Entity } from '@dcl/sdk/ecs'
2
+ import { isServer } from '@dcl/sdk/network'
3
+ import { registerPickup } from '~runtime/carry'
4
+ import { declareInteractButtons } from '~runtime/interactPrompt'
5
+
6
+ export class PickupItem {
7
+ constructor(
8
+ public src: string,
9
+ public entity: Entity,
10
+ /** What this is, e.g. "Tomato". Stations, recipes and scripts match items by this word. */
11
+ public kind: string = 'Item',
12
+ /** "one item" is this thing itself; "endless" hands out a new one every time (a crate); "look only" is hidden and only gives the kind its look. */
13
+ public supply: 'one item' | 'endless' | 'look only' = 'one item',
14
+ /** The prompt's verb; "{item}" marks where the kind goes, otherwise it follows the verb. */
15
+ public pickVerb: string = 'Pick up',
16
+ public dropVerb: string = 'Drop',
17
+ public throwable: boolean = false,
18
+ public throwVerb: string = 'Throw',
19
+ /** Metres a player can be from it to pick it up. */
20
+ public range: number = 2,
21
+ /** Size in the hand, relative to the placed size. */
22
+ public heldScale: number = 1,
23
+ /** After a script uses it up, it comes back home after this many seconds; 0 waits for the next round. */
24
+ public returnSeconds: number = 0
25
+ ) {}
26
+
27
+ start(): void {
28
+ registerPickup({
29
+ entity: this.entity,
30
+ kind: this.kind,
31
+ supply: this.supply,
32
+ range: this.range,
33
+ pickVerb: this.pickVerb,
34
+ dropVerb: this.dropVerb,
35
+ throwVerb: this.throwVerb,
36
+ throwable: this.throwable,
37
+ heldScale: this.heldScale,
38
+ returnSeconds: this.returnSeconds
39
+ })
40
+ if (isServer() || this.supply === 'look only') return
41
+ declareInteractButtons(this.throwable ? 'throw' : undefined)
42
+ }
43
+ }
@@ -0,0 +1,91 @@
1
+ ---
2
+ prefab: work-station
3
+ ---
4
+
5
+ # Work Station — AI guide
6
+
7
+ A spot where a carried item is put down and taken back, and optionally worked
8
+ on until it becomes another kind: chop, wash, cook. The Multiplayer Server
9
+ decides; the player sees the result at once.
10
+
11
+ The project copy is normally custom/work_station/ — check what is on disk.
12
+ Items come from the Pickup Item prefab; read custom/pickup_item/ai.md too.
13
+
14
+ ## When to use
15
+
16
+ Counters, chopping boards, sinks, stoves, ovens, delivery windows, crafting
17
+ benches: anything that holds one carried item. Never write your own put-down /
18
+ progress-bar / hold-F code: this prefab does all of it, on phones too.
19
+
20
+ ## API
21
+
22
+ Params (set them in the placePrefab request):
23
+
24
+ - `mode`: "counter" (holds one item), "hold to work" (progress only while a
25
+ player holds F / the phone's second button and stays near; letting go keeps
26
+ the progress), "timed" (progress runs by itself once the item is down —
27
+ cooking; after one turn it continues into the next recipe, so
28
+ "Soup > Burnt Soup" burns it).
29
+ - `turns`: recipes, "Tomato > Chopped Tomato, Lettuce > Chopped Lettuce".
30
+ - `seconds`: seconds each turn takes.
31
+ - `accepts`: comma-separated kinds it takes; empty takes anything.
32
+ - `combines`: putting one kind on another, "Bread + Cheese > Sandwich" (either
33
+ order). Without a combine, an occupied station refuses a second item.
34
+ - `putVerb`, `takeVerb`, `workVerb`: prompt words ("{item}" places the kind),
35
+ in the scene's language. `workVerb` defaults to "Chop": set "Wash", "Knead"…
36
+ - `range`: metres to use it (default 2).
37
+ - `itemHeight`: where the item sits above the station's origin (the default
38
+ box top is at 0.9).
39
+
40
+ The station's Name is its id. Its look is the "Work Station Top" child: replace
41
+ that box with a model (or put a model on it). A progress bar floats over the
42
+ station while work runs. Every round start empties every station.
43
+
44
+ Each kind a station makes needs a look: place a Pickup Item with `supply` "look
45
+ only" and that `kind` (e.g. "Chopped Tomato" with its model) anywhere.
46
+
47
+ Script hooks live in `src/scripts/runtime/carry.ts` (`./runtime/carry`) — read
48
+ the module header there: `onStation(name, fn)` for put/take/combine/done events,
49
+ `setRecipe` / `setCombine` (call on BOTH sides, outside `isServer()`),
50
+ `putOnStation` / `takeFromStation` / `stationItem` / `stationProgress`.
51
+
52
+ ## Do / Don't
53
+
54
+ - DON'T count progress or swap kinds in your own `game.every`; use `turns` or
55
+ `setRecipe`.
56
+ - DO react to a delivery with `onStation` inside `if (isServer())`, then clear
57
+ the station with `takeFromStation`.
58
+ - DON'T put one Work Station on top of another; give each its own Name.
59
+
60
+ ## Example
61
+
62
+ "Overcooked-style: chop tomatoes and serve them for points". Place:
63
+ Pickup Item "Tomato Crate" (`kind` "Tomato", `supply` "endless"); Pickup Item
64
+ "Chopped Tomato Look" (`kind` "Chopped Tomato", `supply` "look only"); Work
65
+ Station "Chopping Board" (`mode` "hold to work", `turns` "Tomato > Chopped
66
+ Tomato", `seconds` 3); Work Station "Serving Window" (`accepts` "Chopped
67
+ Tomato", `putVerb` "Serve"). Then src/scripts/Serving.ts:
68
+
69
+ ```ts
70
+ import { Entity } from '@dcl/sdk/ecs'
71
+ import { isServer } from '@dcl/sdk/network'
72
+ import { game } from './runtime/game'
73
+ import { onStation, takeFromStation } from './runtime/carry'
74
+
75
+ export class Serving {
76
+ constructor(public src: string, public entity: Entity) {}
77
+ start(): void {
78
+ if (!isServer()) return
79
+ onStation('Serving Window', (event) => {
80
+ if (event.type !== 'put' || event.player === undefined) return
81
+ takeFromStation('Serving Window')
82
+ const rows = (Array.isArray(game.state.served) ? game.state.served : []) as Array<{ player: string; score: number }>
83
+ const mine = rows.find((row) => row.player === event.player)
84
+ const others = rows.filter((row) => row !== mine)
85
+ game.setState({ served: [...others, { player: event.player, score: (mine?.score ?? 0) + 10 }] })
86
+ })
87
+ }
88
+ }
89
+ ```
90
+
91
+ A Leaderboard with `boardKey` "served" shows it.
@@ -0,0 +1,52 @@
1
+ {
2
+ "version": 1,
3
+ "components": [
4
+ {
5
+ "name": "core-schema::Name",
6
+ "data": {
7
+ "512": { "json": { "value": "Work Station" } },
8
+ "513": { "json": { "value": "Work Station Top" } }
9
+ }
10
+ },
11
+ {
12
+ "name": "core::Transform",
13
+ "data": {
14
+ "513": {
15
+ "json": {
16
+ "position": { "x": 0, "y": 0.45, "z": 0 },
17
+ "rotation": { "x": 0, "y": 0, "z": 0, "w": 1 },
18
+ "scale": { "x": 1, "y": 0.9, "z": 0.8 },
19
+ "parent": 512
20
+ }
21
+ }
22
+ }
23
+ },
24
+ { "name": "core::MeshRenderer", "data": { "513": { "json": { "mesh": { "$case": "box", "box": { "uvs": [] } } } } } },
25
+ { "name": "core::MeshCollider", "data": { "513": { "json": { "mesh": { "$case": "box", "box": {} } } } } },
26
+ {
27
+ "name": "core::Material",
28
+ "data": {
29
+ "513": {
30
+ "json": {
31
+ "material": {
32
+ "$case": "pbr",
33
+ "pbr": { "albedoColor": { "r": 0.55, "g": 0.4, "b": 0.27, "a": 1 } }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ },
39
+ {
40
+ "name": "asset-packs::Script",
41
+ "data": {
42
+ "512": {
43
+ "json": {
44
+ "value": [
45
+ { "path": "{assetPath}/scripts/work-station.ts", "priority": 0, "layout": "{\"params\":{},\"actions\":[]}" }
46
+ ]
47
+ }
48
+ }
49
+ }
50
+ }
51
+ ]
52
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "id": "500b804b-8d35-420a-b323-243df2e0eaa9",
3
+ "name": "Work Station",
4
+ "description": "A spot where a carried item is put down and taken back, and optionally worked on: hold F (or the phone's second button) to chop or wash it, or let it cook by itself, with a progress bar over it. Works with: Pickup Item.",
5
+ "category": "custom",
6
+ "tags": [
7
+ "station",
8
+ "counter",
9
+ "craft",
10
+ "cook",
11
+ "chop",
12
+ "progress",
13
+ "multiplayer"
14
+ ],
15
+ "requiresSdk": "auth-server",
16
+ "version": "1.0.0",
17
+ "changelog": [
18
+ {
19
+ "version": "1.0.0",
20
+ "notes": "Initial release: put down and take back one carried item, hold-to-work and timed modes that turn one kind into another with a progress bar, combining two kinds, and station events a script reacts to by the station's Name."
21
+ }
22
+ ],
23
+ "origin": {
24
+ "source": "builtin"
25
+ }
26
+ }
@@ -0,0 +1,46 @@
1
+ import type { Entity } from '@dcl/sdk/ecs'
2
+ import { isServer } from '@dcl/sdk/network'
3
+ import { registerStation } from '~runtime/carry'
4
+ import { declareInteractButtons } from '~runtime/interactPrompt'
5
+
6
+ export class WorkStation {
7
+ constructor(
8
+ public src: string,
9
+ public entity: Entity,
10
+ /** "counter" holds one item; "hold to work" turns it while a player holds F (the phone's second button); "timed" turns it by itself (cooking). */
11
+ public mode: 'counter' | 'hold to work' | 'timed' = 'counter',
12
+ /** What work turns into what, e.g. "Tomato > Chopped Tomato, Lettuce > Chopped Lettuce". */
13
+ public turns: string = '',
14
+ /** Seconds of work (or of waiting, when timed) each turn takes. */
15
+ public seconds: number = 3,
16
+ /** Kinds this station takes, comma-separated; empty takes anything. */
17
+ public accepts: string = '',
18
+ /** Putting one kind on another makes a third, e.g. "Bread + Cheese > Sandwich". */
19
+ public combines: string = '',
20
+ public putVerb: string = 'Put down',
21
+ public takeVerb: string = 'Take',
22
+ public workVerb: string = 'Chop',
23
+ /** Metres a player can be from it to use it. */
24
+ public range: number = 2,
25
+ /** Height above the station's origin where an item sits. */
26
+ public itemHeight: number = 1.05
27
+ ) {}
28
+
29
+ start(): void {
30
+ registerStation({
31
+ entity: this.entity,
32
+ mode: this.mode === 'hold to work' ? 'hold' : this.mode,
33
+ accepts: this.accepts,
34
+ turns: this.turns,
35
+ combines: this.combines,
36
+ seconds: this.seconds,
37
+ range: this.range,
38
+ itemHeight: this.itemHeight,
39
+ putVerb: this.putVerb,
40
+ takeVerb: this.takeVerb,
41
+ workVerb: this.workVerb
42
+ })
43
+ if (isServer()) return
44
+ declareInteractButtons(this.mode === 'hold to work' ? 'chop' : undefined)
45
+ }
46
+ }
package/scene/about CHANGED
@@ -5,7 +5,7 @@
5
5
  "networkId": 0,
6
6
  "globalScenesUrn": [],
7
7
  "scenesUrn": [
8
- "urn:decentraland:entity:bafkreidloe2ozo4x2bmsjzt7svco43amj6pmj5zo7sisjnubj5w4et4sjm"
8
+ "urn:decentraland:entity:bafkreihd3gtmg3p2azy5yfmzwihyk2pwunwuqkhrjybqzdp6vavsosna4y"
9
9
  ],
10
10
  "realmName": "editor-scene"
11
11
  },
@@ -1 +1 @@
1
- {"content":[{"file":"scene.json","hash":"bafkreiby2gmthtauf7cckttphmhpecsueyypi2hzlke4lcodg7fm4cm2sq"},{"file":"bin/index.js","hash":"bafybeid4ndp7yylj3crls72kctre6gtc4hggnrxf7qqutw5giym2rr4qba"}],"pointers":[],"timestamp":0,"type":"scene","metadata":{"ecs7":true,"runtimeVersion":"7","display":{"title":"Component Inspector","description":"Inspect and modify component state of the current scene"},"owner":"","contact":{"name":"","email":""},"main":"bin/index.js","tags":[],"scene":{"parcels":["0,0"],"base":"0,0"},"spawnPoints":[],"featureToggles":{"portableExperiences":"enabled"}},"version":"v3"}
1
+ {"content":[{"file":"scene.json","hash":"bafkreiby2gmthtauf7cckttphmhpecsueyypi2hzlke4lcodg7fm4cm2sq"},{"file":"bin/index.js","hash":"bafybeifiaotfpb4kis6f46xdw6a2rm6c534wewr55bq7zwcidmthvd4y7m"}],"pointers":[],"timestamp":0,"type":"scene","metadata":{"ecs7":true,"runtimeVersion":"7","display":{"title":"Component Inspector","description":"Inspect and modify component state of the current scene"},"owner":"","contact":{"name":"","email":""},"main":"bin/index.js","tags":[],"scene":{"parcels":["0,0"],"base":"0,0"},"spawnPoints":[],"featureToggles":{"portableExperiences":"enabled"}},"version":"v3"}