spoint 0.1.491 → 0.1.493
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/README.md +10 -0
- package/apps/matrix-construct-room/index.js +267 -0
- package/apps/world/matrix-construct.js +96 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -165,6 +165,16 @@ npm run bots
|
|
|
165
165
|
|
|
166
166
|
Env vars: `BOT_COUNT`, `BOT_DURATION`, `BOT_HZ`, `BOT_URL`
|
|
167
167
|
|
|
168
|
+
## Documentation
|
|
169
|
+
|
|
170
|
+
- **Getting Started**: `docs/getting-started.md` — Full tutorial, world/app creation, API reference
|
|
171
|
+
- **Quick Reference**: `docs/quick-reference.md` — Cheatsheet for config, physics, client, network messages
|
|
172
|
+
- **Architecture**: `docs/architecture-decisions.md`
|
|
173
|
+
- **Rendering**: `docs/rendering.md`
|
|
174
|
+
- **Editor**: `docs/editor-composing.md`
|
|
175
|
+
- **Publishing**: `docs/publish.md`
|
|
176
|
+
- **Anticheat**: `docs/anticheat.md`
|
|
177
|
+
|
|
168
178
|
## License
|
|
169
179
|
|
|
170
180
|
MIT
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
server: {
|
|
3
|
+
setup(ctx) {
|
|
4
|
+
const roomSize = 30
|
|
5
|
+
const wallHeight = 8
|
|
6
|
+
const wallThickness = 0.5
|
|
7
|
+
|
|
8
|
+
// Floor
|
|
9
|
+
ctx.physics.addColliderFromConfig({
|
|
10
|
+
type: 'box',
|
|
11
|
+
size: [roomSize / 2, wallThickness / 2, roomSize / 2],
|
|
12
|
+
position: [0, -wallThickness / 2, 0],
|
|
13
|
+
mass: 0,
|
|
14
|
+
dynamic: false
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
// Ceiling
|
|
18
|
+
ctx.physics.addColliderFromConfig({
|
|
19
|
+
type: 'box',
|
|
20
|
+
size: [roomSize / 2, wallThickness / 2, roomSize / 2],
|
|
21
|
+
position: [0, wallHeight + wallThickness / 2, 0],
|
|
22
|
+
mass: 0,
|
|
23
|
+
dynamic: false
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// Walls - back (negative Z)
|
|
27
|
+
ctx.physics.addColliderFromConfig({
|
|
28
|
+
type: 'box',
|
|
29
|
+
size: [roomSize / 2, wallHeight / 2, wallThickness / 2],
|
|
30
|
+
position: [0, wallHeight / 2, -roomSize / 2],
|
|
31
|
+
mass: 0,
|
|
32
|
+
dynamic: false
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// Walls - front (positive Z)
|
|
36
|
+
ctx.physics.addColliderFromConfig({
|
|
37
|
+
type: 'box',
|
|
38
|
+
size: [roomSize / 2, wallHeight / 2, wallThickness / 2],
|
|
39
|
+
position: [0, wallHeight / 2, roomSize / 2],
|
|
40
|
+
mass: 0,
|
|
41
|
+
dynamic: false
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// Walls - left (negative X)
|
|
45
|
+
ctx.physics.addColliderFromConfig({
|
|
46
|
+
type: 'box',
|
|
47
|
+
size: [wallThickness / 2, wallHeight / 2, roomSize / 2],
|
|
48
|
+
position: [-roomSize / 2, wallHeight / 2, 0],
|
|
49
|
+
mass: 0,
|
|
50
|
+
dynamic: false
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
// Walls - right (positive X)
|
|
54
|
+
ctx.physics.addColliderFromConfig({
|
|
55
|
+
type: 'box',
|
|
56
|
+
size: [wallThickness / 2, wallHeight / 2, roomSize / 2],
|
|
57
|
+
position: [roomSize / 2, wallHeight / 2, 0],
|
|
58
|
+
mass: 0,
|
|
59
|
+
dynamic: false
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// Store room dimensions for client rendering
|
|
63
|
+
ctx.state.roomSize = roomSize
|
|
64
|
+
ctx.state.wallHeight = wallHeight
|
|
65
|
+
ctx.state.wallThickness = wallThickness
|
|
66
|
+
ctx.state.gridSize = 2
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
client: {
|
|
70
|
+
setup(engine) {
|
|
71
|
+
// Create the white room with grid lines
|
|
72
|
+
this.createConstructRoom(engine)
|
|
73
|
+
},
|
|
74
|
+
render(ctx) {
|
|
75
|
+
return {
|
|
76
|
+
position: [0, 0, 0],
|
|
77
|
+
rotation: [0, 0, 0, 1],
|
|
78
|
+
custom: {
|
|
79
|
+
// Empty - we create the room in setup
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
createConstructRoom(engine) {
|
|
84
|
+
const { THREE, scene } = engine
|
|
85
|
+
const roomSize = 30
|
|
86
|
+
const wallHeight = 8
|
|
87
|
+
const wallThickness = 0.5
|
|
88
|
+
const gridSize = 2
|
|
89
|
+
|
|
90
|
+
// White material with slight emissive glow
|
|
91
|
+
const whiteMaterial = new THREE.MeshStandardMaterial({
|
|
92
|
+
color: 0xffffff,
|
|
93
|
+
roughness: 0.1,
|
|
94
|
+
metalness: 0,
|
|
95
|
+
emissive: 0x222222,
|
|
96
|
+
emissiveIntensity: 0.3,
|
|
97
|
+
side: THREE.DoubleSide
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
// Grid line material - subtle gray
|
|
101
|
+
const gridMaterial = new THREE.MeshStandardMaterial({
|
|
102
|
+
color: 0x888888,
|
|
103
|
+
roughness: 0.3,
|
|
104
|
+
metalness: 0,
|
|
105
|
+
emissive: 0x111111,
|
|
106
|
+
emissiveIntensity: 0.1,
|
|
107
|
+
side: THREE.DoubleSide,
|
|
108
|
+
transparent: true,
|
|
109
|
+
opacity: 0.4
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
// Bright grid line material for main axes
|
|
113
|
+
const axisMaterial = new THREE.MeshStandardMaterial({
|
|
114
|
+
color: 0xcccccc,
|
|
115
|
+
roughness: 0.2,
|
|
116
|
+
metalness: 0,
|
|
117
|
+
emissive: 0x333333,
|
|
118
|
+
emissiveIntensity: 0.2,
|
|
119
|
+
side: THREE.DoubleSide
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
// Floor
|
|
123
|
+
const floorGeo = new THREE.BoxGeometry(roomSize, wallThickness, roomSize)
|
|
124
|
+
const floor = new THREE.Mesh(floorGeo, whiteMaterial)
|
|
125
|
+
floor.position.set(0, -wallThickness / 2, 0)
|
|
126
|
+
floor.receiveShadow = true
|
|
127
|
+
scene.add(floor)
|
|
128
|
+
|
|
129
|
+
// Ceiling
|
|
130
|
+
const ceilGeo = new THREE.BoxGeometry(roomSize, wallThickness, roomSize)
|
|
131
|
+
const ceil = new THREE.Mesh(ceilGeo, whiteMaterial)
|
|
132
|
+
ceil.position.set(0, wallHeight + wallThickness / 2, 0)
|
|
133
|
+
scene.add(ceil)
|
|
134
|
+
|
|
135
|
+
// Walls
|
|
136
|
+
const wallGeo = new THREE.BoxGeometry(roomSize, wallHeight, wallThickness)
|
|
137
|
+
const sideWallGeo = new THREE.BoxGeometry(wallThickness, wallHeight, roomSize)
|
|
138
|
+
|
|
139
|
+
// Back wall (negative Z)
|
|
140
|
+
const backWall = new THREE.Mesh(wallGeo, whiteMaterial)
|
|
141
|
+
backWall.position.set(0, wallHeight / 2, -roomSize / 2)
|
|
142
|
+
backWall.receiveShadow = true
|
|
143
|
+
scene.add(backWall)
|
|
144
|
+
|
|
145
|
+
// Front wall (positive Z)
|
|
146
|
+
const frontWall = new THREE.Mesh(wallGeo, whiteMaterial)
|
|
147
|
+
frontWall.position.set(0, wallHeight / 2, roomSize / 2)
|
|
148
|
+
frontWall.receiveShadow = true
|
|
149
|
+
scene.add(frontWall)
|
|
150
|
+
|
|
151
|
+
// Left wall (negative X)
|
|
152
|
+
const leftWall = new THREE.Mesh(sideWallGeo, whiteMaterial)
|
|
153
|
+
leftWall.position.set(-roomSize / 2, wallHeight / 2, 0)
|
|
154
|
+
leftWall.receiveShadow = true
|
|
155
|
+
scene.add(leftWall)
|
|
156
|
+
|
|
157
|
+
// Right wall (positive X)
|
|
158
|
+
const rightWall = new THREE.Mesh(sideWallGeo, whiteMaterial)
|
|
159
|
+
rightWall.position.set(roomSize / 2, wallHeight / 2, 0)
|
|
160
|
+
rightWall.receiveShadow = true
|
|
161
|
+
scene.add(rightWall)
|
|
162
|
+
|
|
163
|
+
// Grid lines on floor
|
|
164
|
+
const lineThickness = 0.05
|
|
165
|
+
const lineGeo = new THREE.BoxGeometry(roomSize, lineThickness, lineThickness)
|
|
166
|
+
const crossLineGeo = new THREE.BoxGeometry(lineThickness, lineThickness, roomSize)
|
|
167
|
+
|
|
168
|
+
// Floor grid
|
|
169
|
+
for (let i = -roomSize / 2; i <= roomSize / 2; i += gridSize) {
|
|
170
|
+
// X-axis lines
|
|
171
|
+
const lineX = new THREE.Mesh(lineGeo, i === 0 ? axisMaterial : gridMaterial)
|
|
172
|
+
lineX.position.set(0, lineThickness / 2, i)
|
|
173
|
+
scene.add(lineX)
|
|
174
|
+
|
|
175
|
+
// Z-axis lines
|
|
176
|
+
const lineZ = new THREE.Mesh(crossLineGeo, i === 0 ? axisMaterial : gridMaterial)
|
|
177
|
+
lineZ.position.set(i, lineThickness / 2, 0)
|
|
178
|
+
scene.add(lineZ)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Wall grids - back wall
|
|
182
|
+
const wallLineGeoH = new THREE.BoxGeometry(roomSize, lineThickness, lineThickness)
|
|
183
|
+
const wallLineGeoV = new THREE.BoxGeometry(lineThickness, wallHeight, lineThickness)
|
|
184
|
+
|
|
185
|
+
for (let i = -roomSize / 2; i <= roomSize / 2; i += gridSize) {
|
|
186
|
+
// Horizontal lines
|
|
187
|
+
const hLine = new THREE.Mesh(wallLineGeoH, i === 0 ? axisMaterial : gridMaterial)
|
|
188
|
+
hLine.position.set(0, -wallHeight / 2 + i + wallHeight / 2, -roomSize / 2 + wallThickness / 2 + lineThickness)
|
|
189
|
+
scene.add(hLine)
|
|
190
|
+
|
|
191
|
+
// Vertical lines
|
|
192
|
+
const vLine = new THREE.Mesh(wallLineGeoV, i === 0 ? axisMaterial : gridMaterial)
|
|
193
|
+
vLine.position.set(-roomSize / 2 + i, 0, -roomSize / 2 + wallThickness / 2 + lineThickness)
|
|
194
|
+
scene.add(vLine)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Front wall grid
|
|
198
|
+
for (let i = -roomSize / 2; i <= roomSize / 2; i += gridSize) {
|
|
199
|
+
const hLine = new THREE.Mesh(wallLineGeoH, i === 0 ? axisMaterial : gridMaterial)
|
|
200
|
+
hLine.position.set(0, -wallHeight / 2 + i + wallHeight / 2, roomSize / 2 - wallThickness / 2 - lineThickness)
|
|
201
|
+
scene.add(hLine)
|
|
202
|
+
|
|
203
|
+
const vLine = new THREE.Mesh(wallLineGeoV, i === 0 ? axisMaterial : gridMaterial)
|
|
204
|
+
vLine.position.set(-roomSize / 2 + i, 0, roomSize / 2 - wallThickness / 2 - lineThickness)
|
|
205
|
+
scene.add(vLine)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Left wall grid
|
|
209
|
+
const sideWallLineGeoH = new THREE.BoxGeometry(lineThickness, lineThickness, roomSize)
|
|
210
|
+
const sideWallLineGeoV = new THREE.BoxGeometry(lineThickness, wallHeight, lineThickness)
|
|
211
|
+
|
|
212
|
+
for (let i = -roomSize / 2; i <= roomSize / 2; i += gridSize) {
|
|
213
|
+
const hLine = new THREE.Mesh(sideWallLineGeoH, i === 0 ? axisMaterial : gridMaterial)
|
|
214
|
+
hLine.position.set(-roomSize / 2 + wallThickness / 2 + lineThickness, -wallHeight / 2 + i + wallHeight / 2, 0)
|
|
215
|
+
scene.add(hLine)
|
|
216
|
+
|
|
217
|
+
const vLine = new THREE.Mesh(sideWallLineGeoV, i === 0 ? axisMaterial : gridMaterial)
|
|
218
|
+
vLine.position.set(-roomSize / 2 + wallThickness / 2 + lineThickness, 0, -roomSize / 2 + i)
|
|
219
|
+
scene.add(vLine)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Right wall grid
|
|
223
|
+
for (let i = -roomSize / 2; i <= roomSize / 2; i += gridSize) {
|
|
224
|
+
const hLine = new THREE.Mesh(sideWallLineGeoH, i === 0 ? axisMaterial : gridMaterial)
|
|
225
|
+
hLine.position.set(roomSize / 2 - wallThickness / 2 - lineThickness, -wallHeight / 2 + i + wallHeight / 2, 0)
|
|
226
|
+
scene.add(hLine)
|
|
227
|
+
|
|
228
|
+
const vLine = new THREE.Mesh(sideWallLineGeoV, i === 0 ? axisMaterial : gridMaterial)
|
|
229
|
+
vLine.position.set(roomSize / 2 - wallThickness / 2 - lineThickness, 0, -roomSize / 2 + i)
|
|
230
|
+
scene.add(vLine)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Ceiling grid
|
|
234
|
+
for (let i = -roomSize / 2; i <= roomSize / 2; i += gridSize) {
|
|
235
|
+
const lineX = new THREE.Mesh(lineGeo, i === 0 ? axisMaterial : gridMaterial)
|
|
236
|
+
lineX.position.set(0, wallHeight + wallThickness - lineThickness / 2, i)
|
|
237
|
+
scene.add(lineX)
|
|
238
|
+
|
|
239
|
+
const lineZ = new THREE.Mesh(crossLineGeo, i === 0 ? axisMaterial : gridMaterial)
|
|
240
|
+
lineZ.position.set(i, wallHeight + wallThickness - lineThickness / 2, 0)
|
|
241
|
+
scene.add(lineZ)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Add subtle point lights for that construct glow
|
|
245
|
+
const centerLight = new THREE.PointLight(0xffffff, 2, 50)
|
|
246
|
+
centerLight.position.set(0, wallHeight / 2, 0)
|
|
247
|
+
scene.add(centerLight)
|
|
248
|
+
|
|
249
|
+
// Corner accent lights
|
|
250
|
+
const cornerPositions = [
|
|
251
|
+
[-roomSize / 2 + 2, wallHeight - 2, -roomSize / 2 + 2],
|
|
252
|
+
[roomSize / 2 - 2, wallHeight - 2, -roomSize / 2 + 2],
|
|
253
|
+
[-roomSize / 2 + 2, wallHeight - 2, roomSize / 2 - 2],
|
|
254
|
+
[roomSize / 2 - 2, wallHeight - 2, roomSize / 2 - 2]
|
|
255
|
+
]
|
|
256
|
+
|
|
257
|
+
cornerPositions.forEach(pos => {
|
|
258
|
+
const light = new THREE.PointLight(0xffffff, 0.5, 15)
|
|
259
|
+
light.position.set(...pos)
|
|
260
|
+
scene.add(light)
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
// Store reference for cleanup if needed
|
|
264
|
+
this.constructRoom = { floor, ceil, backWall, frontWall, leftWall, rightWall }
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const MATRIX_CONSTRUCT = {
|
|
2
|
+
enabled: false,
|
|
3
|
+
anchorDir: [0, 1, 0],
|
|
4
|
+
radius: 1000,
|
|
5
|
+
reliefScale: 0,
|
|
6
|
+
maxLevel: 0,
|
|
7
|
+
offsetY: 0,
|
|
8
|
+
center: [0, 0],
|
|
9
|
+
physics: { extent: 1, resolution: 1 },
|
|
10
|
+
seed: 0,
|
|
11
|
+
timeOfDay: { serverAuthoritative: true, dayLengthSec: 600, startFraction: 0.5 },
|
|
12
|
+
weather: { serverAuthoritative: true, type: 'clear', intensity: 0, particleCount: 0 },
|
|
13
|
+
vegetation: { enabled: false }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default {
|
|
17
|
+
port: 3001,
|
|
18
|
+
tickRate: 64,
|
|
19
|
+
entityTickRate: 15,
|
|
20
|
+
gravity: [0, -9.81, 0],
|
|
21
|
+
relevanceRadius: 100,
|
|
22
|
+
physicsRadius: 50,
|
|
23
|
+
physicsBodyBudget: 128,
|
|
24
|
+
movement: {
|
|
25
|
+
maxSpeed: 7.0,
|
|
26
|
+
sprintSpeed: 12.0,
|
|
27
|
+
groundAccel: 300.0,
|
|
28
|
+
airAccel: 30.0,
|
|
29
|
+
airMaxSpeed: 0.15,
|
|
30
|
+
airSpeedCap: 16.0,
|
|
31
|
+
friction: 5.0,
|
|
32
|
+
stopSpeed: 1.0,
|
|
33
|
+
jumpImpulse: 5.5,
|
|
34
|
+
collisionRestitution: 0.2,
|
|
35
|
+
collisionDamping: 0.25
|
|
36
|
+
},
|
|
37
|
+
player: {
|
|
38
|
+
health: 100,
|
|
39
|
+
capsuleRadius: 0.28,
|
|
40
|
+
capsuleHalfHeight: 0.63,
|
|
41
|
+
crouchHalfHeight: 0.315,
|
|
42
|
+
mass: 120,
|
|
43
|
+
modelScale: 1.323,
|
|
44
|
+
feetOffset: 0.212
|
|
45
|
+
},
|
|
46
|
+
scene: {
|
|
47
|
+
skyColor: 0xffffff,
|
|
48
|
+
fogColor: 0xffffff,
|
|
49
|
+
fogNear: 500,
|
|
50
|
+
fogFar: 1000,
|
|
51
|
+
ambientColor: 0xffffff,
|
|
52
|
+
ambientIntensity: 0.8,
|
|
53
|
+
sunColor: 0xffffff,
|
|
54
|
+
sunIntensity: 0.5,
|
|
55
|
+
sunPosition: [0, 100, 0],
|
|
56
|
+
fillColor: 0xffffff,
|
|
57
|
+
fillIntensity: 0.5,
|
|
58
|
+
fillPosition: [0, 50, 0],
|
|
59
|
+
shadowMapSize: 1024,
|
|
60
|
+
shadowBias: 0.001,
|
|
61
|
+
shadowNormalBias: 0.1
|
|
62
|
+
},
|
|
63
|
+
camera: {
|
|
64
|
+
fov: 70,
|
|
65
|
+
shoulderOffset: 0.35,
|
|
66
|
+
shoulderOffsets: [0, 0.55, 0.35, 0.1, 0.0],
|
|
67
|
+
headHeight: 1.85,
|
|
68
|
+
zoomStages: [0, 2, 4, 8, 18],
|
|
69
|
+
defaultZoomIndex: 2,
|
|
70
|
+
followSpeed: 12.0,
|
|
71
|
+
snapSpeed: 30.0,
|
|
72
|
+
mouseSensitivity: 0.002,
|
|
73
|
+
pitchRange: [-1.4, 1.4]
|
|
74
|
+
},
|
|
75
|
+
animation: {
|
|
76
|
+
mixerTimeScale: 1.3,
|
|
77
|
+
walkTimeScale: 2.4,
|
|
78
|
+
jogTimeScale: 1.9,
|
|
79
|
+
sprintTimeScale: 1.0,
|
|
80
|
+
fadeTime: 0.15
|
|
81
|
+
},
|
|
82
|
+
trustedApps: ['matrix-construct-room', 'tps-game'],
|
|
83
|
+
placeableApps: [],
|
|
84
|
+
terrain: MATRIX_CONSTRUCT,
|
|
85
|
+
entities: [
|
|
86
|
+
{ id: 'terrain', app: 'terrain', config: MATRIX_CONSTRUCT },
|
|
87
|
+
{ id: 'matrix-room', app: 'matrix-construct-room', position: [0, 0, 0] },
|
|
88
|
+
{ id: 'tps-game', position: [0, 0, 0], app: 'tps-game' }
|
|
89
|
+
],
|
|
90
|
+
spawnPoint: [0, 2, 0],
|
|
91
|
+
playerModel: './apps/tps-game/cleetus.vrm',
|
|
92
|
+
iceServers: [
|
|
93
|
+
{ urls: 'stun:stun.l.google.com:19302' },
|
|
94
|
+
{ urls: 'turn:openrelay.metered.ca:443?transport=tcp', username: 'openrelayproject', credential: 'openrelayproject' }
|
|
95
|
+
]
|
|
96
|
+
}
|