@modlock/modlock 0.0.0-stage → 0.1.64

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 ADDED
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Christian Stewart <christian@cjs.zip>
4
+ Copyright (c) 2026 Daniel Kapadia <business@ddkesports.com>
5
+ Copyright (c) 2026 Deadworks
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,11 @@
1
- # Temporary Holding Version
1
+ # modlock
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Build, test and publish mods for Deadlock. This package installs the
4
+ `modlock` command line and the TypeScript library mods import:
5
+
6
+ ```sh
7
+ npm install --save-dev @modlock/modlock
8
+ npx modlock new my-mod
9
+ ```
10
+
11
+ See https://github.com/paralin/modlock for the guide.
package/bin/modlock.js ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+ // Runs the modlock command line that npm installed for this system, from the
3
+ // optional dependency @modlock/<platform>-<arch>, with this process's
4
+ // arguments, input and output, and exits as it exits.
5
+ import { spawnSync } from 'node:child_process'
6
+ import { createRequire } from 'node:module'
7
+
8
+ const require = createRequire(import.meta.url)
9
+ const name = `@modlock/${process.platform}-${process.arch}`
10
+ const file = process.platform === 'win32' ? 'modlock.exe' : 'modlock'
11
+
12
+ let binary
13
+ try {
14
+ binary = require.resolve(`${name}/bin/${file}`)
15
+ } catch {
16
+ console.error(
17
+ `modlock has no build for ${process.platform} ${process.arch} installed; ` +
18
+ `install @modlock/modlock again without --omit=optional or --no-optional, ` +
19
+ `or download it from https://github.com/paralin/modlock/releases`,
20
+ )
21
+ process.exit(1)
22
+ }
23
+
24
+ const result = spawnSync(binary, process.argv.slice(2), { stdio: 'inherit' })
25
+ if (result.error) {
26
+ console.error(`modlock could not start ${binary}: ${result.error.message}`)
27
+ process.exit(1)
28
+ }
29
+ if (result.signal) {
30
+ process.kill(process.pid, result.signal)
31
+ }
32
+ process.exit(result.status ?? 1)
package/bits.d.ts ADDED
@@ -0,0 +1,52 @@
1
+ /** Buttons names input bits for blockInput, watchInput and Player.press. */
2
+ export declare const Buttons: {
3
+ /** attack is the primary fire button. */
4
+ readonly attack: 1n;
5
+ /**
6
+ * jump is the jump key, Space by default (IN_MANTLE). Blocking it stops the
7
+ * native jump and mantle; the jumping client still predicts the jump and is
8
+ * corrected.
9
+ */
10
+ readonly jump: bigint;
11
+ /** crouch is the crouch key, Ctrl by default. */
12
+ readonly crouch: bigint;
13
+ /** dash is the dash key, Shift by default. */
14
+ readonly dash: bigint;
15
+ /** use is the interact key. */
16
+ readonly use: bigint;
17
+ /** altFire is the zoom and alternate fire button, right mouse by default. */
18
+ readonly altFire: bigint;
19
+ /** reload is the reload key. */
20
+ readonly reload: bigint;
21
+ /** melee is the light melee key, Q by default. */
22
+ readonly melee: bigint;
23
+ /** ability1 to ability3 are the hero's first three ability keys. */
24
+ readonly ability1: bigint;
25
+ readonly ability2: bigint;
26
+ readonly ability3: bigint;
27
+ /** ultimate is the hero's ultimate ability key, the fourth. */
28
+ readonly ultimate: bigint;
29
+ /** parry is the melee parry button. */
30
+ readonly parry: bigint;
31
+ };
32
+ /** Layers names collision layers for trace, as bits. */
33
+ export declare const Layers: {
34
+ /** solid is the world and solid objects. */
35
+ readonly solid: bigint;
36
+ /** hitbox is the hit boxes of heroes and units. */
37
+ readonly hitbox: bigint;
38
+ /** trigger is invisible volumes that react to touch. */
39
+ readonly trigger: bigint;
40
+ /** playerClip is walls that only stop heroes. */
41
+ readonly playerClip: bigint;
42
+ /** player is player-controlled heroes. */
43
+ readonly player: bigint;
44
+ /** npc is units that are not players. */
45
+ readonly npc: bigint;
46
+ /** staticLevel is the map's built geometry, foliage included. */
47
+ readonly staticLevel: bigint;
48
+ /** hero, trooper and building are those units' bodies. */
49
+ readonly hero: bigint;
50
+ readonly trooper: bigint;
51
+ readonly building: bigint;
52
+ };
package/camera.d.ts ADDED
@@ -0,0 +1,101 @@
1
+ import { type CameraCurve, type Ease } from './curve.js';
2
+ import { type CameraParam, type CameraValue, type Player } from './host.gen.js';
3
+ /**
4
+ * setOrbitCamera gives the player's hero the hideout's orbit camera, zoomed
5
+ * with the wheel, or returns the normal camera and drops the wheel's zoom.
6
+ * The hideout HUD replaces the game HUD while it is on. It returns false when
7
+ * the player has no hero or a call fails.
8
+ */
9
+ export declare function setOrbitCamera(player: Player, enabled: boolean): boolean;
10
+ /** CameraPlayOptions plays curves on a player's camera. */
11
+ export interface CameraPlayOptions {
12
+ /**
13
+ * tracks holds a curve for each param that moves. All tracks start
14
+ * together, so a pull back and a wider view can share one timeline.
15
+ */
16
+ tracks: Partial<Record<CameraParam, CameraCurve>>;
17
+ /** relative adds the curves' values to each param's usual value. */
18
+ relative?: boolean;
19
+ /** delay starts the tracks after this many seconds. */
20
+ delay?: number;
21
+ /** loop plays the tracks again each time they end, until cancelled. */
22
+ loop?: boolean;
23
+ /**
24
+ * rate is how many lerps each second play a span the game's lerp cannot
25
+ * draw; omitted, 30. A straight or bias and gain span is always one lerp.
26
+ */
27
+ rate?: number;
28
+ /** context names the operations; omitted, a name of its own. */
29
+ context?: string;
30
+ /** priority decides between these tracks and another context's moves. */
31
+ priority?: number;
32
+ /** target is the entity handle of the hero whose camera moves. */
33
+ target?: number;
34
+ }
35
+ /** CameraMove is a set of curves playing on a player's camera. */
36
+ export interface CameraMove {
37
+ /** context names the operations. */
38
+ readonly context: string;
39
+ /** duration is how long the move runs, in seconds; Infinity when it loops. */
40
+ readonly duration: number;
41
+ /** cancel ends the move at once and returns each param to its usual value. */
42
+ cancel(): boolean;
43
+ }
44
+ /**
45
+ * playCamera plays a curve for each param of the player's camera, sent at
46
+ * once as lerps queued in one context. Each param returns to its usual value
47
+ * after its curve ends, so a curve ends where the camera rests: at zero when
48
+ * relative. Moves in their own contexts take turns by priority. It returns
49
+ * undefined when the player has no hero or a call fails.
50
+ */
51
+ export declare function playCamera(player: Player, options: CameraPlayOptions): CameraMove | undefined;
52
+ /** CameraPulseOptions moves a param away, holds it and brings it back. */
53
+ export interface CameraPulseOptions {
54
+ /** param is the camera value the pulse moves. */
55
+ param: CameraParam;
56
+ /** by is how far the param moves from its usual value. */
57
+ by: CameraValue;
58
+ /** in is how long the move out takes, in seconds. */
59
+ in: number;
60
+ /** hold is how long the param stays out, in seconds. */
61
+ hold: number;
62
+ /** out is how long the move back takes, in seconds. */
63
+ out: number;
64
+ /** ease shapes the move out; the move back is its mirror. Omitted, linear. */
65
+ ease?: Ease;
66
+ /** context names the pulse's operations; omitted, a name of its own. */
67
+ context?: string;
68
+ /** priority decides between this pulse and another context's moves. */
69
+ priority?: number;
70
+ /** target is the entity handle of the hero whose camera moves. */
71
+ target?: number;
72
+ }
73
+ /**
74
+ * cameraPulse moves one param of the player's camera by an amount, holds it
75
+ * there and brings it back, as an ability pulls the camera back while it
76
+ * charges. It returns undefined when the player has no hero or a call fails.
77
+ */
78
+ export declare function cameraPulse(player: Player, options: CameraPulseOptions): CameraMove | undefined;
79
+ /** CameraShakeOptions shakes a param around its usual value. */
80
+ export interface CameraShakeOptions {
81
+ /** param is the camera value that shakes; omitted, horizontalOffset. */
82
+ param?: CameraParam;
83
+ /** amplitude is how far the first swing reaches. */
84
+ amplitude: number;
85
+ /** duration is how long the shake runs, in seconds. */
86
+ duration: number;
87
+ /** frequency is how many full swings it makes each second; omitted, 8. */
88
+ frequency?: number;
89
+ /** context names the shake's operations; omitted, a name of its own. */
90
+ context?: string;
91
+ /** priority decides between this shake and another context's moves. */
92
+ priority?: number;
93
+ /** target is the entity handle of the hero whose camera moves. */
94
+ target?: number;
95
+ }
96
+ /**
97
+ * cameraShake swings one param of the player's camera to either side of its
98
+ * usual value, smaller each time, and settles back. It returns undefined
99
+ * when the player has no hero or a call fails.
100
+ */
101
+ export declare function cameraShake(player: Player, options: CameraShakeOptions): CameraMove | undefined;
package/cast.d.ts ADDED
@@ -0,0 +1,73 @@
1
+ import { type Connection, type Pawn, type Player } from './host.gen.js';
2
+ /** Want is what a member's hero should be; each field it leaves out is free. */
3
+ export interface Want {
4
+ /**
5
+ * hero seats the member on a hero: its name, such as 'hero_atlas', its id,
6
+ * or 'any' for the hero they have or else a random one.
7
+ */
8
+ readonly hero?: string | number;
9
+ /**
10
+ * team is the team, 2 or 3, to seat the member on. Without one a member
11
+ * keeps their hero's team, or else joins the side with fewer members.
12
+ */
13
+ readonly team?: number;
14
+ /** respawn is the seconds a fallen hero waits before Cast asks for it back. */
15
+ readonly respawn?: number;
16
+ }
17
+ /** CastOptions are a mode's answers to its players coming and going. */
18
+ export interface CastOptions<M> {
19
+ /** join makes the member for a human who finished joining. */
20
+ join(connection: Connection): M;
21
+ /** leave ends a member whose connection left the slot. */
22
+ leave?(member: M, connection: Connection): void;
23
+ /**
24
+ * want is what every member wants, or a function that returns what one
25
+ * member wants now. Cast calls it once per member each frame, so it should
26
+ * return a want it keeps rather than make a new one.
27
+ */
28
+ want?: Want | ((member: M) => Want);
29
+ /**
30
+ * bots says what to do with a bot: skip leaves it out of the cast, join
31
+ * makes it a member as a human is, and kick asks the server to remove it,
32
+ * once per connection. Skip is the default.
33
+ */
34
+ bots?: 'skip' | 'join' | 'kick';
35
+ }
36
+ /** Cast keeps one member of type M per human player. */
37
+ export declare class Cast<M> {
38
+ private readonly options;
39
+ private readonly seats;
40
+ /** kicked holds the connection generation each kicked bot's slot had. */
41
+ private readonly kicked;
42
+ /** reported is the player list the host reported since the last frame. */
43
+ private reported;
44
+ constructor(options: CastOptions<M>);
45
+ /** size is the number of members. */
46
+ get size(): number;
47
+ /** members lists the members in the order they joined. */
48
+ members(): M[];
49
+ /** get returns the member in player's slot, if any. */
50
+ get(player: Player): M | undefined;
51
+ /** pawn returns the member's hero as Cast read it this frame. */
52
+ pawn(player: Player): Pawn | undefined;
53
+ /**
54
+ * frame settles the joins and leaves reported since the last frame, reads
55
+ * each member's hero, and asks the game once a second for any want it does
56
+ * not show yet. seconds is the game clock.
57
+ */
58
+ frame(seconds: number): void;
59
+ /** settle ends the members whose connection left and makes the new ones. */
60
+ private settle;
61
+ /** kick asks the server to remove a bot, once per connection. */
62
+ private kick;
63
+ /** reconcile reads a member's hero and asks for the part of the want it lacks. */
64
+ private reconcile;
65
+ /** wantOf is what the member in seat wants now. */
66
+ private wantOf;
67
+ /** seated reports whether the member's hero shows the hero and team they want. */
68
+ private seated;
69
+ /** seat asks the game to put the member on hero and their team. */
70
+ private seat;
71
+ /** side is the team a member joins: their hero's, or the one with fewer heroes. */
72
+ private side;
73
+ }