@v12-engine/engine 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/dist/abilities/buffs.d.ts +83 -0
- package/dist/abilities/castTold.d.ts +12 -0
- package/dist/abilities/charges.d.ts +28 -0
- package/dist/abilities/dispel.d.ts +9 -0
- package/dist/abilities/effectFields.d.ts +10 -0
- package/dist/abilities/effects/buff.d.ts +8 -0
- package/dist/abilities/effects/core.d.ts +1 -0
- package/dist/abilities/effects/damage.d.ts +1 -0
- package/dist/abilities/effects/heal.d.ts +2 -0
- package/dist/abilities/effects/missile.d.ts +1 -0
- package/dist/abilities/effects/moves.d.ts +11 -0
- package/dist/abilities/effects/passives.d.ts +15 -0
- package/dist/abilities/effects/sight.d.ts +4 -0
- package/dist/abilities/effects/spawn.d.ts +2 -0
- package/dist/abilities/effects/timed.d.ts +4 -0
- package/dist/abilities/effects/trade.d.ts +1 -0
- package/dist/abilities/effects.d.ts +122 -0
- package/dist/abilities/land.d.ts +21 -0
- package/dist/abilities/scaled.d.ts +21 -0
- package/dist/abilities/text.d.ts +113 -0
- package/dist/ai/area.d.ts +53 -0
- package/dist/ai/brain.d.ts +528 -0
- package/dist/ai/budget.d.ts +67 -0
- package/dist/ai/checks.d.ts +115 -0
- package/dist/ai/computer.d.ts +166 -0
- package/dist/ai/defence.d.ts +108 -0
- package/dist/ai/define.d.ts +21 -0
- package/dist/ai/economy.d.ts +129 -0
- package/dist/ai/geometry.d.ts +35 -0
- package/dist/ai/goals.d.ts +360 -0
- package/dist/ai/index.d.ts +38 -0
- package/dist/ai/knowledge.d.ts +418 -0
- package/dist/ai/lanes.d.ts +232 -0
- package/dist/ai/melee/build.d.ts +61 -0
- package/dist/ai/melee/goals.d.ts +299 -0
- package/dist/ai/melee/heroes.d.ts +27 -0
- package/dist/ai/melee/index.d.ts +14 -0
- package/dist/ai/melee/production.d.ts +8 -0
- package/dist/ai/melee/surrender.d.ts +24 -0
- package/dist/ai/micro.d.ts +278 -0
- package/dist/ai/mission.d.ts +195 -0
- package/dist/ai/missionRules.d.ts +18 -0
- package/dist/ai/module.d.ts +116 -0
- package/dist/ai/options.d.ts +61 -0
- package/dist/ai/plans/build.d.ts +280 -0
- package/dist/ai/plans/placement.d.ts +82 -0
- package/dist/ai/plans/plans.d.ts +105 -0
- package/dist/ai/plans/production.d.ts +210 -0
- package/dist/ai/plans/purse.d.ts +73 -0
- package/dist/ai/plans/tech.d.ts +37 -0
- package/dist/ai/profiles.d.ts +204 -0
- package/dist/ai/reach.d.ts +4 -0
- package/dist/ai/report.d.ts +203 -0
- package/dist/ai/roles.d.ts +133 -0
- package/dist/ai/rules.d.ts +288 -0
- package/dist/ai/scouting.d.ts +98 -0
- package/dist/ai/settings.d.ts +73 -0
- package/dist/ai/squads.d.ts +429 -0
- package/dist/ai/strength.d.ts +167 -0
- package/dist/ai/task.d.ts +118 -0
- package/dist/ai/tasks/attack.d.ts +7 -0
- package/dist/ai/tasks/capture.d.ts +21 -0
- package/dist/ai/tasks/creep.d.ts +16 -0
- package/dist/ai/tasks/defend.d.ts +29 -0
- package/dist/ai/tasks/drop.d.ts +34 -0
- package/dist/ai/tasks/escort.d.ts +16 -0
- package/dist/ai/tasks/gather.d.ts +23 -0
- package/dist/ai/tasks/harass.d.ts +7 -0
- package/dist/ai/tasks/hold.d.ts +20 -0
- package/dist/ai/tasks/index.d.ts +32 -0
- package/dist/ai/tasks/move.d.ts +19 -0
- package/dist/ai/tasks/patrol.d.ts +8 -0
- package/dist/ai/tasks/retreat.d.ts +20 -0
- package/dist/ai/tasks/scout.d.ts +29 -0
- package/dist/ai/tasks/shared.d.ts +74 -0
- package/dist/ai/team.d.ts +155 -0
- package/dist/ai/threat.d.ts +91 -0
- package/dist/ai/view.d.ts +366 -0
- package/dist/ai/waves.d.ts +126 -0
- package/dist/ai.js +6239 -0
- package/dist/ai.js.map +1 -0
- package/dist/aiTesting.d.ts +179 -0
- package/dist/areas.d.ts +149 -0
- package/dist/attacks.d.ts +66 -0
- package/dist/attributes.d.ts +66 -0
- package/dist/brain-BvVdUhX8.js +7659 -0
- package/dist/brain-BvVdUhX8.js.map +1 -0
- package/dist/builds-C6LfgvEU.js +460 -0
- package/dist/builds-C6LfgvEU.js.map +1 -0
- package/dist/bytes.d.ts +6 -0
- package/dist/camps.d.ts +95 -0
- package/dist/capture.d.ts +131 -0
- package/dist/cellLayers.d.ts +75 -0
- package/dist/cinematics.d.ts +194 -0
- package/dist/clock.d.ts +32 -0
- package/dist/commands.d.ts +235 -0
- package/dist/components.d.ts +184 -0
- package/dist/computers.d.ts +108 -0
- package/dist/concealment.d.ts +61 -0
- package/dist/coreComponents-syuh2fPG.js +5149 -0
- package/dist/coreComponents-syuh2fPG.js.map +1 -0
- package/dist/coreComponents.d.ts +1 -0
- package/dist/dashing.d.ts +8 -0
- package/dist/debug.d.ts +36 -0
- package/dist/debug.js +3 -0
- package/dist/debugCommands-CzjrSm66.js +14739 -0
- package/dist/debugCommands-CzjrSm66.js.map +1 -0
- package/dist/debugCommands.d.ts +213 -0
- package/dist/debugging.d.ts +10 -0
- package/dist/definitions.d.ts +43 -0
- package/dist/defs.d.ts +1162 -0
- package/dist/denying.d.ts +81 -0
- package/dist/destructibles.d.ts +27 -0
- package/dist/determinism-BCymQwiE.js +518 -0
- package/dist/determinism-BCymQwiE.js.map +1 -0
- package/dist/determinism.d.ts +121 -0
- package/dist/dialog.d.ts +94 -0
- package/dist/effectRefs.d.ts +16 -0
- package/dist/effects.d.ts +80 -0
- package/dist/endings.d.ts +22 -0
- package/dist/engagement.d.ts +108 -0
- package/dist/engineEvents.d.ts +710 -0
- package/dist/entity.d.ts +409 -0
- package/dist/entityIndex.d.ts +50 -0
- package/dist/errors.d.ts +85 -0
- package/dist/events.d.ts +97 -0
- package/dist/exactMath.d.ts +63 -0
- package/dist/features.d.ts +10 -0
- package/dist/fields.d.ts +114 -0
- package/dist/fixture.d.ts +17 -0
- package/dist/fog.d.ts +110 -0
- package/dist/formation.d.ts +111 -0
- package/dist/friendlyFire.d.ts +26 -0
- package/dist/game-DiJEN-Ks.js +5800 -0
- package/dist/game-DiJEN-Ks.js.map +1 -0
- package/dist/game.d.ts +501 -0
- package/dist/gameData.d.ts +325 -0
- package/dist/gameFiles.d.ts +26 -0
- package/dist/gates.d.ts +28 -0
- package/dist/generate.d.ts +403 -0
- package/dist/generateWorker.d.ts +39 -0
- package/dist/grid.d.ts +53 -0
- package/dist/ground.d.ts +127 -0
- package/dist/groundSpeed.d.ts +22 -0
- package/dist/hero.d.ts +177 -0
- package/dist/home.d.ts +14 -0
- package/dist/hooks.d.ts +780 -0
- package/dist/hotReload.d.ts +76 -0
- package/dist/ids.d.ts +26 -0
- package/dist/index.d.ts +227 -0
- package/dist/index.js +4701 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect-D9dWHmZ0.js +491 -0
- package/dist/inspect-D9dWHmZ0.js.map +1 -0
- package/dist/inspect.d.ts +176 -0
- package/dist/inventory.d.ts +18 -0
- package/dist/items.d.ts +91 -0
- package/dist/lanes.d.ts +213 -0
- package/dist/life.d.ts +53 -0
- package/dist/local-Dkovq42k.js +1379 -0
- package/dist/local-Dkovq42k.js.map +1 -0
- package/dist/log.d.ts +140 -0
- package/dist/manaBurn.d.ts +39 -0
- package/dist/map/file.d.ts +114 -0
- package/dist/map/images.d.ts +18 -0
- package/dist/map/look.d.ts +47 -0
- package/dist/map/pathProfile.d.ts +13 -0
- package/dist/map/resize.d.ts +54 -0
- package/dist/map/schema.d.ts +10 -0
- package/dist/map/terrain.d.ts +32 -0
- package/dist/map/types.d.ts +613 -0
- package/dist/map.d.ts +7 -0
- package/dist/mapCheck/cells.d.ts +19 -0
- package/dist/mapCheck/rule.d.ts +30 -0
- package/dist/mapCheck/rules/names.d.ts +3 -0
- package/dist/mapCheck/rules/objects.d.ts +3 -0
- package/dist/mapCheck/rules/paths.d.ts +3 -0
- package/dist/mapCheck/rules/players.d.ts +3 -0
- package/dist/mapCheck/rules/races.d.ts +3 -0
- package/dist/mapCheck/rules/random.d.ts +3 -0
- package/dist/mapCheck/rules/regions.d.ts +3 -0
- package/dist/mapCheck/rules/targets.d.ts +3 -0
- package/dist/mapCheck/rules/walking.d.ts +3 -0
- package/dist/mapCheck.d.ts +23 -0
- package/dist/mapFields.d.ts +364 -0
- package/dist/mapFile.d.ts +23 -0
- package/dist/mapMeasure.d.ts +95 -0
- package/dist/mapMerge.d.ts +19 -0
- package/dist/mapObjectives.d.ts +82 -0
- package/dist/mapObjects.d.ts +1 -0
- package/dist/math.d.ts +44 -0
- package/dist/messages.d.ts +150 -0
- package/dist/missionRules-C-bGxm0Q.js +523 -0
- package/dist/missionRules-C-bGxm0Q.js.map +1 -0
- package/dist/missionRules.d.ts +179 -0
- package/dist/mods.d.ts +146 -0
- package/dist/names.d.ts +93 -0
- package/dist/navigation/agentParams.d.ts +4 -0
- package/dist/navigation/air.d.ts +89 -0
- package/dist/navigation/builds.d.ts +140 -0
- package/dist/navigation/groundAreas.d.ts +23 -0
- package/dist/navigation/navigation.d.ts +127 -0
- package/dist/navigation/recast.d.ts +214 -0
- package/dist/navigation/sidePaths.d.ts +69 -0
- package/dist/navigation/sized.d.ts +1 -0
- package/dist/navigation-worker.js +11 -0
- package/dist/navigation-worker.js.map +1 -0
- package/dist/nearest.d.ts +8 -0
- package/dist/noise.d.ts +12 -0
- package/dist/objectives.d.ts +93 -0
- package/dist/orders/basic.d.ts +96 -0
- package/dist/orders/build.d.ts +91 -0
- package/dist/orders/cast.d.ts +105 -0
- package/dist/orders/facts.d.ts +14 -0
- package/dist/orders/harvest.d.ts +94 -0
- package/dist/orders/idle.d.ts +7 -0
- package/dist/orders/items.d.ts +14 -0
- package/dist/orders/queue.d.ts +24 -0
- package/dist/pack.schema.json +6621 -0
- package/dist/packs/director/index.d.ts +81 -0
- package/dist/packs/heroes/campaign.d.ts +137 -0
- package/dist/packs/heroes/carry.d.ts +59 -0
- package/dist/packs/heroes/commands.d.ts +6 -0
- package/dist/packs/heroes/hire.d.ts +9 -0
- package/dist/packs/heroes/index.d.ts +12 -0
- package/dist/packs/heroes/making.d.ts +16 -0
- package/dist/packs/heroes/respawn.d.ts +42 -0
- package/dist/packs/moba/index.d.ts +34 -0
- package/dist/packs/pack.d.ts +84 -0
- package/dist/packs-g5thvmGn.js +3199 -0
- package/dist/packs-g5thvmGn.js.map +1 -0
- package/dist/packs.d.ts +84 -0
- package/dist/paths.d.ts +51 -0
- package/dist/plain.d.ts +17 -0
- package/dist/player.d.ts +117 -0
- package/dist/portals.d.ts +66 -0
- package/dist/prefabs.d.ts +139 -0
- package/dist/presetBuildings.d.ts +52 -0
- package/dist/presetGround.d.ts +22 -0
- package/dist/profiles-B3NS9jwk.js +335 -0
- package/dist/profiles-B3NS9jwk.js.map +1 -0
- package/dist/races.d.ts +136 -0
- package/dist/randomGroups.d.ts +2 -0
- package/dist/registry.d.ts +464 -0
- package/dist/remains.d.ts +119 -0
- package/dist/replication.d.ts +103 -0
- package/dist/rng.d.ts +17 -0
- package/dist/rules.d.ts +395 -0
- package/dist/rulesCheck.d.ts +37 -0
- package/dist/runes.d.ts +41 -0
- package/dist/save.d.ts +277 -0
- package/dist/scenario.d.ts +56 -0
- package/dist/scheduler.d.ts +67 -0
- package/dist/score.d.ts +306 -0
- package/dist/sequences.d.ts +132 -0
- package/dist/server/doorman.d.ts +21 -0
- package/dist/server/gameServer.d.ts +346 -0
- package/dist/server/index.d.ts +24 -0
- package/dist/server/lobby.d.ts +1 -0
- package/dist/server/log.d.ts +13 -0
- package/dist/server/match.d.ts +24 -0
- package/dist/server/mode.d.ts +168 -0
- package/dist/server/navigation-worker.d.ts +1 -0
- package/dist/server/navigation.d.ts +11 -0
- package/dist/server/ops.d.ts +78 -0
- package/dist/server/packs.d.ts +15 -0
- package/dist/server/ratings.d.ts +62 -0
- package/dist/server/relay.d.ts +34 -0
- package/dist/server/rooms.d.ts +162 -0
- package/dist/server/seat.d.ts +2 -0
- package/dist/server/seatSettings.d.ts +15 -0
- package/dist/server/secret.d.ts +5 -0
- package/dist/server/start.d.ts +54 -0
- package/dist/server/websocket.d.ts +74 -0
- package/dist/server.js +2861 -0
- package/dist/server.js.map +1 -0
- package/dist/session/can.d.ts +20 -0
- package/dist/session/commandReplay.d.ts +92 -0
- package/dist/session/debug.d.ts +65 -0
- package/dist/session/delay.d.ts +15 -0
- package/dist/session/delta.d.ts +98 -0
- package/dist/session/entityState.d.ts +1 -0
- package/dist/session/local.d.ts +214 -0
- package/dist/session/memory.d.ts +27 -0
- package/dist/session/protocol.d.ts +1155 -0
- package/dist/session/remote.d.ts +530 -0
- package/dist/session/replay.d.ts +114 -0
- package/dist/session/seed.d.ts +7 -0
- package/dist/session/share.d.ts +78 -0
- package/dist/session/socket.d.ts +8 -0
- package/dist/session/wire.d.ts +153 -0
- package/dist/session/worker.d.ts +227 -0
- package/dist/shared.d.ts +171 -0
- package/dist/sides.d.ts +75 -0
- package/dist/sight.d.ts +27 -0
- package/dist/simulate-oXBiw1Ff.js +167 -0
- package/dist/simulate-oXBiw1Ff.js.map +1 -0
- package/dist/simulate-worker.d.ts +1 -0
- package/dist/simulate-worker.js +28 -0
- package/dist/simulate-worker.js.map +1 -0
- package/dist/simulate.d.ts +154 -0
- package/dist/smart.d.ts +9 -0
- package/dist/spatial.d.ts +62 -0
- package/dist/spawning.d.ts +33 -0
- package/dist/stances.d.ts +76 -0
- package/dist/start.d.ts +71 -0
- package/dist/stats.d.ts +122 -0
- package/dist/summons.d.ts +63 -0
- package/dist/systems/abilities.d.ts +3 -0
- package/dist/systems/combat.d.ts +71 -0
- package/dist/systems/combatTold.d.ts +14 -0
- package/dist/systems/construction.d.ts +34 -0
- package/dist/systems/economy.d.ts +21 -0
- package/dist/systems/fog.d.ts +19 -0
- package/dist/systems/life.d.ts +3 -0
- package/dist/systems/movement.d.ts +105 -0
- package/dist/systems/orders.d.ts +7 -0
- package/dist/systems/production.d.ts +49 -0
- package/dist/systems/productionQueue.d.ts +40 -0
- package/dist/systems/victory.d.ts +14 -0
- package/dist/talk.d.ts +65 -0
- package/dist/tech.d.ts +62 -0
- package/dist/techTree.d.ts +38 -0
- package/dist/terrain.d.ts +173 -0
- package/dist/terrainSave.d.ts +29 -0
- package/dist/testing.d.ts +58 -0
- package/dist/testing.js +822 -0
- package/dist/testing.js.map +1 -0
- package/dist/tiles.d.ts +34 -0
- package/dist/timers.d.ts +146 -0
- package/dist/tomes.d.ts +48 -0
- package/dist/trade.d.ts +28 -0
- package/dist/transport.d.ts +76 -0
- package/dist/tunables.d.ts +45 -0
- package/dist/upkeep.d.ts +16 -0
- package/dist/veterancy.d.ts +80 -0
- package/dist/walls.d.ts +86 -0
- package/dist/world.d.ts +1118 -0
- package/package.json +80 -5
- package/README.md +0 -3
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import type { Ratings } from './ratings';
|
|
2
|
+
import type { GameListing } from '#engine/session/protocol';
|
|
3
|
+
import type { Logger } from '#engine/log';
|
|
4
|
+
import { type ServerLog } from './log';
|
|
5
|
+
import type { PlayerId } from '#engine/entity';
|
|
6
|
+
import type { RejectedKind } from '#engine/errors';
|
|
7
|
+
import type { GameResult, ServerSeat } from '#engine/game';
|
|
8
|
+
import type { SessionHost } from '#engine/session/remote';
|
|
9
|
+
import type { World } from '#engine/world';
|
|
10
|
+
import type { GameMode } from './mode';
|
|
11
|
+
import { type ServerHttpOptions, type ServerMetrics } from './ops';
|
|
12
|
+
import { type ConnectionSource } from './websocket';
|
|
13
|
+
/** @beta */
|
|
14
|
+
export interface GameServerOptions {
|
|
15
|
+
mode: GameMode;
|
|
16
|
+
/** Port to listen on: 0 for any free one */
|
|
17
|
+
port: number;
|
|
18
|
+
/** Seats the computer plays, whoever joins */
|
|
19
|
+
ai?: PlayerId[];
|
|
20
|
+
/**
|
|
21
|
+
* Where ratings are kept (`Ratings`, `createRatings`): the players' shown in the lobby and the list of games, and
|
|
22
|
+
* moved by every game that ends. A player is who brings the same key (`join`'s `who`), or the `seat` hook's `id`
|
|
23
|
+
*/
|
|
24
|
+
ratings?: Ratings;
|
|
25
|
+
/**
|
|
26
|
+
* The game's settings it starts with (`ServerHooks.settings`), in place of their defaults: the map a room was made
|
|
27
|
+
* for. Only those the game offers, with a value it offers
|
|
28
|
+
*/
|
|
29
|
+
settings?: Record<string, string>;
|
|
30
|
+
/** Starts once every seat for a player is taken, without anyone saying so. Yes when left out */
|
|
31
|
+
autoStart?: boolean;
|
|
32
|
+
/** What `admin` messages must carry: no admin without */
|
|
33
|
+
adminKey?: string;
|
|
34
|
+
/** Where results are kept as files, when the game has no `saveResult` of its own. Kept nowhere without */
|
|
35
|
+
resultsDir?: string;
|
|
36
|
+
/** Commands a second a connection may send, and how many at once: what is over the limit is dropped, and answered refused. 30 and 60 */
|
|
37
|
+
rate?: {
|
|
38
|
+
perSecond: number;
|
|
39
|
+
burst: number;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Messages a second a connection may send besides its commands (`rate`), and how many at once: what is over is
|
|
43
|
+
* dropped, unanswered. A player's screen says it got what it was sent `sendRate` times a second, pings every two
|
|
44
|
+
* seconds and asks for the ground a part at a time. 100 and 200 when left out
|
|
45
|
+
*
|
|
46
|
+
* @beta
|
|
47
|
+
*/
|
|
48
|
+
messageRate?: {
|
|
49
|
+
perSecond: number;
|
|
50
|
+
burst: number;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* The lobby's messages a second a connection may send, and how many at once: a join, a seat, a name, a setting,
|
|
54
|
+
* ready, start, an admin's word. Each is told to everyone (and an admin's key tried): what is over is dropped. 4 and
|
|
55
|
+
* 20 when left out
|
|
56
|
+
*
|
|
57
|
+
* @beta
|
|
58
|
+
*/
|
|
59
|
+
lobbyRate?: {
|
|
60
|
+
perSecond: number;
|
|
61
|
+
burst: number;
|
|
62
|
+
};
|
|
63
|
+
sendRate?: number;
|
|
64
|
+
/** Whether the seated players may use the debug tools (`debug.*` commands): for a game to try things out in. No when left out */
|
|
65
|
+
debug?: boolean;
|
|
66
|
+
/** Whether to compress what goes to players whose browsers can take it (`permessage-deflate`). Yes when left out */
|
|
67
|
+
compress?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Whether those who come once the seats are taken, or who ask to, may watch: they see everything, the whole map
|
|
70
|
+
* without fog and every player's resources, so a player who could watch on the side would know all the other
|
|
71
|
+
* side does. No when left out. `{ key }` lets in who brings the key (`join`'s `key`); a function decides for each
|
|
72
|
+
* who asks
|
|
73
|
+
*/
|
|
74
|
+
watch?: boolean | {
|
|
75
|
+
key: string;
|
|
76
|
+
} | ((request: WatchRequest) => boolean);
|
|
77
|
+
/**
|
|
78
|
+
* Seconds who watches a game being played sees it behind (`delayed`): so that a watcher cannot tell a side where the
|
|
79
|
+
* other is now. None when left out
|
|
80
|
+
*/
|
|
81
|
+
watchDelay?: number;
|
|
82
|
+
/**
|
|
83
|
+
* Who sits where, decided for each who joins: for a login, a matchmaker's ticket, a seat a lobby gave, a name
|
|
84
|
+
* checked. It gets who asks (`SeatRequest`: their address, name, the ticket they brought and the seats free) and
|
|
85
|
+
* answers a seat, the name to use and who they are, or a refusal with a reason; it may be asynchronous, to ask a
|
|
86
|
+
* login service. Without, the first free seat, by the name sent. One who comes back with their seat's token takes it
|
|
87
|
+
* again without being asked about. Watching is still `watch`'s
|
|
88
|
+
*/
|
|
89
|
+
seat?: (request: SeatRequest) => SeatAnswer | Promise<SeatAnswer>;
|
|
90
|
+
/**
|
|
91
|
+
* What becomes of a player whose client sends what an honest one never does (`commandRejected`: a command not what
|
|
92
|
+
* it says it is, another player's unit, a unit there never was): each is counted by seat and said in the log, and
|
|
93
|
+
* this decides, from who it is, why and how many: `ignore`, `warn` (said in the log as a warning), `kick` (let go,
|
|
94
|
+
* their token and id no good any more) or `end` (the game ends, with no winner). Without, a warning each time, and a
|
|
95
|
+
* kick once there are `cheating.kickAfter` within `cheating.seconds`
|
|
96
|
+
*/
|
|
97
|
+
onCheat?: (report: CheatReport) => CheatAnswer | void;
|
|
98
|
+
/** How many refusals in how many seconds the server kicks after when there is no `onCheat`, and `CheatReport.recent` counts over. 20 in 10 */
|
|
99
|
+
cheating?: {
|
|
100
|
+
kickAfter?: number;
|
|
101
|
+
seconds?: number;
|
|
102
|
+
};
|
|
103
|
+
/** Seconds between two lines of where the host's time goes, while a game runs: none without */
|
|
104
|
+
stats?: number;
|
|
105
|
+
/**
|
|
106
|
+
* Whether the navigations of its worlds are built in a worker thread (S37), so that a world being made does not
|
|
107
|
+
* hold up the ticks of the games already running: yes when left out, where the engine is built (in this
|
|
108
|
+
* repository, which runs it as it is written, they are built on the server's thread). Handed to the mode's worlds
|
|
109
|
+
* (`GameMode.makeWorld`'s `context.navigation`): a mode of its own passes it on
|
|
110
|
+
*/
|
|
111
|
+
navigationWorker?: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Seconds a game goes on once every player has left it, for one of them to come back with their token: then it ends,
|
|
114
|
+
* with no winner, and the server goes back to its lobby. 60 when left out; 0 ends it at once, `Infinity` never. A game
|
|
115
|
+
* may end itself sooner or later its own way (`ServerHooks.onPlayerLeave`, `world.winner`)
|
|
116
|
+
*/
|
|
117
|
+
abandonAfter?: number;
|
|
118
|
+
/** Seconds of the game a player may go without saying it got what it was sent, before it is let go (`SessionHostOptions.dropSilentAfter`) */
|
|
119
|
+
dropSilentAfter?: number;
|
|
120
|
+
/** Bytes of what is kept for each player to make a delta against, at most (`SessionHostOptions.keptBytes`): 8 MB when left out */
|
|
121
|
+
keptBytes?: number;
|
|
122
|
+
/** Seconds a connection may say nothing, pings unanswered, before it is closed (`SocketServerOptions.idleTimeout`) */
|
|
123
|
+
idleTimeout?: number;
|
|
124
|
+
/** Bytes waiting to go out to a connection, at most, before it is closed (`SocketServerOptions.maxBuffered`) */
|
|
125
|
+
maxBuffered?: number;
|
|
126
|
+
/**
|
|
127
|
+
* Connections open at once, at most (`SocketServerOptions.maxConnections`): one more is turned away before it is a
|
|
128
|
+
* WebSocket. 1024 when left out
|
|
129
|
+
*
|
|
130
|
+
* @beta
|
|
131
|
+
*/
|
|
132
|
+
maxConnections?: number;
|
|
133
|
+
/**
|
|
134
|
+
* Seconds a connection has to join (`join`) before it is closed: one that never does is told nothing of the lobby
|
|
135
|
+
* meanwhile, and would be kept for good, as a browser answers the pings that let go of those gone (RV38). 10 when
|
|
136
|
+
* left out; `Infinity` waits for ever
|
|
137
|
+
*
|
|
138
|
+
* @beta
|
|
139
|
+
*/
|
|
140
|
+
joinWithin?: number;
|
|
141
|
+
/**
|
|
142
|
+
* Where the server says what it does (seats, games, slow ticks, what went wrong), and its games with it: a logger
|
|
143
|
+
* (`Logger`), whose entries say what they are about by name, or a function that takes each as a line of text.
|
|
144
|
+
* Warnings and errors go to the root logger when left out
|
|
145
|
+
*/
|
|
146
|
+
log?: ServerLog;
|
|
147
|
+
/**
|
|
148
|
+
* The addresses on its HTTP server besides the sockets: one that says whether it is well (`/health`) and one with
|
|
149
|
+
* its numbers (`/metrics`), each to move or leave out, and a key the numbers take. See `ServerHttpOptions`
|
|
150
|
+
*/
|
|
151
|
+
http?: ServerHttpOptions;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Who asks to watch a game (`GameServerOptions.watch`)
|
|
155
|
+
*
|
|
156
|
+
* @beta
|
|
157
|
+
*/
|
|
158
|
+
export interface WatchRequest {
|
|
159
|
+
/** The address they connect from */
|
|
160
|
+
address: string;
|
|
161
|
+
/** The name they gave */
|
|
162
|
+
name?: string;
|
|
163
|
+
/** The key they brought */
|
|
164
|
+
key?: string;
|
|
165
|
+
/** Whether a seat is held from the same address: a player who would watch their own game from the side */
|
|
166
|
+
seated: boolean;
|
|
167
|
+
phase: GameServer['phase'];
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* A player whose client sent what an honest one never does (`GameServerOptions.onCheat`)
|
|
171
|
+
*
|
|
172
|
+
* @beta
|
|
173
|
+
*/
|
|
174
|
+
export interface CheatReport {
|
|
175
|
+
seat: ServerSeat;
|
|
176
|
+
/** The address they connect from */
|
|
177
|
+
address?: string;
|
|
178
|
+
/** Why it was turned away (`commandRejected`'s kind), in words (its reason), and the command's type when it is known */
|
|
179
|
+
kind: RejectedKind;
|
|
180
|
+
reason: string;
|
|
181
|
+
type?: string;
|
|
182
|
+
/** How many there were within `cheating.seconds`, this one with them, and in the whole game */
|
|
183
|
+
recent: number;
|
|
184
|
+
total: number;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* What the server does about it (`GameServerOptions.onCheat`): nothing, a warning in the log, let them go, or end the game
|
|
188
|
+
*
|
|
189
|
+
* @beta
|
|
190
|
+
*/
|
|
191
|
+
export type CheatAnswer = 'ignore' | 'warn' | 'kick' | 'end';
|
|
192
|
+
/**
|
|
193
|
+
* Who asks for a seat (`GameServerOptions.seat`)
|
|
194
|
+
*
|
|
195
|
+
* @beta
|
|
196
|
+
*/
|
|
197
|
+
export interface SeatRequest {
|
|
198
|
+
/** The address they connect from */
|
|
199
|
+
address: string;
|
|
200
|
+
/** The name they gave */
|
|
201
|
+
name?: string;
|
|
202
|
+
/** What they brought to be let in by (`join`'s `ticket`): a login's token, a matchmaker's ticket. Checked by the game, never by the server */
|
|
203
|
+
ticket?: string;
|
|
204
|
+
/** The seats nobody holds now, in the mode's order: none once a game is on, where only coming back is left */
|
|
205
|
+
free: ServerSeat[];
|
|
206
|
+
phase: GameServer['phase'];
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Where who asked sits (`GameServerOptions.seat`): a seat by its player (the first free one when left out), the name to
|
|
210
|
+
* use there (theirs, or the seat's, when left out), and who they are (`id`): one who comes again as the same id gets the
|
|
211
|
+
* seat they hold, from another page or after a drop, and the connection there before is let go. A seat another holds is
|
|
212
|
+
* refused. `{ refuse }` sends them away with the reason, which they are told
|
|
213
|
+
*
|
|
214
|
+
* @beta
|
|
215
|
+
*/
|
|
216
|
+
export type SeatAnswer = {
|
|
217
|
+
player?: PlayerId;
|
|
218
|
+
name?: string;
|
|
219
|
+
id?: string;
|
|
220
|
+
/**
|
|
221
|
+
* Who to rate them as (`ratings`): a login's account. The key they brought (`join`'s `who`) when left out, and
|
|
222
|
+
* `id` without one; a matchmaker's ticket, a new id every game, is no one to rate
|
|
223
|
+
*/
|
|
224
|
+
rate?: string;
|
|
225
|
+
} | {
|
|
226
|
+
refuse: string;
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* A server of a game: its connections, who joins and where they go (`Doorman`), its lobby (`Lobby`: the seats, the
|
|
230
|
+
* settings, when a game starts) and its game while one is on (`Match`)
|
|
231
|
+
*
|
|
232
|
+
* @beta
|
|
233
|
+
*/
|
|
234
|
+
export declare class GameServer {
|
|
235
|
+
private readonly source;
|
|
236
|
+
readonly options: GameServerOptions;
|
|
237
|
+
/** Who builds the navigations of its worlds: its worker thread (`navigationWorker`), or the world's own way */
|
|
238
|
+
private readonly navigation?;
|
|
239
|
+
phase: 'lobby' | 'game' | 'ended';
|
|
240
|
+
private readonly clients;
|
|
241
|
+
/** The keys of those the lobby voted out (`kick`): kept out until the server starts afresh (`reset`) */
|
|
242
|
+
private readonly kickedOut;
|
|
243
|
+
/** Where each who joins goes */
|
|
244
|
+
private readonly doorman;
|
|
245
|
+
/** The seats, the settings, and when a game starts */
|
|
246
|
+
private readonly lobby;
|
|
247
|
+
/** The game on, or the one that ended while its players are still on its screen */
|
|
248
|
+
private match?;
|
|
249
|
+
private constructor();
|
|
250
|
+
/** Starts a server, and resolves once it listens */
|
|
251
|
+
static start(options: GameServerOptions): Promise<GameServer>;
|
|
252
|
+
/**
|
|
253
|
+
* A server whose connections come from elsewhere (`ConnectionSource`): a room of `GameRooms`, those a port it shares
|
|
254
|
+
* hands it. Closing it closes those, and leaves where they come from to whoever owns it
|
|
255
|
+
*/
|
|
256
|
+
static attach(source: ConnectionSource, options: Omit<GameServerOptions, 'port'>): Promise<GameServer>;
|
|
257
|
+
/** Says it is there, and starts a game at once where the computer has every seat */
|
|
258
|
+
private begin;
|
|
259
|
+
/** The game's settings (`ServerHooks.settings`), as chosen in the lobby */
|
|
260
|
+
get settings(): Record<string, string>;
|
|
261
|
+
/** The world of the game on, or of the one that ended while its players are still on its screen */
|
|
262
|
+
get world(): World | undefined;
|
|
263
|
+
/** What sends the game to its players, while there is one */
|
|
264
|
+
get host(): SessionHost | undefined;
|
|
265
|
+
/** Who paused the game: an admin, or a player (with a pause of theirs, for so long at most). Nobody while it runs */
|
|
266
|
+
get pausedBy(): PlayerId | 'admin' | undefined;
|
|
267
|
+
/** When it started, for its uptime */
|
|
268
|
+
private readonly startedAt;
|
|
269
|
+
/** Games played to their end */
|
|
270
|
+
private played;
|
|
271
|
+
/** What the hosts of the games before this one counted: the numbers go on from there */
|
|
272
|
+
private readonly past;
|
|
273
|
+
/** It takes no new games: it is stopping once the running one is over (`close({ drain })`) */
|
|
274
|
+
draining: boolean;
|
|
275
|
+
/** Tells a stop that waits that the running game is over */
|
|
276
|
+
private drained?;
|
|
277
|
+
/** What a list of games says of it (`GET /games`, `GameListing`), as the room it is reached at */
|
|
278
|
+
listing(room: string): GameListing;
|
|
279
|
+
/** How many are connected to it, playing or watching: none, for a room that may be closed */
|
|
280
|
+
get connections(): number;
|
|
281
|
+
/** How many watch */
|
|
282
|
+
private get watching();
|
|
283
|
+
/** Its numbers now: what `/metrics` says (see `ServerMetrics`) */
|
|
284
|
+
metrics(): ServerMetrics;
|
|
285
|
+
/** The game let go of, what its host counted kept for the numbers */
|
|
286
|
+
private dropMatch;
|
|
287
|
+
get port(): number;
|
|
288
|
+
/** Bytes sent to those connected now, as they went over the wire: compressed, where they are */
|
|
289
|
+
get bytesSent(): number;
|
|
290
|
+
/** What the server and its games say: see `GameServerOptions.log` */
|
|
291
|
+
readonly logger: Logger;
|
|
292
|
+
private log;
|
|
293
|
+
private accept;
|
|
294
|
+
private tell;
|
|
295
|
+
/** Tells everyone who joined: never a connection that has not (RV38) */
|
|
296
|
+
private tellAll;
|
|
297
|
+
private receive;
|
|
298
|
+
/** Whether a command of this client's goes in: a bucket that fills at the rate allowed. Why not, when it does not */
|
|
299
|
+
private allow;
|
|
300
|
+
private join;
|
|
301
|
+
/** Takes who joined where the doorman said: a seat, watching, told every seat is taken, or away with why */
|
|
302
|
+
private enter;
|
|
303
|
+
/** A seated player moves to another seat, free, in the lobby */
|
|
304
|
+
private move;
|
|
305
|
+
/** Seats a client, and lets go whoever had the seat before: a player back from another page. A name the game gave goes in any phase */
|
|
306
|
+
private sit;
|
|
307
|
+
/** The game's hooks */
|
|
308
|
+
private get hooks();
|
|
309
|
+
/**
|
|
310
|
+
* Who comes once the seats are taken watches, when the server lets them (`watch`): everything, the whole map without fog, every player's resources. From
|
|
311
|
+
* the side of the world's neutral player, so that nobody's units are theirs; from the first seat's, in a world without one
|
|
312
|
+
*/
|
|
313
|
+
private watch;
|
|
314
|
+
private seatInGame;
|
|
315
|
+
private leave;
|
|
316
|
+
/** Makes the world, seats everyone at it, and runs it */
|
|
317
|
+
startGame(): Promise<void>;
|
|
318
|
+
/** Lets a player go for good: told why, their connection closed, and their token and id no good any more */
|
|
319
|
+
kick(player: PlayerId, reason: string): void;
|
|
320
|
+
/** The game is over: the result told to everyone and kept. The game goes on being shown until everyone has left */
|
|
321
|
+
endGame(): Promise<GameResult | undefined>;
|
|
322
|
+
/**
|
|
323
|
+
* Back to the lobby after a game, with who is still there in their seats: a player of it who joins again ("Again",
|
|
324
|
+
* with their seat's token) takes theirs, the seats of those gone are free
|
|
325
|
+
*/
|
|
326
|
+
private backToLobby;
|
|
327
|
+
/** Back to the lobby, for a new game: the old one gone, every seat free */
|
|
328
|
+
private reset;
|
|
329
|
+
private admin;
|
|
330
|
+
/**
|
|
331
|
+
* Pauses the game for everyone, or lets it go on. A player's pause (`by`, from the `pause` command) ends by itself
|
|
332
|
+
* after its seconds, or when a seated player says `resume`; an admin's, when the admin says so
|
|
333
|
+
*/
|
|
334
|
+
pause(paused: boolean, by?: {
|
|
335
|
+
player: PlayerId;
|
|
336
|
+
seconds: number;
|
|
337
|
+
}): void;
|
|
338
|
+
/**
|
|
339
|
+
* Stops the server: every connection closed. With `drain`, it first takes no new games (its health says so, for a
|
|
340
|
+
* load balancer to send nobody new) and waits for the running one to end, up to so many seconds: then it is ended
|
|
341
|
+
* (no winner, the players told the server stopped) and the server closes
|
|
342
|
+
*/
|
|
343
|
+
close(options?: {
|
|
344
|
+
drain?: number;
|
|
345
|
+
}): Promise<void>;
|
|
346
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@v12-engine/engine/server`: a game server, for Node. `startServer` runs a game for players who connect over WebSockets;
|
|
3
|
+
* the parts it is made of are here too, and a relay for games played in a page and watched from others.
|
|
4
|
+
*
|
|
5
|
+
* Nothing of any one game is in it: a game is handed in
|
|
6
|
+
*/
|
|
7
|
+
export type { StartServerOptions } from './start';
|
|
8
|
+
export { startServer } from './start';
|
|
9
|
+
export type { CheatAnswer, CheatReport, GameServerOptions, SeatAnswer, SeatRequest, WatchRequest } from './gameServer';
|
|
10
|
+
export { GameServer } from './gameServer';
|
|
11
|
+
export type { GameRoomsOptions, RoomKind, RoomOptions } from './rooms';
|
|
12
|
+
export { GameRooms } from './rooms';
|
|
13
|
+
export type { ServerHttpOptions, ServerMetrics } from './ops';
|
|
14
|
+
export type { GameMode, GeneratedModeOptions, MapModeOptions, ModeBrain, ModeSeat } from './mode';
|
|
15
|
+
export { againstTheRest, generatedMode, looksOfSeats, mapMode, PLAYER_COLOR_NAMES, racesOfSeats, seatLooksOf, seatsOf } from './mode';
|
|
16
|
+
export { seatSettingsOf } from './seatSettings';
|
|
17
|
+
export type { RelayOptions } from './relay';
|
|
18
|
+
export type { ServerLog } from './log';
|
|
19
|
+
export { WatchRelay } from './relay';
|
|
20
|
+
export type { Connection, ConnectionSource, SocketServer, SocketServerOptions } from './websocket';
|
|
21
|
+
export { startSocketServer } from './websocket';
|
|
22
|
+
export { nodeNavigationBuilder } from './navigation';
|
|
23
|
+
export { createRatings, type RatedPlayer, type Rating, ratedId, type Ratings } from './ratings';
|
|
24
|
+
export { readPacks, withPackFiles } from './packs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Logger } from '#engine/log';
|
|
2
|
+
/**
|
|
3
|
+
* What a server may be given to log with: a logger, or a function that takes each line as text
|
|
4
|
+
*
|
|
5
|
+
* @beta
|
|
6
|
+
*/
|
|
7
|
+
export type ServerLog = Logger | ((line: string) => void);
|
|
8
|
+
/**
|
|
9
|
+
* The logger of a server, from what it was started with. A logger: one under it. A function of lines: a logger of its
|
|
10
|
+
* own that gives it the server's own entries as their words, and everything else (a game's, a warning) as a whole
|
|
11
|
+
* line. Nothing: one under the root, which says warnings and errors only, as a server said nothing else before
|
|
12
|
+
*/
|
|
13
|
+
export declare function serverLogger(given: ServerLog | undefined): Logger;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { PlayerId } from '#engine/entity';
|
|
2
|
+
import type { ServerSeat } from '#engine/game';
|
|
3
|
+
import { type Logger } from '#engine/log';
|
|
4
|
+
import type { NavigationBuilds } from '#engine/navigation/builds';
|
|
5
|
+
import type { LobbyServerMessage } from '../session/wire';
|
|
6
|
+
import type { GameServerOptions } from './gameServer';
|
|
7
|
+
/** What a game reads of the server it is played on */
|
|
8
|
+
export interface MatchContext {
|
|
9
|
+
readonly options: GameServerOptions;
|
|
10
|
+
readonly logger: Logger;
|
|
11
|
+
readonly seats: readonly Seat[];
|
|
12
|
+
/** Who builds the navigation of its world, where the server says */
|
|
13
|
+
readonly navigation?: NavigationBuilds;
|
|
14
|
+
/** How many watch now: for the line of where the host's time goes */
|
|
15
|
+
readonly watching: number;
|
|
16
|
+
publicSeat(seat: Seat): ServerSeat;
|
|
17
|
+
/** What nobody joined is the computer's: once the world is made, before the computers sit */
|
|
18
|
+
fill(): void;
|
|
19
|
+
/** Tells everyone connected */
|
|
20
|
+
tellAll(message: LobbyServerMessage): void;
|
|
21
|
+
kick(player: PlayerId, reason: string): void;
|
|
22
|
+
/** The game is over: the server ends it (`GameServer.endGame`) */
|
|
23
|
+
end(): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { Logger } from '#engine/log';
|
|
2
|
+
import type { NavigationBuilds } from '#engine/navigation/builds';
|
|
3
|
+
import type { BrainDef } from '#engine/ai/brain';
|
|
4
|
+
import type { AiOptions } from '#engine/ai/options';
|
|
5
|
+
import type { PlayerId } from '#engine/entity';
|
|
6
|
+
import { type GameModule, type ServerHooks } from '#engine/game';
|
|
7
|
+
import { type GeneratorOptions, type MapGenerator } from '#engine/generate';
|
|
8
|
+
import { type GameMap } from '#engine/map';
|
|
9
|
+
import type { Vec2 } from '#engine/math';
|
|
10
|
+
import type { World } from '#engine/world';
|
|
11
|
+
/**
|
|
12
|
+
* A seat a mode has: a player of the world, by default for whoever joins, or for the computer
|
|
13
|
+
*
|
|
14
|
+
* @beta
|
|
15
|
+
*/
|
|
16
|
+
export interface ModeSeat {
|
|
17
|
+
player: PlayerId;
|
|
18
|
+
name: string;
|
|
19
|
+
/** Where it starts, for a computer player to know where its opponents are */
|
|
20
|
+
base?: Vec2;
|
|
21
|
+
/** The team it plays for, shown in the lobby: the map's, for a mode made from a map */
|
|
22
|
+
team?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Settings of the seat that are not the lobby's to choose, by name (`ServerHooks.seatSettings`): the race a map gives
|
|
25
|
+
* its player (`MapPlayer.race`)
|
|
26
|
+
*/
|
|
27
|
+
fixed?: Record<string, string>;
|
|
28
|
+
/**
|
|
29
|
+
* Settings of the seat chosen for it until someone chooses otherwise, by name: its team and its colour on the map
|
|
30
|
+
* (`seatLooksOf`)
|
|
31
|
+
*/
|
|
32
|
+
preset?: Record<string, string>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* What a server runs: a game module, the seats of a game of it, and how its world is made. Each game starts from a
|
|
36
|
+
* world made anew, with the lobby's settings
|
|
37
|
+
*
|
|
38
|
+
* @beta
|
|
39
|
+
*/
|
|
40
|
+
export interface GameMode {
|
|
41
|
+
id: string;
|
|
42
|
+
name: string;
|
|
43
|
+
game: GameModule;
|
|
44
|
+
seats: ModeSeat[];
|
|
45
|
+
/**
|
|
46
|
+
* What can be chosen for each seat in the lobby, in place of what the game offers (`seatSettingsOf(game)`): the races
|
|
47
|
+
* a map offers (`GameMap.races`)
|
|
48
|
+
*/
|
|
49
|
+
seatSettings?: NonNullable<ServerHooks['seatSettings']>;
|
|
50
|
+
/**
|
|
51
|
+
* Makes the world of a game. `context.log` is the server's logger, for the world's own to be made under;
|
|
52
|
+
* `context.seats` what was chosen for each seat in the lobby, by player (`ServerHooks.seatSettings`): a race among
|
|
53
|
+
* them, in a game with races (`seatSettingsOf`), for the world to give each player (`MapWorldOptions.races`);
|
|
54
|
+
* `context.navigation` who builds its navigation (the server's worker thread: `GameServerOptions.navigationWorker`)
|
|
55
|
+
*/
|
|
56
|
+
makeWorld(settings: Record<string, string>, context?: {
|
|
57
|
+
log?: Logger;
|
|
58
|
+
seats?: Readonly<Record<PlayerId, Readonly<Record<string, string>>>>;
|
|
59
|
+
navigation?: NavigationBuilds;
|
|
60
|
+
}): Promise<World>;
|
|
61
|
+
/**
|
|
62
|
+
* How a computer player in a seat plays: with what was chosen for that seat in the lobby (`settings`, from
|
|
63
|
+
* `ServerHooks.seatSettings`: a difficulty, a race). No computer players without
|
|
64
|
+
*/
|
|
65
|
+
ai?(seat: ModeSeat, seats: readonly ModeSeat[], settings: Readonly<Record<string, string>>): AiOptions;
|
|
66
|
+
/**
|
|
67
|
+
* Which brain plays a seat of the computer (`defineBrain`), or its id (one the game lists in `GameModule.brains`, or
|
|
68
|
+
* the engine's `core.melee`): one for every seat, or one by seat, with what was chosen for it in the lobby. The first
|
|
69
|
+
* brain the game lists when left out
|
|
70
|
+
*/
|
|
71
|
+
brain?: ModeBrain;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Which brain plays a seat of the computer on a server (`GameMode.brain`): a brain, its id, or one chosen by seat
|
|
75
|
+
*
|
|
76
|
+
* @beta
|
|
77
|
+
*/
|
|
78
|
+
export type ModeBrain = BrainDef | string | ((seat: ModeSeat, seats: readonly ModeSeat[], settings: Readonly<Record<string, string>>) => BrainDef | string | undefined);
|
|
79
|
+
/**
|
|
80
|
+
* A computer player that goes for everyone else's base: what a seat of the computer does when the server says nothing
|
|
81
|
+
* else. As hard as its seat's `difficulty` says and of the `personality` it says, where the game offers them to choose
|
|
82
|
+
* (`ServerHooks.seatSettings`, `seatSettingsOf`); a name the game does not have is left to the defaults
|
|
83
|
+
*
|
|
84
|
+
* @beta
|
|
85
|
+
*/
|
|
86
|
+
export declare const againstTheRest: (seat: ModeSeat, seats: readonly ModeSeat[], settings?: Readonly<Record<string, string>>) => AiOptions;
|
|
87
|
+
/**
|
|
88
|
+
* The race chosen for each seat in the lobby, by player: none where nobody chose one, or the game has no races
|
|
89
|
+
*
|
|
90
|
+
* @beta
|
|
91
|
+
*/
|
|
92
|
+
export declare function racesOfSeats(seats: Readonly<Record<PlayerId, Readonly<Record<string, string>>>> | undefined): Record<PlayerId, string> | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* The seats a map has room for: a seat for each of its players with a start, the creeps apart
|
|
95
|
+
*
|
|
96
|
+
* @beta
|
|
97
|
+
*/
|
|
98
|
+
export declare const seatsOf: (map: GameMap) => ModeSeat[];
|
|
99
|
+
/**
|
|
100
|
+
* The names of the players' colours (`PLAYER_COLORS`), in their order, as a lobby shows them
|
|
101
|
+
*
|
|
102
|
+
* @beta
|
|
103
|
+
*/
|
|
104
|
+
export declare const PLAYER_COLOR_NAMES: readonly ['Blue', 'Red', 'Teal', 'Purple', 'Yellow', 'Orange', 'Green', 'Pink', 'Grey', 'Light blue', 'Dark green', 'Brown', 'Maroon', 'Navy', 'Turquoise', 'Violet', 'Wheat', 'Peach', 'Mint', 'Lavender', 'Coal', 'Snow', 'Emerald', 'Peanut'];
|
|
105
|
+
/**
|
|
106
|
+
* What a lobby offers to choose for each seat of a map's game beside the game's own: a team, of as many as there are
|
|
107
|
+
* seats, and a colour of the players' (`PLAYER_COLORS`, by `PLAYER_COLOR_NAMES`), no two seats the same. Each seat has
|
|
108
|
+
* the map's until chosen otherwise (`ModeSeat.preset`)
|
|
109
|
+
*
|
|
110
|
+
* @beta
|
|
111
|
+
*/
|
|
112
|
+
export declare function seatLooksOf(seats: readonly ModeSeat[]): NonNullable<ServerHooks['seatSettings']>;
|
|
113
|
+
/**
|
|
114
|
+
* The teams and colours chosen in the lobby (`seatLooksOf`), by player, where they are not the map's: what
|
|
115
|
+
* `MapWorldOptions.teams` and `colors` take
|
|
116
|
+
*
|
|
117
|
+
* @beta
|
|
118
|
+
*/
|
|
119
|
+
export declare function looksOfSeats(seats: Readonly<Record<PlayerId, Readonly<Record<string, string>>>> | undefined, modeSeats: readonly ModeSeat[]): {
|
|
120
|
+
teams?: Record<PlayerId, number>;
|
|
121
|
+
colors?: Record<PlayerId, [number, number, number]>;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* How a mode is made from a map (`mapMode`)
|
|
125
|
+
*
|
|
126
|
+
* @beta
|
|
127
|
+
*/
|
|
128
|
+
export interface MapModeOptions {
|
|
129
|
+
/** The seats a player may take. One for each player of the map with a start when left out */
|
|
130
|
+
seats?: ModeSeat[];
|
|
131
|
+
/** How a computer player in a seat plays: against everyone else's base when left out, `null` for none */
|
|
132
|
+
ai?: GameMode['ai'] | null;
|
|
133
|
+
/** Which brain plays a seat of the computer: the first the game lists when left out */
|
|
134
|
+
brain?: ModeBrain;
|
|
135
|
+
/**
|
|
136
|
+
* What the game does once a world is made from the map, before anyone plays (the game's `start`, as a page or
|
|
137
|
+
* `startServer` runs it): the units at each start, the first wave sent. Nothing when left out
|
|
138
|
+
*/
|
|
139
|
+
start?: (world: World, context: {
|
|
140
|
+
map: GameMap;
|
|
141
|
+
settings: Record<string, string>;
|
|
142
|
+
}) => void | Promise<void>;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* A game on a map of it: a seat for each player the map has a start for, and a world made from the map for each game
|
|
146
|
+
*
|
|
147
|
+
* @beta
|
|
148
|
+
*/
|
|
149
|
+
export declare function mapMode(game: GameModule, map: GameMap, options?: MapModeOptions): GameMode;
|
|
150
|
+
/**
|
|
151
|
+
* How a mode on a generated map is made (`generatedMode`): the generator's options (the seed a new one each time
|
|
152
|
+
* when left out), and what a mode on a map takes
|
|
153
|
+
*
|
|
154
|
+
* @beta
|
|
155
|
+
*/
|
|
156
|
+
export interface GeneratedModeOptions extends Omit<GeneratorOptions, 'seed'>, MapModeOptions {
|
|
157
|
+
seed?: number;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* A game on a map made by a generator (`generateMap`): the map made once, with the seed given or a new one, and a
|
|
161
|
+
* game of it as on any map (`mapMode`): a seat for each start, the world made from it for each game. For a room of a
|
|
162
|
+
* random map (`RoomKind.room` as a function: a new map for each room made)
|
|
163
|
+
*
|
|
164
|
+
* @beta
|
|
165
|
+
*/
|
|
166
|
+
export declare function generatedMode(game: GameModule, generator: MapGenerator, options: GeneratedModeOptions): GameMode & {
|
|
167
|
+
map: GameMap;
|
|
168
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type NavigationBuilder } from '#engine/navigation/builds';
|
|
2
|
+
/**
|
|
3
|
+
* A builder of navigations in a worker thread of this process (S37): what a server builds with, so that the world of
|
|
4
|
+
* one game being made does not hold up the ticks of the others (two seconds for a map of 512 cells a side). One
|
|
5
|
+
* thread, made the first time and kept, which keeps the process alive only while it builds. Nothing where the
|
|
6
|
+
* worker's file is not there: in this repository, which runs the engine as it is written, it builds on the thread
|
|
7
|
+
* that asks
|
|
8
|
+
*
|
|
9
|
+
* @beta
|
|
10
|
+
*/
|
|
11
|
+
export declare function nodeNavigationBuilder(): NavigationBuilder | undefined;
|