hytopia 0.1.76 → 0.1.78

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.
Files changed (41) hide show
  1. package/boilerplate/index.ts +2 -2
  2. package/docs/server.entitymanager.getallplayerentities.md +3 -39
  3. package/docs/server.entitymanager.getplayerentitiesbyplayer.md +55 -0
  4. package/docs/server.entitymanager.md +16 -2
  5. package/docs/server.gameserver.md +2 -2
  6. package/docs/{server.gameserver.modelmanager.md → server.gameserver.modelregistry.md} +3 -3
  7. package/docs/server.md +1 -1
  8. package/docs/{server.modelmanager.getboundingbox.md → server.modelregistry.getboundingbox.md} +2 -2
  9. package/docs/server.modelregistry.instance.md +13 -0
  10. package/docs/{server.modelmanager.md → server.modelregistry.md} +12 -12
  11. package/docs/server.playermanager.getconnectedplayersbyworld.md +55 -0
  12. package/docs/server.playermanager.md +14 -0
  13. package/docs/server.sceneuimanager.getsceneuibyid.md +55 -0
  14. package/docs/server.sceneuimanager.md +14 -0
  15. package/examples/ai-agents/README.md +47 -0
  16. package/examples/ai-agents/assets/map.json +25828 -0
  17. package/examples/ai-agents/assets/ui/index.html +215 -0
  18. package/examples/ai-agents/index.ts +350 -0
  19. package/examples/ai-agents/package.json +16 -0
  20. package/examples/ai-agents/src/BaseAgent.ts +482 -0
  21. package/examples/ai-agents/src/behaviors/FishingBehavior.ts +181 -0
  22. package/examples/ai-agents/src/behaviors/FollowBehavior.ts +171 -0
  23. package/examples/ai-agents/src/behaviors/MiningBehavior.ts +226 -0
  24. package/examples/ai-agents/src/behaviors/PathfindingBehavior.ts +435 -0
  25. package/examples/ai-agents/src/behaviors/SpeakBehavior.ts +50 -0
  26. package/examples/ai-agents/src/behaviors/TradeBehavior.ts +254 -0
  27. package/examples/big-world/index.ts +1 -1
  28. package/examples/block-entity/index.ts +3 -3
  29. package/examples/custom-ui/index.ts +1 -1
  30. package/examples/entity-controller/MyEntityController.ts +1 -1
  31. package/examples/entity-controller/index.ts +1 -1
  32. package/examples/entity-spawn/index.ts +1 -1
  33. package/examples/hole-in-wall-game/index.ts +1 -1
  34. package/examples/lighting/index.ts +1 -1
  35. package/examples/payload-game/index.ts +1 -1
  36. package/examples/wall-dodge-game/index.ts +1 -1
  37. package/package.json +1 -1
  38. package/server.api.json +181 -38
  39. package/server.d.ts +31 -21
  40. package/server.js +19 -19
  41. package/docs/server.modelmanager.instance.md +0 -13
@@ -103,7 +103,7 @@ startServer(world => {
103
103
  * instance.
104
104
  */
105
105
  world.onPlayerLeave = player => {
106
- world.entityManager.getAllPlayerEntities(player).forEach(entity => entity.despawn());
106
+ world.entityManager.getPlayerEntitiesByPlayer(player).forEach(entity => entity.despawn());
107
107
  };
108
108
 
109
109
  /**
@@ -111,7 +111,7 @@ startServer(world => {
111
111
  * "/rocket" in the game, they'll get launched into the air!
112
112
  */
113
113
  world.chatManager.registerCommand('/rocket', player => {
114
- world.entityManager.getAllPlayerEntities(player).forEach(entity => {
114
+ world.entityManager.getPlayerEntitiesByPlayer(player).forEach(entity => {
115
115
  entity.applyImpulse({ x: 0, y: 20, z: 0 });
116
116
  });
117
117
  });
@@ -4,52 +4,16 @@
4
4
 
5
5
  ## EntityManager.getAllPlayerEntities() method
6
6
 
7
- Gets all spawned entities in the world assigned to a player.
7
+ Gets all spawned player entities in the world.
8
8
 
9
9
  **Signature:**
10
10
 
11
11
  ```typescript
12
- getAllPlayerEntities(player: Player): PlayerEntity[];
12
+ getAllPlayerEntities(): PlayerEntity[];
13
13
  ```
14
-
15
- ## Parameters
16
-
17
- <table><thead><tr><th>
18
-
19
- Parameter
20
-
21
-
22
- </th><th>
23
-
24
- Type
25
-
26
-
27
- </th><th>
28
-
29
- Description
30
-
31
-
32
- </th></tr></thead>
33
- <tbody><tr><td>
34
-
35
- player
36
-
37
-
38
- </td><td>
39
-
40
- [Player](./server.player.md)
41
-
42
-
43
- </td><td>
44
-
45
- The player to get the entities for.
46
-
47
-
48
- </td></tr>
49
- </tbody></table>
50
14
  **Returns:**
51
15
 
52
16
  [PlayerEntity](./server.playerentity.md)<!-- -->\[\]
53
17
 
54
- All spawned entities in the world assigned to the player.
18
+ All spawned player entities in the world.
55
19
 
@@ -0,0 +1,55 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [server](./server.md) &gt; [EntityManager](./server.entitymanager.md) &gt; [getPlayerEntitiesByPlayer](./server.entitymanager.getplayerentitiesbyplayer.md)
4
+
5
+ ## EntityManager.getPlayerEntitiesByPlayer() method
6
+
7
+ Gets all spawned entities in the world assigned to the provided player.
8
+
9
+ **Signature:**
10
+
11
+ ```typescript
12
+ getPlayerEntitiesByPlayer(player: Player): PlayerEntity[];
13
+ ```
14
+
15
+ ## Parameters
16
+
17
+ <table><thead><tr><th>
18
+
19
+ Parameter
20
+
21
+
22
+ </th><th>
23
+
24
+ Type
25
+
26
+
27
+ </th><th>
28
+
29
+ Description
30
+
31
+
32
+ </th></tr></thead>
33
+ <tbody><tr><td>
34
+
35
+ player
36
+
37
+
38
+ </td><td>
39
+
40
+ [Player](./server.player.md)
41
+
42
+
43
+ </td><td>
44
+
45
+ The player to get the entities for.
46
+
47
+
48
+ </td></tr>
49
+ </tbody></table>
50
+ **Returns:**
51
+
52
+ [PlayerEntity](./server.playerentity.md)<!-- -->\[\]
53
+
54
+ All spawned entities in the world assigned to the player.
55
+
@@ -107,7 +107,7 @@ Gets all spawned entities in the world.
107
107
  </td></tr>
108
108
  <tr><td>
109
109
 
110
- [getAllPlayerEntities(player)](./server.entitymanager.getallplayerentities.md)
110
+ [getAllPlayerEntities()](./server.entitymanager.getallplayerentities.md)
111
111
 
112
112
 
113
113
  </td><td>
@@ -115,7 +115,7 @@ Gets all spawned entities in the world.
115
115
 
116
116
  </td><td>
117
117
 
118
- Gets all spawned entities in the world assigned to a player.
118
+ Gets all spawned player entities in the world.
119
119
 
120
120
 
121
121
  </td></tr>
@@ -160,5 +160,19 @@ Gets all spawned entities in the world with a tag that includes a specific subst
160
160
  Gets a spawned entity in the world by its id.
161
161
 
162
162
 
163
+ </td></tr>
164
+ <tr><td>
165
+
166
+ [getPlayerEntitiesByPlayer(player)](./server.entitymanager.getplayerentitiesbyplayer.md)
167
+
168
+
169
+ </td><td>
170
+
171
+
172
+ </td><td>
173
+
174
+ Gets all spawned entities in the world assigned to the provided player.
175
+
176
+
163
177
  </td></tr>
164
178
  </tbody></table>
@@ -66,7 +66,7 @@ The singleton instance of the game server.
66
66
  </td></tr>
67
67
  <tr><td>
68
68
 
69
- [modelManager](./server.gameserver.modelmanager.md)
69
+ [modelRegistry](./server.gameserver.modelregistry.md)
70
70
 
71
71
 
72
72
  </td><td>
@@ -76,7 +76,7 @@ The singleton instance of the game server.
76
76
 
77
77
  </td><td>
78
78
 
79
- [ModelManager](./server.modelmanager.md)
79
+ [ModelRegistry](./server.modelregistry.md)
80
80
 
81
81
 
82
82
  </td><td>
@@ -1,13 +1,13 @@
1
1
  <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
2
 
3
- [Home](./index.md) &gt; [server](./server.md) &gt; [GameServer](./server.gameserver.md) &gt; [modelManager](./server.gameserver.modelmanager.md)
3
+ [Home](./index.md) &gt; [server](./server.md) &gt; [GameServer](./server.gameserver.md) &gt; [modelRegistry](./server.gameserver.modelregistry.md)
4
4
 
5
- ## GameServer.modelManager property
5
+ ## GameServer.modelRegistry property
6
6
 
7
7
  The model manager for the game server.
8
8
 
9
9
  **Signature:**
10
10
 
11
11
  ```typescript
12
- get modelManager(): ModelManager;
12
+ get modelRegistry(): ModelRegistry;
13
13
  ```
package/docs/server.md CHANGED
@@ -195,7 +195,7 @@ Manages Light instances in a world.
195
195
  </td></tr>
196
196
  <tr><td>
197
197
 
198
- [ModelManager](./server.modelmanager.md)
198
+ [ModelRegistry](./server.modelregistry.md)
199
199
 
200
200
 
201
201
  </td><td>
@@ -1,8 +1,8 @@
1
1
  <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
2
 
3
- [Home](./index.md) &gt; [server](./server.md) &gt; [ModelManager](./server.modelmanager.md) &gt; [getBoundingBox](./server.modelmanager.getboundingbox.md)
3
+ [Home](./index.md) &gt; [server](./server.md) &gt; [ModelRegistry](./server.modelregistry.md) &gt; [getBoundingBox](./server.modelregistry.getboundingbox.md)
4
4
 
5
- ## ModelManager.getBoundingBox() method
5
+ ## ModelRegistry.getBoundingBox() method
6
6
 
7
7
  Retrieves the bounding box of a model.
8
8
 
@@ -0,0 +1,13 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [server](./server.md) &gt; [ModelRegistry](./server.modelregistry.md) &gt; [instance](./server.modelregistry.instance.md)
4
+
5
+ ## ModelRegistry.instance property
6
+
7
+ The global ModelRegistry instance as a singleton.
8
+
9
+ **Signature:**
10
+
11
+ ```typescript
12
+ static readonly instance: ModelRegistry;
13
+ ```
@@ -1,31 +1,31 @@
1
1
  <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
2
 
3
- [Home](./index.md) &gt; [server](./server.md) &gt; [ModelManager](./server.modelmanager.md)
3
+ [Home](./index.md) &gt; [server](./server.md) &gt; [ModelRegistry](./server.modelregistry.md)
4
4
 
5
- ## ModelManager class
5
+ ## ModelRegistry class
6
6
 
7
7
  Manages model data for all known models of the game.
8
8
 
9
9
  **Signature:**
10
10
 
11
11
  ```typescript
12
- export default class ModelManager
12
+ export default class ModelRegistry
13
13
  ```
14
14
 
15
15
  ## Remarks
16
16
 
17
- The ModelManager is created internally as a global singletone accessible with the static property `ModelManager.instance`<!-- -->.
17
+ The ModelRegistry is created internally as a global singletone accessible with the static property `ModelRegistry.instance`<!-- -->.
18
18
 
19
- The constructor for this class is marked as internal. Third-party code should not call the constructor directly or create subclasses that extend the `ModelManager` class.
19
+ The constructor for this class is marked as internal. Third-party code should not call the constructor directly or create subclasses that extend the `ModelRegistry` class.
20
20
 
21
21
  ## Example
22
22
 
23
23
 
24
24
  ```typescript
25
- import { ModelManager } from 'hytopia';
25
+ import { ModelRegistry } from 'hytopia';
26
26
 
27
- const modelManager = ModelManager.instance;
28
- const boundingBox = modelManager.getBoundingBox('models/player.gltf');
27
+ const modelRegistry = ModelRegistry.instance;
28
+ const boundingBox = modelRegistry.getBoundingBox('models/player.gltf');
29
29
  ```
30
30
 
31
31
  ## Properties
@@ -53,7 +53,7 @@ Description
53
53
  </th></tr></thead>
54
54
  <tbody><tr><td>
55
55
 
56
- [instance](./server.modelmanager.instance.md)
56
+ [instance](./server.modelregistry.instance.md)
57
57
 
58
58
 
59
59
  </td><td>
@@ -65,12 +65,12 @@ Description
65
65
 
66
66
  </td><td>
67
67
 
68
- [ModelManager](./server.modelmanager.md)
68
+ [ModelRegistry](./server.modelregistry.md)
69
69
 
70
70
 
71
71
  </td><td>
72
72
 
73
- The global PlayerManager instance as a singleton.
73
+ The global ModelRegistry instance as a singleton.
74
74
 
75
75
 
76
76
  </td></tr>
@@ -96,7 +96,7 @@ Description
96
96
  </th></tr></thead>
97
97
  <tbody><tr><td>
98
98
 
99
- [getBoundingBox(modelUri)](./server.modelmanager.getboundingbox.md)
99
+ [getBoundingBox(modelUri)](./server.modelregistry.getboundingbox.md)
100
100
 
101
101
 
102
102
  </td><td>
@@ -0,0 +1,55 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [server](./server.md) &gt; [PlayerManager](./server.playermanager.md) &gt; [getConnectedPlayersByWorld](./server.playermanager.getconnectedplayersbyworld.md)
4
+
5
+ ## PlayerManager.getConnectedPlayersByWorld() method
6
+
7
+ Get all connected players in a specific world.
8
+
9
+ **Signature:**
10
+
11
+ ```typescript
12
+ getConnectedPlayersByWorld(world: World): Player[];
13
+ ```
14
+
15
+ ## Parameters
16
+
17
+ <table><thead><tr><th>
18
+
19
+ Parameter
20
+
21
+
22
+ </th><th>
23
+
24
+ Type
25
+
26
+
27
+ </th><th>
28
+
29
+ Description
30
+
31
+
32
+ </th></tr></thead>
33
+ <tbody><tr><td>
34
+
35
+ world
36
+
37
+
38
+ </td><td>
39
+
40
+ [World](./server.world.md)
41
+
42
+
43
+ </td><td>
44
+
45
+ The world to get connected players for.
46
+
47
+
48
+ </td></tr>
49
+ </tbody></table>
50
+ **Returns:**
51
+
52
+ [Player](./server.player.md)<!-- -->\[\]
53
+
54
+ An array of all connected players in the world.
55
+
@@ -121,5 +121,19 @@ Get a connected player by their username (case insensitive).
121
121
  Get all connected players.
122
122
 
123
123
 
124
+ </td></tr>
125
+ <tr><td>
126
+
127
+ [getConnectedPlayersByWorld(world)](./server.playermanager.getconnectedplayersbyworld.md)
128
+
129
+
130
+ </td><td>
131
+
132
+
133
+ </td><td>
134
+
135
+ Get all connected players in a specific world.
136
+
137
+
124
138
  </td></tr>
125
139
  </tbody></table>
@@ -0,0 +1,55 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [server](./server.md) &gt; [SceneUIManager](./server.sceneuimanager.md) &gt; [getSceneUIById](./server.sceneuimanager.getsceneuibyid.md)
4
+
5
+ ## SceneUIManager.getSceneUIById() method
6
+
7
+ Retrieves a SceneUI instance by its unique identifier (id).
8
+
9
+ **Signature:**
10
+
11
+ ```typescript
12
+ getSceneUIById(id: number): SceneUI | undefined;
13
+ ```
14
+
15
+ ## Parameters
16
+
17
+ <table><thead><tr><th>
18
+
19
+ Parameter
20
+
21
+
22
+ </th><th>
23
+
24
+ Type
25
+
26
+
27
+ </th><th>
28
+
29
+ Description
30
+
31
+
32
+ </th></tr></thead>
33
+ <tbody><tr><td>
34
+
35
+ id
36
+
37
+
38
+ </td><td>
39
+
40
+ number
41
+
42
+
43
+ </td><td>
44
+
45
+ The unique identifier (id) of the SceneUI to retrieve.
46
+
47
+
48
+ </td></tr>
49
+ </tbody></table>
50
+ **Returns:**
51
+
52
+ [SceneUI](./server.sceneui.md) \| undefined
53
+
54
+ The SceneUI instance if found, otherwise undefined.
55
+
@@ -109,6 +109,20 @@ Retrieves all loaded SceneUI instances attached to a specific entity.
109
109
  Retrieves all loaded SceneUI instances for the world.
110
110
 
111
111
 
112
+ </td></tr>
113
+ <tr><td>
114
+
115
+ [getSceneUIById(id)](./server.sceneuimanager.getsceneuibyid.md)
116
+
117
+
118
+ </td><td>
119
+
120
+
121
+ </td><td>
122
+
123
+ Retrieves a SceneUI instance by its unique identifier (id).
124
+
125
+
112
126
  </td></tr>
113
127
  <tr><td>
114
128
 
@@ -0,0 +1,47 @@
1
+ # Hytopia Multi Agent Demo
2
+
3
+ This demo codebase provides an example for building multi Agent AI systems in Hytopia. The server has the following features:
4
+ - Multiple AI agents with unique pathfinding, behaviour and capabilities
5
+ - Chat bubbles for agent speech
6
+ - Side bar UI for viewing Agent actions
7
+
8
+ ## How do Agents work in Hytopia?
9
+ Game Agents are driven by a combination of game-specific action logic, world state representation, and Large Language Models.
10
+
11
+ At a high level, to integrate agents into your game, you need to think about these three pieces.
12
+
13
+ ### World State Representation
14
+ Your Agents need to know what is going on in the game. Where are they? What is around them? etc..
15
+ In this demo, the following data is available in the Agent's personal state:
16
+ - Their location
17
+ - Entities around them
18
+ - The status of any ongoing actions ("Behaviors")
19
+ - Items in their inventory
20
+
21
+ For more information on this, see the [`getCurrentState()`](src/BaseAgent.ts#L205) function in BaseAgent. Each behavior returns their Agent-specific state as a string, which we group together into an object and stringify it for the Agent's prompt.
22
+ States are prepended to each prompt to the agent.
23
+
24
+ ### Actions
25
+ Actions are things that people and agents do in your game. In this simple demo, the things people do are simple: they go places, they say things, and some of them do profession-specific tasks like Fishing and Mining.
26
+
27
+ Going places means going to specific locations (by coordinates), or going to a person or thing (by name). This means Bob can go to Jim, without knowing where Jim is. Bob might also decide to go to the Pier, since Jim is a Fisherman and one would expect the town fisherman to be at the pier.
28
+
29
+ Saying things is simple, but the weeds of what that means is also game specific. In this demo, when agents speak, other agents can hear them in close proximity, but for the sake of the demo we also show their messages globally in chat. Speaking also spawns a chat bubble UI template. See the [`agent-chat template`](assets/ui/index.html#L178) for more info on this.
30
+
31
+ Actions also interact with LLMs. Since actions are called by the LLM, we need to show the LLM how to call them.
32
+ Some agent frameworks use tool calling/function calling, which is very popular with OpenAI.
33
+ You can do this if you want, but I prefer XML. XML takes less output tokens, is very natural for LLMs to write (billions of html pages parsed). Most importantly, valid XML can be easily regexed out of any text, intermingled with other thoughts from the LLM. Many benchmarks show creativity in language models decreasing as output format is increasingly restricted.
34
+
35
+ In this demo, an action can be called by an LLM simply by outputting text like this:
36
+ `<action type="speak">...</action>`
37
+
38
+ Another benefit of this approach is that models with very little infrastructure around their APIs can all output valid XML, so you can easily use whatever model or provider you want.
39
+
40
+ ### Large Language Models
41
+ LLM's act as a router and brain for the agent, converting state representations and inputs into a sequence of actions.
42
+ LLM's need to be prompted. You will not get a spontaneous output without an input. In a game, this means you need to decide when Agent's make decisions. In this demo I show two common techniques:
43
+ - Response Triggers: when a Player speaks to an Agent, they will respond immediately. This lets players have some immediate control over influencing agent behaviours, and makes it easy to test your prompts with quick feedback. This is best for smaller player counts.
44
+ - Game Steps: as you can imagine, the above response triggers will not work at scale. Imagine 100 players in an area all talking to the same agent. You would not want it to respond outloud to everyone in the area. Instead, you can take a page out of the playbook of turn-based strategy games. Divide your game time into turns (a step could be every 5 seconds, 10 seconds, whatever you want), and each turn, you trigger each agent with the new state since their last turn. Players don't need to be limited by turns, but this makes your agents a bit simpler to manage. You can see an example of how this works in the idle detection of the agents in this repo. If an agent has not been triggered by a player in the last 30 seconds, they wake up and can decide what to do next.
45
+
46
+ ## What's next?
47
+ We want to continue to make AI Agents accessible for developers of Hytopia games. This means more game-specific demos, more tooling, and a standardized Agent implementation that you can import as a plugin into your games. More on this soon :)