spoint 0.1.82 → 0.1.83

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.
Binary file
@@ -2,6 +2,7 @@ export default {
2
2
  port: 3001,
3
3
  tickRate: 128,
4
4
  gravity: [0, -9.81, 0],
5
+ relevanceRadius: 150,
5
6
  movement: {
6
7
  maxSpeed: 4.0,
7
8
  groundAccel: 10.0,
@@ -58,8 +59,19 @@ export default {
58
59
  fadeTime: 0.15
59
60
  },
60
61
  entities: [
61
- { id: 'environment', model: './apps/tps-game/schwust.glb', position: [0, 0, 0], app: 'environment' }
62
+ { id: 'env-schwust', model: './apps/tps-game/schwust.glb', position: [0, 0, 0], app: 'environment' },
63
+ { id: 'env-kosova', model: './apps/maps/aim_kosova_ak47.glb', position: [200, 0, 0], app: 'environment' },
64
+ { id: 'env-sillos', model: './apps/maps/aim_sillos.glb', position: [400, 0, 0], app: 'environment' },
65
+ { id: 'env-dust2', model: './apps/maps/de_dust2_kosovo.glb', position: [600, 0, 0], app: 'environment' },
66
+ { id: 'env-gash', model: './apps/maps/de_gash.glb', position: [800, 0, 0], app: 'environment' }
62
67
  ],
63
- playerModel: './apps/tps-game/cleetus.vrm',
64
- spawnPoint: [-30, 7.6, -30]
68
+ spawnPoints: [
69
+ [-30, 20, -30],
70
+ [212, 20, 12],
71
+ [412, 20, 12],
72
+ [612, 20, 12],
73
+ [812, 20, 12]
74
+ ],
75
+ spawnPoint: [-30, 20, -30],
76
+ playerModel: './apps/tps-game/cleetus.vrm'
65
77
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spoint",
3
- "version": "0.1.82",
3
+ "version": "0.1.83",
4
4
  "description": "Physics and netcode SDK for multiplayer game servers",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -2,12 +2,12 @@ import { WebSocket } from 'ws'
2
2
  import { pack, unpack } from '../protocol/msgpack.js'
3
3
 
4
4
  const CONFIG = {
5
- botCount: 100,
6
- durationMs: 60000,
7
- inputHz: 60,
5
+ botCount: parseInt(process.env.BOT_COUNT || '100'),
6
+ durationMs: parseInt(process.env.BOT_DURATION || '60000'),
7
+ inputHz: parseInt(process.env.BOT_HZ || '60'),
8
8
  serverUrl: process.env.BOT_URL || 'ws://localhost:3001/ws',
9
- batchSize: 10,
10
- batchDelayMs: 200
9
+ batchSize: parseInt(process.env.BOT_BATCH || '20'),
10
+ batchDelayMs: parseInt(process.env.BOT_DELAY || '100')
11
11
  }
12
12
 
13
13
  const MSG_INPUT = 0x11
@@ -33,7 +33,9 @@ export function createServerAPI(ctx) {
33
33
 
34
34
  async loadWorld(worldDef) {
35
35
  ctx.currentWorldDef = worldDef
36
- if (worldDef.spawnPoint) ctx.worldSpawnPoint = [...worldDef.spawnPoint]
36
+ if (worldDef.spawnPoints?.length) ctx.worldSpawnPoints = worldDef.spawnPoints
37
+ else if (worldDef.spawnPoint) ctx.worldSpawnPoints = [worldDef.spawnPoint]
38
+ ctx.worldSpawnPoint = ctx.worldSpawnPoints?.[0] || worldDef.spawnPoint || [0, 5, 0]
37
39
  await appLoader.loadAll()
38
40
  const stage = stageLoader.loadFromDefinition('main', worldDef)
39
41
  return { entities: new Map(), apps: new Map(), count: stage.entityCount }
@@ -5,7 +5,8 @@ export function createConnectionHandlers(ctx) {
5
5
  const { tickSystem, playerManager, networkState, lagCompensator, physicsIntegration, connections, sessions, appLoader, appRuntime, emitter, inspector } = ctx
6
6
 
7
7
  function onClientConnect(transport) {
8
- const sp = [...ctx.worldSpawnPoint]
8
+ const spawnPoints = ctx.worldSpawnPoints || [ctx.worldSpawnPoint]
9
+ const sp = [...spawnPoints[Math.floor(Math.random() * spawnPoints.length)]]
9
10
  const playerConfig = ctx.currentWorldDef?.player || {}
10
11
  const playerId = playerManager.addPlayer(transport, { position: sp, health: playerConfig.health })
11
12
  networkState.addPlayer(playerId, { position: sp })
@@ -5,13 +5,13 @@ import { isUnreliable } from '../protocol/MessageTypes.js'
5
5
  import { applyMovement as _applyMovement, DEFAULT_MOVEMENT as _DEFAULT_MOVEMENT } from '../shared/movement.js'
6
6
 
7
7
  const KEYFRAME_INTERVAL = 128
8
- const SNAP_GROUPS = 4
8
+ const MAX_SENDS_PER_TICK = 25
9
9
 
10
10
  export function createTickHandler(deps) {
11
11
  const {
12
12
  networkState, playerManager, physicsIntegration,
13
13
  lagCompensator, physics, appRuntime, connections,
14
- movement: m = {}, stageLoader, eventLog, _movement
14
+ movement: m = {}, stageLoader, eventLog, _movement, getRelevanceRadius
15
15
  } = deps
16
16
  const applyMovement = _movement?.applyMovement || _applyMovement
17
17
  const DEFAULT_MOVEMENT = _movement?.DEFAULT_MOVEMENT || _DEFAULT_MOVEMENT
@@ -119,12 +119,15 @@ export function createTickHandler(deps) {
119
119
  const playerSnap = networkState.getSnapshot()
120
120
  snapshotSeq++
121
121
  const isKeyframe = snapshotSeq % KEYFRAME_INTERVAL === 0
122
- const curGroup = tick % SNAP_GROUPS
122
+ const snapGroups = Math.max(1, Math.ceil(players.length / MAX_SENDS_PER_TICK))
123
+ const curGroup = tick % snapGroups
123
124
 
124
- if (stageLoader && stageLoader.getActiveStage()) {
125
- const relevanceRadius = stageLoader.getActiveStage().spatial.relevanceRadius
125
+ const relevanceRadius = (stageLoader && stageLoader.getActiveStage())
126
+ ? stageLoader.getActiveStage().spatial.relevanceRadius
127
+ : (getRelevanceRadius ? getRelevanceRadius() : 0)
128
+ if (relevanceRadius > 0) {
126
129
  for (const player of players) {
127
- if (!isKeyframe && player.id % SNAP_GROUPS !== curGroup) continue
130
+ if (!isKeyframe && player.id % snapGroups !== curGroup) continue
128
131
  const entitySnap = appRuntime.getSnapshotForPlayer(player.state.position, relevanceRadius)
129
132
  const combined = { tick: playerSnap.tick, timestamp: playerSnap.timestamp, players: playerSnap.players, entities: entitySnap.entities }
130
133
  const prevMap = (isKeyframe || !playerEntityMaps.has(player.id)) ? new Map() : playerEntityMaps.get(player.id)
@@ -140,7 +143,7 @@ export function createTickHandler(deps) {
140
143
  broadcastEntityMap = entityMap
141
144
  const data = pack({ type: MSG.SNAPSHOT, payload: { seq: snapshotSeq, ...encoded } })
142
145
  for (const player of players) {
143
- if (!isKeyframe && player.id % SNAP_GROUPS !== curGroup) continue
146
+ if (!isKeyframe && player.id % snapGroups !== curGroup) continue
144
147
  connections.sendPacked(player.id, data, snapUnreliable)
145
148
  }
146
149
  }
package/src/sdk/server.js CHANGED
@@ -171,7 +171,8 @@ export async function createServer(config = {}) {
171
171
  connections,
172
172
  movement,
173
173
  stageLoader,
174
- eventLog
174
+ eventLog,
175
+ getRelevanceRadius: () => ctx.currentWorldDef?.relevanceRadius || 0
175
176
  }))
176
177
 
177
178
  const { onClientConnect } = createConnectionHandlers(ctx)