hytopia 0.5.0-dev3 → 0.5.2
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.
- package/bin/writeVersion.js +12 -0
- package/examples/hygrounds/classes/GamePlayerEntity.ts +1 -0
- package/examples/player-persistence/package.json +1 -1
- package/examples/world-switching/README.md +3 -0
- package/examples/world-switching/assets/maps/world1.json +2623 -0
- package/examples/world-switching/assets/maps/world2.json +25828 -0
- package/examples/world-switching/bun.lock +598 -0
- package/examples/world-switching/index.ts +102 -0
- package/examples/world-switching/package.json +19 -0
- package/package.json +5 -2
- package/server.js +124 -124
@@ -0,0 +1,102 @@
|
|
1
|
+
import {
|
2
|
+
startServer,
|
3
|
+
Collider,
|
4
|
+
DefaultPlayerEntity,
|
5
|
+
Entity,
|
6
|
+
Player,
|
7
|
+
PlayerEvent,
|
8
|
+
WorldManager,
|
9
|
+
World,
|
10
|
+
RigidBodyType,
|
11
|
+
BlockType,
|
12
|
+
} from 'hytopia';
|
13
|
+
|
14
|
+
/**
|
15
|
+
* This example demonstrates how to use the world switching system.
|
16
|
+
*
|
17
|
+
* The world switching system is designed to be flexible and performant, allowing you to:
|
18
|
+
* - Create and manage multiple distinct worlds
|
19
|
+
* - Switch players between worlds seamlessly
|
20
|
+
* - Handle world-specific events and state
|
21
|
+
* - Worlds act as fully isolated simulations from one another
|
22
|
+
*
|
23
|
+
* Performance considerations:
|
24
|
+
* - Memory usage is the primary constraint since each world's representative colliders for its map are stored in RAM
|
25
|
+
* - The system can typically handle tens of millions of blocks across multiple worlds before memory becomes an issue
|
26
|
+
* - Physics performance depends on the number of active (non-sleeping) entities across all worlds
|
27
|
+
* - Worlds with only sleeping entities (entities that haven't moved recently) use minimal CPU resources (< 0.1ms per world)
|
28
|
+
* - You can typically run a few thousand entities in total across all worlds before performance issues arise so long as they can sleep (not all moving at once).
|
29
|
+
* - Worlds are currently all simulated in the same thread, so 1 non-performant world will have some impact on the performance of other worlds.
|
30
|
+
*/
|
31
|
+
|
32
|
+
// We'll use 2 maps in this example, 1 for each unique world.
|
33
|
+
import world1Map from './assets/maps/world1.json';
|
34
|
+
import world2Map from './assets/maps/world2.json';
|
35
|
+
|
36
|
+
// The server always starts with a created default world passed in the startServer callback.
|
37
|
+
startServer(defaultWorld => {
|
38
|
+
// We'll use defaultWorld as world1 in this example.
|
39
|
+
defaultWorld.loadMap(world1Map);
|
40
|
+
|
41
|
+
// We'll create our second world using the WorldManager instance.
|
42
|
+
// This is the correct way to create a new world.
|
43
|
+
const world2 = WorldManager.instance.createWorld({
|
44
|
+
name: 'World 2',
|
45
|
+
skyboxUri: 'skyboxes/partly-cloudy', // We'll use the default skybox that ships with @hytopia.com/assets package
|
46
|
+
});
|
47
|
+
world2.loadMap(world2Map);
|
48
|
+
|
49
|
+
// We made a convenience function that spawns a entity that acts as a portal.
|
50
|
+
// When a player touches it, they'll teleport to the other world in this example.
|
51
|
+
addPortal(defaultWorld, world2);
|
52
|
+
addPortal(world2, defaultWorld);
|
53
|
+
|
54
|
+
// Each world handles player join/leave events separately. When a player switches worlds,
|
55
|
+
// they start fresh in the new world - no state or UI carries over. This gives you full
|
56
|
+
// control over what loads in each world without handling complex state management.
|
57
|
+
defaultWorld.on(PlayerEvent.JOINED_WORLD, playerJoinedWorld);
|
58
|
+
defaultWorld.on(PlayerEvent.LEFT_WORLD, playerLeftWorld);
|
59
|
+
|
60
|
+
world2.on(PlayerEvent.JOINED_WORLD, playerJoinedWorld);
|
61
|
+
world2.on(PlayerEvent.LEFT_WORLD, playerLeftWorld);
|
62
|
+
});
|
63
|
+
|
64
|
+
function playerJoinedWorld({ player, world }: { player: Player, world: World }) {
|
65
|
+
const playerEntity = new DefaultPlayerEntity({
|
66
|
+
player,
|
67
|
+
name: 'Player',
|
68
|
+
});
|
69
|
+
|
70
|
+
playerEntity.spawn(world, { x: 0, y: 10, z: 0 });
|
71
|
+
}
|
72
|
+
|
73
|
+
function playerLeftWorld({ player, world }: { player: Player, world: World }) {
|
74
|
+
world.entityManager.getPlayerEntitiesByPlayer(player).forEach(entity => entity.despawn());
|
75
|
+
}
|
76
|
+
|
77
|
+
// Our portal function creates a entity using the jump pad model at the 5,1.5,-5 position
|
78
|
+
// in the world it's added to. When a player touches the entity, they'll be switched
|
79
|
+
// to the world provided for toWorld. When they switch, the LEFT_WORLD event
|
80
|
+
// is invoked on the previous world and the JOINED_WORLD event is invoked on the one switched to.
|
81
|
+
function addPortal(world: World, toWorld: World) {
|
82
|
+
const portal = new Entity({
|
83
|
+
name: 'Portal',
|
84
|
+
modelUri: 'models/structures/jump-pad.gltf',
|
85
|
+
rigidBodyOptions: {
|
86
|
+
type: RigidBodyType.KINEMATIC_POSITION,
|
87
|
+
colliders: [
|
88
|
+
{
|
89
|
+
...Collider.optionsFromModelUri('models/structures/jump-pad.gltf'),
|
90
|
+
isSensor: true,
|
91
|
+
onCollision(other: Entity | BlockType, started: boolean) {
|
92
|
+
if (started && other instanceof DefaultPlayerEntity) {
|
93
|
+
other.player.joinWorld(toWorld);
|
94
|
+
}
|
95
|
+
},
|
96
|
+
},
|
97
|
+
],
|
98
|
+
},
|
99
|
+
});
|
100
|
+
|
101
|
+
portal.spawn(world, { x: 5, y: 1.5, z: -5 });
|
102
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
{
|
2
|
+
"name": "world-switching",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "",
|
5
|
+
"main": "index.js",
|
6
|
+
"scripts": {
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
8
|
+
},
|
9
|
+
"keywords": [],
|
10
|
+
"author": "",
|
11
|
+
"license": "ISC",
|
12
|
+
"dependencies": {
|
13
|
+
"@hytopia.com/assets": "latest",
|
14
|
+
"hytopia": "latest"
|
15
|
+
},
|
16
|
+
"trustedDependencies": [
|
17
|
+
"mediasoup"
|
18
|
+
]
|
19
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "hytopia",
|
3
|
-
"version": "0.5.
|
3
|
+
"version": "0.5.2",
|
4
4
|
"description": "The HYTOPIA SDK makes it easy for developers to create massively multiplayer games using JavaScript or TypeScript.",
|
5
5
|
"main": "server.js",
|
6
6
|
"bin": {
|
@@ -54,5 +54,8 @@
|
|
54
54
|
},
|
55
55
|
"trustedDependencies": [
|
56
56
|
"mediasoup"
|
57
|
-
]
|
57
|
+
],
|
58
|
+
"scripts": {
|
59
|
+
"prepublishOnly": "node ./bin/writeVersion.js"
|
60
|
+
}
|
58
61
|
}
|