typed-factorio 1.17.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -2,23 +2,20 @@
2
2
 
3
3
  Complete and featureful typescript definitions for the Factorio modding lua api. This is intended to be used with [TypescriptToLua](https://typescripttolua.github.io/).
4
4
 
5
- This project aims to provide type definitions for the Factorio lua API that are as complete as possible. This means no `any`s or `unknown`s, correct nullability, and lots of smart type features. The generator integrates both the Factorio JSON api docs and manually defined additions and overrides.
5
+ This project aims to provide type definitions for the Factorio lua API that are as complete as possible.
6
+ The generator uses both the Factorio api docs JSON and manually defined additions.
6
7
 
7
8
  ## Installation
8
9
 
9
- To use in your TypescriptToLua project:
10
+ To use in your [TypescriptToLua](https://typescripttolua.github.io/) project:
10
11
 
11
- 1. Install this package
12
+ 1. Install this package: `npm install typed-factorio`
13
+ - Note: When types are updated for a new factorio version, you will need to the npm package to get the latest types.
12
14
 
13
- ```
14
- npm install typed-factorio
15
-
16
- or
17
-
18
- yarn add typed-factorio
19
- ```
15
+ 2. Add the types for the [stages](https://lua-api.factorio.com/1.1.89/index.html) used to `tsconfig.json > compilerOptions > types`.
16
+ The available stages are `"typed-factorio/settings"`, `"typed-factorio/prototype"`, and `"typed-factorio/runtime"`.
20
17
 
21
- 2. Add to your `tsconfig.json`:
18
+ Example:
22
19
 
23
20
  ```diff
24
21
  {
@@ -28,84 +25,137 @@ yarn add typed-factorio
28
25
  }
29
26
  ```
30
27
 
31
- This will add the types for the runtime stage to your entire project.
28
+ The stages selected will control the global variables defined.
29
+ It is possible to include multiple stages, but there are some caveats. See [Using multiple stages in the same project](#using-multiple-stages-in-the-same-project) for more info.
32
30
 
33
- Note: When types are updated, or released for a new factorio version, you will need update your package version to get the types.
31
+ ## Usage
34
32
 
35
- ### Settings and data stage
33
+ Global variables will be defined for the stage(s) selected.
36
34
 
37
- There are also definitions for the settings/data stage.
35
+ ### Types
38
36
 
39
- To avoid type conflicts, the global tables for the settings/data stages have to be declared manually where you need them. These types can be imported from `typed-factorio/data/types` or `typed-factorio/settings/types`.
37
+ No matter which stage(s) are selected, _type_ definitions for all stages are available in the modules `"factorio:settings"`, `"factorio:prototype"`, and `"factorio:runtime"`:
38
+ ```ts
39
+ import { BoolSettingDefinition } from "factorio:settings"
40
+ import { ItemPrototype } from "factorio:prototype"
41
+ import { LuaEntity } from "factorio:runtime"
42
+ ```
40
43
 
41
- Example:
44
+ ### Data.extend
45
+ In the settings and prototype stages, the `data` global variable is available.
42
46
 
47
+ For [performance reasons](https://github.com/microsoft/TypeScript/wiki/Performance#preferring-base-types-over-unions), `data.extend()` is only loosely typed.
48
+ To get full type checking, use specific types when adding prototypes:
43
49
  ```ts
44
- import { Data, Mods } from "typed-factorio/data/types"
45
- // or
46
- import { Data, Mods } from "typed-factorio/settings/types"
47
-
48
- declare const data: Data
49
- declare const mods: Mods
50
+ // example: adding an ammo category and item prototype
51
+ import { AmmoCategory, ItemPrototype } from "factorio:prototype"
52
+
53
+ data.extend([
54
+ {
55
+ type: "ammo-category",
56
+ name: "foo",
57
+ } satisfies AmmoCategory,
58
+ {
59
+ type: "item",
60
+ name: "bar",
61
+ // other fields...
62
+ } satisfies ItemPrototype,
63
+ ])
50
64
 
51
- data.extend([{ ... }])
52
65
  ```
53
66
 
54
- There are currently full types for settings stage, but only basic types for the data stage.
55
-
56
67
  ### Factorio lualib modules
57
68
 
58
- Currently, there are types for the following modules:
69
+ There are types for the following [Factorio lualib modules](https://github.com/wube/factorio-data/tree/master/core/lualib):
59
70
 
60
71
  - `util`
61
72
  - `mod-gui`
62
73
 
63
- If you have a need for types to more lualib modules, feel free to open an issue or pull request on GitHub.
74
+ These can be imported as modules:
75
+
76
+ ```ts
77
+ import * as util from "util"
78
+
79
+ const foo = util.copy(bar)
80
+ ```
81
+
82
+ If you wish to see types for more lualib modules, feel free to open an issue or pull request.
64
83
 
65
84
  ### The `global` table
66
85
 
67
- The `global` table is a lua table which can have any shape, so it is not defined in typed-factorio. Instead, you can either:
86
+ The `global` table (in the runtime stage) can have any shape, so it is not defined here. Instead, you can:
68
87
 
69
88
  - add `declare const global: <Your type>` in a `.d.ts` file included in your project, to apply it project-wide, or
70
- - add `declare const global: {...}` to each module/file where needed. This way, you can define only attributes that each module/file specifically uses.
89
+ - add `declare const global: {...}` to each file where needed. This way, you can define only properties that each file specifically uses.
90
+
91
+ ## Using multiple stages in the same project
92
+
93
+ Every Factorio loading stage declares different global variables.
94
+ To add types for multiple Factorio stages, you have a few options, with different pros and cons:
95
+
96
+ 1. Add multiple stages to the "types" field, e.g. `"types": ["typed-factorio/prototype", "typed-factorio/runtime"]`. This will define global variables for _all_ stages selected. With this option, take care that you only use global variables available in the stages the code is run.
97
+ 2. Add _only_ the runtime stage to your types, then manually declare other global variables in other stages, only in files that use them. There are types in `"factorio:common"` to allow this:
98
+ ```ts
99
+ // -- For the prototype stage --
100
+ import { PrototypeData, ActiveMods } from "factorio:common"
101
+ declare const data: PrtotopyeData
102
+ declare const mods: ActiveMods
103
+ // The `settings` global variable is already declared in the runtime stage.
104
+ // However, in the prototype stage _only_ startup settings are available.
105
+ ```
106
+ ```ts
107
+ // -- For the settings stage --
108
+ import { SettingsData, ActiveMods } from "factorio:common"
109
+ declare const settings: SettingsData
110
+ declare const mods: ActiveMods
111
+ ```
112
+ 3. Use a separate `tsconfig.json` for each stage. In each `tsconfig.json`, include only files in that stage in the `"include"` field, e.g. `include: ["src/control.ts"]` for the runtime stage. However, this means you need to run `tstl` separately for each stage, and files shared by multiple stages will be compiled multiple times.
113
+
114
+ ### Additional notes
115
+
116
+ You can also include just `"typed-factorio"` in your `types` field. This will include only global variables available to _all_ stages.
71
117
 
72
118
  ## Type features
73
119
 
74
- ### `nil`
120
+ Here is some info on type features that you may find useful:
75
121
 
76
- `nil` is equivalent to `undefined`.
122
+ ### `nil`
77
123
 
78
- A class attribute is marked as possibly undefined only if the _read_ type is possibly `nil`. For properties where `nil` is not possible on _read_, but possible on _write_, you can write `nil` by using `undefined!` or `myNullableValue!`, e.g. `controlBehavior.parameters = undefined!`.
124
+ The `nil` type is equivalent to `undefined`.
125
+ A class attribute is marked as possibly nil if the _read_ type is possibly `nil`. For properties where `nil` is possible on _write_, but not _read_, you can use `undefined!` or `myNullableValue!`, e.g. `controlBehavior.parameters = undefined!`.
79
126
 
80
127
  ### Parameter Variants
81
128
 
82
- Parameter tables with variants (having "additional attributes can be specified depending on type ...") are defined as a union of all variants. The type for a specific variant is prefixed with the variant name, or "Other" types variants without extra properties (e.g. `AmmoDamageTechnologyModifier`, `OtherTechnologyModifier`).
129
+ Parameter tables with variants (having "additional attributes can be specified depending on type ...") are defined as a union of all variants. The type for a specific variant is prefixed with the variant name (e.g. `AmmoDamageTechnologyModifier`), or prefixed with "Other" for variants without extra properties (e.g. `OtherTechnologyModifier`).
83
130
 
84
131
  ### Events
85
132
 
86
- Event IDs (`defines.events`) carry information about their event type and filters, which is used by the various methods on `script`.
87
- You can pass an event data type parameter to `script.generate_event_name<T>()`, and it will return a `CustomEventId` that holds type info of the event data.
133
+ Event IDs (`defines.events`) hold type info for their corresponding event type and filters, which is used by various methods in `script`.
134
+
135
+ You can pass an event data type parameter to `script.generate_event_name<T>()`, and it will return a `CustomEventId` that includes type info.
88
136
 
89
137
  ### Array-like classes
90
138
 
91
- Classes that have an index operator, a length operator, and have an array-like structure, inherit from `(Readonly)Array` (these are `LuaInventory`, `LuaFluidBox`, `LuaTransportLine`). This allows you to use these classes like arrays, meaning having array methods, and `.length` translating to the lua length operator. However, this also means, like typescript arrays, they are **0-indexed, not 1-indexed**.
139
+ Classes that have an index operator, a length operator, and have an array-like structure subclass from `(Readonly)Array`. These are `LuaInventory`, `LuaFluidBox`, `LuaTransportLine`.
140
+ This allows you to use these classes like arrays, e.g. having array methods and `.length` translating to the lua length operator. However, this means like typescript arrays, they are **0-indexed, not 1-indexed**.
92
141
 
93
142
  ### Read and write variants
94
143
 
95
144
  For concepts that can take a table or array form, the main type (e.g. `MapPosition`) defines the table form, and an `Array` suffix (e.g. `MapPositionArray`) defines the array form.
96
- Concepts in a "read" position will always be in the table form, and concepts in a "write" position may be either in table or array form (e.g. `MapPosition | MapPositionArray`). This is including within other concepts (e.g. in `ScriptArea`, via the `ScriptAreaWrite` type).
145
+ Concepts in a "read" position are in table form, and concepts in a "write" position may be either in table or array form (e.g. `MapPosition | MapPositionArray`).
146
+ Concepts that include table-or-array concepts may have an additional `Write` variant (e.g. `ScriptArea`, `ScriptAreaWrite`).
97
147
 
98
148
  ### Classes with subclasses
99
149
 
100
- Some classes have attributes that are documented to only work for particular subclasses. For these classes, e.g. `LuaEntity`, there are specific types that you can _optionally_ use:
150
+ Some classes have attributes that only work for particular subclasses. For these classes (e.g. `LuaEntity`) there are specific types that you can _optionally_ use:
101
151
 
102
- - a "Base" type, e.g. `BaseEntity`, which only contains members usable by all subclasses
103
- - individual subclass types, e.g. `CraftingMachineEntity`, which extends the base type with members specific to that subclass.
152
+ - A "Base" type (e.g. `BaseEntity`) which contains only members usable by all subclasses
153
+ - Multiple subclass types, e.g. `CraftingMachineEntity`, which extends the base type with members specific to that subclass.
104
154
 
105
- The simple class name, e.g. `LuaEntity`, contains attributes for _all_ subclasses.
155
+ The original class name (e.g. `LuaEntity`) contains attributes for _all_ subclasses.
106
156
 
107
157
  For stricter types, use the `Base` type generally, and the specific subclass type when needed.
108
- You can also create your own type-narrowing functions, like so:
158
+ You can also create your own type-narrowing functions:
109
159
 
110
160
  ```ts
111
161
  function isCraftingMachineEntity(entity: BaseEntity): entity is CraftingMachineEntity {
@@ -115,16 +165,8 @@ function isCraftingMachineEntity(entity: BaseEntity): entity is CraftingMachineE
115
165
 
116
166
  ### LuaGuiElement
117
167
 
118
- `LuaGuiElement` is broken up into a [discriminated union](https://basarat.gitbook.io/typescript/type-system/discriminated-unions), with a separate type for each gui element type. Individual gui element types can be referred to by `<Type>GuiElement`, e.g. `ButtonGuiElement`.
168
+ `LuaGuiElement` is broken up into a [discriminated union](https://basarat.gitbook.io/typescript/type-system/discriminated-unions), for each gui element type. Individual gui element types can be referred to by `<Type>GuiElement`, e.g. `ButtonGuiElement`.
119
169
 
120
- Similarly, the table passed to `LuaGuiElement.add`, referred to as `GuiSpec`, is also broken up into a discriminated union. The type for a specific GuiSpec is `<Type>GuiSpec`, e.g. `ListBoxGuiSpec`. `LuaGuiElement.add` will return the appropriate gui element type corresponding to the GuiSpec type received.
170
+ Similarly, `GuiSpec` (the table passed to `LuaGuiElement.add`), is also a discriminated union. The type for a specific GuiSpec is `<Type>GuiSpec`, e.g. `ListBoxGuiSpec`. `LuaGuiElement.add` will return the appropriate gui element type corresponding to the GuiSpec type passed in.
121
171
 
122
172
  This is done both to provide more accurate types, and for possible integration with [JSX](https://typescripttolua.github.io/docs/jsx/).
123
-
124
- ### Strict index types
125
-
126
- This is a recommended **opt-in** feature. To opt in, add `"typed-factorio/strict-index-types"` to `compilerOptions > types` in your tsconfig.json (in addition to `"typed-factorio/runtime"`).
127
-
128
- Some `uint` types which represent unique indices, e.g. player_index, entity_number, can be "branded" numbers, e.g. `PlayerIndex` and `EntityNumber`. If opted-in, these index-types will be still assignable to `number`, but a plain `number` is not directly assignable to them. This helps ensure their correct use.
129
- You can use these types as keys in an index signature, e.g. `{ [index: PlayerIndex]: "foo" }`.
130
- You can cast "plain" numbers to these types, e.g. `1 as PlayerIndex`, do this with caution.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Provides access to read/edit prototypes.
3
+ *
4
+ * This is only available in the settings or prototype stage.
5
+ * Only prototypes for the current stage can be accessed.
6
+ */
7
+ declare const data: import("factorio:common").DataGlobal
8
+
9
+ /**
10
+ * A table of (mod name -> mod version) for all currently active mods.
11
+ *
12
+ * This global is only available in the settings or prototype stage.
13
+ * In the runtime stage, use `script.active_mods`.
14
+ */
15
+ declare const mods: import("factorio:common").ActiveMods
@@ -0,0 +1,93 @@
1
+ // from https://lua-api.factorio.com/latest/Libraries.html
2
+ // last updated for 1.1.35, 1.1.36, 1.1.37
3
+
4
+ /** @noSelfInFile */
5
+
6
+ /**
7
+ * Factorio provides the {@link https://github.com/pkulchenko/serpent serpent library} as a global variable `serpent` for
8
+ * all mods to use. It allows for easy debugging of tables, because serpent makes it trivial to print them, for example
9
+ * by using `serpent.block()`. However, serpent cannot pretty-print LuaObjects such as LuaEntity. The serpent library
10
+ * was modified to improve determinism, e.g. comments are turned off by default to avoid returning table addresses.
11
+ * Furthermore, two options were added: `refcomment` (true/false/maxlevel) and `tablecomment` (true/false/maxlevel),
12
+ * which allow to separately control the self-reference and table value output of the `comment` option.
13
+ */
14
+ declare namespace serpent {
15
+ /** @noSelf */
16
+ interface Options {
17
+ /** Indentation; triggers long multi-line output. */
18
+ indent: string
19
+ /** Provide stringified value in a comment (up to maxlevel of depth). */
20
+ comment: boolean | number
21
+ /** Sort keys. */
22
+ sortkeys: boolean | ((this: void, keys: any[], table: any) => void)
23
+ /** Force sparse encoding (no nil filling based on #t). */
24
+ sparse: boolean
25
+ /** Remove spaces. */
26
+ compact: boolean
27
+ /** Raise fatal error on non-serializable values. */
28
+ fatal: boolean
29
+ /** Disable bytecode serialization for easy comparison. */
30
+ nocode: boolean
31
+ /** Disable checking numbers against undefined and huge values. */
32
+ nohuge: boolean
33
+ /** Specify max level up to which to expand nested tables. */
34
+ maxlevel: number
35
+ /** Specify max number of elements in a table. */
36
+ maxnum: number
37
+ /** Specify max length for all table elements. */
38
+ maxlength: number
39
+ /**
40
+ * Use __tostring metamethod when serializing tables (v0.29); set to false to disable and serialize the table as is,
41
+ * even when __tostring is present.
42
+ */
43
+ metatostring: boolean
44
+ /**
45
+ * Specify format for numeric values as shortest possible round-trippable double (v0.30). Use "%.16g" for better
46
+ * readability and "%.17g" (the default value) to preserve floating point precision.
47
+ */
48
+ numformat: string
49
+ /** Allows to specify a list of values to ignore (as keys). */
50
+ valignore: string[]
51
+ /** Allows to specify the list of keys to be serialized. Any keys not in this list are not included in final output (as keys). */
52
+ keyallow: string[]
53
+ /** Allows to specity the list of keys to ignore in serialization. */
54
+ keyignore: string[]
55
+ /** Allows to specify a list of value types to ignore (as keys). */
56
+ valtypeignore: string[]
57
+
58
+ /** Provide custom output for tables. */
59
+ custom(opts: {
60
+ /** The name of the current element with '=' or an empty string in case of array index, */
61
+ tag: string
62
+ /** An opening table bracket { and associated indentation and newline (if any), */
63
+ head: string
64
+ /** Table elements concatenated into a string using commas and indentation/newlines (if any), */
65
+ body: string
66
+ /** A closing table bracket } and associated indentation and newline (if any), and */
67
+ tail: string
68
+ /** The current level. */
69
+ level: number
70
+ }): string
71
+
72
+ /** Name; triggers full serialization with self-ref section. */
73
+ name: string
74
+
75
+ refcomment: boolean | number
76
+ tablecomment: boolean | number
77
+ }
78
+
79
+ /** Full serialization; sets name, compact and sparse options; */
80
+ function dump(tbl: unknown, options?: Partial<Options>): string
81
+
82
+ /** Single line pretty printing, no self-ref section; sets sortkeys and comment options; */
83
+ function line(tbl: unknown, options?: Partial<Options>): string
84
+
85
+ /** Multi-line indented pretty printing, no self-ref section; sets indent, sortkeys, and comment options. */
86
+ function block(tbl: unknown, options?: Partial<Options>): string
87
+
88
+ /**
89
+ * For loading serialized fragments, serpent also provides `load` function that adds safety checks and reports an
90
+ * error if there is any executable code in the fragment.
91
+ */
92
+ function load<T>(str: string, options?: { safe?: boolean }): LuaMultiReturn<[true, T] | [false, string]>
93
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Provides access to the current mod settings.
3
+ * This is available in the prototype and runtime stages.
4
+ *
5
+ * In the prototype stage, _only_ the `startup` settings are available.
6
+ * In the runtime stage, this is extended with the full {@link LuaSettings} interface.
7
+ */
8
+ declare const settings: import("factorio:common").SettingsGlobal
@@ -0,0 +1,74 @@
1
+ /** @noResolution */
2
+ declare module "factorio:common" {
3
+ import { ModSetting } from "factorio:runtime"
4
+ import { PrototypeMap as PrototypePrototypeMap } from "factorio:prototype"
5
+ import { PrototypeMap as SettingsPrototypeMap } from "factorio:settings"
6
+ /**
7
+ * A type map of type name -> prototype type.
8
+ *
9
+ * Including the settings/prototype stage in your tsconfig extends this interface.
10
+ */
11
+ export interface GlobalPrototypeMap {}
12
+
13
+ /** Represents any valid prototype. */
14
+ export interface AnyPrototype<M = GlobalPrototypeMap> {
15
+ readonly type: keyof M
16
+ readonly name: string
17
+ }
18
+
19
+ export interface DataGlobal<M = GlobalPrototypeMap> {
20
+ /**
21
+ * A table of the already added prototypes.
22
+ * Indexed by prototype type, then by prototype name.
23
+ */
24
+ readonly raw: {
25
+ readonly [T in keyof M]: {
26
+ readonly [name in string]?: M[T]
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Add additional prototypes.
32
+ */
33
+ extend<P extends AnyPrototype<M>>(prototypes: readonly P[]): void
34
+ }
35
+
36
+ export interface SettingsGlobal {
37
+ readonly startup: {
38
+ readonly [name: string]: ModSetting
39
+ }
40
+ }
41
+
42
+ /** A version string, in the form "major.minor.patch". */
43
+ export type VersionString = `${bigint}.${bigint}.${bigint}`
44
+
45
+ export interface ActiveMods {
46
+ readonly [modName: string]: VersionString | undefined
47
+ }
48
+
49
+ /**
50
+ * Represents a `data` global variable for the prototype stage.
51
+ *
52
+ * If you did _not_ add `"typed-factorio/prototype"` to your tsconfig, you can manually declare this global like so:
53
+ * ```ts
54
+ * import { PrototypeData } from "factorio:prototype"
55
+ * declare const data: PrototypeData
56
+ *
57
+ * data.extend(...)
58
+ * ```
59
+ */
60
+ export type PrototypeData = DataGlobal<PrototypePrototypeMap>
61
+
62
+ /**
63
+ * Represents a `data` global variable for the settings stage.
64
+ *
65
+ * If you did _not_ add `"typed-factorio/settings"` to your tsconfig, you can manually declare this global like so:
66
+ * ```ts
67
+ * import { SettingsData } from "factorio:settings"
68
+ * declare const data: SettingsData
69
+ *
70
+ * data.extend(...)
71
+ * ```
72
+ */
73
+ export type SettingsData = DataGlobal<SettingsPrototypeMap>
74
+ }
package/index.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ /*
2
+ This file includes _only_ types for all factorio stages; it declares the factorio:common, factorio:prototype,
3
+ and factorio:runtime modules.
4
+ */
5
+ /// <reference types="lua-types/5.2" />
6
+
7
+ /// <reference path="common/types.d.ts" />
8
+
9
+ /// <reference path="settings/types.d.ts" />
10
+
11
+ /// <reference path="prototype/generated/prototypes.d.ts" />
12
+ /// <reference path="prototype/generated/types.d.ts" />
13
+
14
+ /// <reference path="runtime/generated/builtin-types.d.ts" />
15
+ /// <reference path="runtime/generated/events.d.ts" />
16
+ /// <reference path="runtime/generated/classes.d.ts" />
17
+ /// <reference path="runtime/generated/concepts.d.ts" />
18
+ /// <reference path="runtime/generated/index-types.d.ts" />
19
+ /// <reference path="runtime/pairs.d.ts" />
20
+
21
+ /// <reference path="lualib/index.d.ts" />
22
+
23
+ // common globals
24
+ /// <reference path="common/serpent.d.ts" />
25
+ /// <reference path="runtime/generated/defines.d.ts" />
26
+ /// <reference path="runtime/generated/global-functions.d.ts" />
@@ -0,0 +1,2 @@
1
+ /// <reference path="util.d.ts" />
2
+ /// <reference path="mod-gui.d.ts" />
@@ -2,6 +2,7 @@
2
2
 
3
3
  /** @noResolution */
4
4
  declare module "mod-gui" {
5
+ import { FlowGuiElement, FrameGuiElement, LuaPlayer } from "factorio:runtime"
5
6
  const button_style: string
6
7
  const frame_style: string
7
8
 
@@ -1,10 +1,27 @@
1
- // "util" is declared only as a module, even though it also modifies global variables
2
- // This is both because of limitations in `declare module`, and that modules are much friendlier to tooling.
3
-
4
1
  /** @noSelfInFile */
5
2
 
6
3
  /** @noResolution */
7
4
  declare module "util" {
5
+ import {
6
+ ColorArray as RColorArray,
7
+ float,
8
+ LuaEntity,
9
+ MapPosition,
10
+ MapPositionArray,
11
+ nil,
12
+ table,
13
+ } from "factorio:runtime"
14
+ import { Color as PrototypeColor, SpriteParameters } from "factorio:prototype"
15
+ import { PrototypeData } from "factorio:common"
16
+
17
+ type ColorArray = PrototypeColor & float[]
18
+ interface ColorTable {
19
+ r: float
20
+ g: float
21
+ b: float
22
+ a?: float
23
+ }
24
+ type AnyColor = PrototypeColor | RColorArray
8
25
  namespace table {
9
26
  function deepcopy<T>(table: T): T
10
27
 
@@ -20,24 +37,23 @@ declare module "util" {
20
37
  function formattime(ticks: number): string
21
38
 
22
39
  /** Supports 'rrggbb', 'rgb', 'rrggbbaa', 'rgba', 'ww', 'w' */
23
- function color(hex: string): Color
40
+ function color(hex: string): ColorTable
41
+
42
+ function premul_color(color: AnyColor): ColorTable
43
+
44
+ function mix_color(c1: AnyColor, c2: AnyColor): ColorArray
24
45
 
25
- function premul_color(color: Color): Color
46
+ function multiply_color(c1: AnyColor, n: number): ColorArray
26
47
 
27
- function mix_color(c1: Color, c2: Color): ColorArray
48
+ function get_color_with_alpha(color: AnyColor, alpha: number, normalized_alpha?: boolean): ColorTable
28
49
 
29
- function multiply_color(c1: Color, n: number): ColorArray
50
+ const direction_vectors: Record<defines.direction, MapPositionArray>
30
51
 
31
52
  function moveposition(
32
53
  position: MapPositionArray,
33
- direction: defines.direction.north | defines.direction.east | defines.direction.south | defines.direction.west,
54
+ direction: defines.direction.north,
34
55
  distance: number
35
56
  ): MapPositionArray
36
- function moveposition(
37
- position: MapPositionArray,
38
- direction: defines.direction,
39
- distance: number
40
- ): MapPositionArray | nil
41
57
 
42
58
  function oppositedirection(direction: defines.direction): defines.direction
43
59
 
@@ -50,22 +66,30 @@ declare module "util" {
50
66
  /** Gets tile position by pixel, hr */
51
67
  function by_pixel_hr(x: number, y: number): MapPositionArray
52
68
 
53
- // omitted: foreach_sprite_definition
69
+ type SpriteWithHrVersion<T = unknown> = T & SpriteParameters & { hr_version?: SpriteParameters & T }
70
+
71
+ function foreach_sprite_definition<T extends SpriteWithHrVersion>(
72
+ sprite: T,
73
+ fun: (sprite: T & T["hr_version"]) => void
74
+ ): void
54
75
 
55
76
  function add_shift(a: MapPositionArray | nil, b: MapPositionArray): MapPositionArray
56
77
  function add_shift(a: MapPositionArray, b: MapPositionArray | nil): MapPositionArray
57
78
  function add_shift(a: MapPositionArray | nil, b: MapPositionArray | nil): MapPositionArray | nil
58
79
 
59
- // omitted: add_shift_offset
80
+ function add_shift_offset<T extends SpriteWithHrVersion<{ shift?: MapPositionArray }>>(
81
+ offset: MapPositionArray | nil,
82
+ sprite: T
83
+ ): T
60
84
 
61
85
  function mul_shift(shift: MapPositionArray, scale: number | nil): MapPositionArray
62
86
  function mul_shift(shift: MapPositionArray | nil, scale: number | nil): MapPositionArray | nil
63
87
 
64
88
  function format_number(amount: number, append_suffix?: boolean): string
65
89
 
66
- function increment(t: number[], index: number, v?: number): void
90
+ function increment(t: number[], luaIndex: number, v?: number): void
67
91
 
68
- // omitted: conditional_return
92
+ // Omitted: conditional_return; it's literally just `a and b`
69
93
 
70
94
  /**
71
95
  * Recursively merges and/or deep-copies tables. Entries in later tables override entries in earlier ones, unless both
@@ -80,37 +104,44 @@ declare module "util" {
80
104
 
81
105
  function split_whitespace(string: string): string[]
82
106
 
83
- // omitted: split, string_starts_with. already TS functions for that
107
+ // Omitted: split, string_starts_with. Use the builtin tstl functions for that.
84
108
 
85
- // omitted: online_players. use game.connected_players
109
+ // Omitted: online_players. Use game.connected_players
110
+ // The lua code actually logs "But why?" if you do this...
86
111
 
87
112
  function clamp(x: number, lower: number, upper: number): number
88
113
 
89
114
  function get_walkable_tile(): string
90
115
 
91
- // omitted: combine_icons
116
+ /**
117
+ * This function takes 2 icons tables, and adds the second to the first, but applies scale, shift and tint to the entire second set.
118
+ * This allows you to manipulate the entire second icons table in the same way as you would manipulate a single icon when adding to the icons table.
119
+ */
120
+ function combine_icons<T extends SpriteParameters>(
121
+ icons1: readonly T[],
122
+ icons2: readonly T[],
123
+ inputs: {
124
+ scale?: number
125
+ shift?: MapPositionArray
126
+ tint?: AnyColor
127
+ }
128
+ ): T[]
129
+
92
130
  // omitted: technology_icons. Create an issue if you really want to see these
93
131
 
94
132
  function parse_energy(energy: string): number
95
133
 
96
- function product_amount(
97
- product: {
98
- probability: number
99
- } & (
100
- | {
101
- amount: number
102
- }
103
- | {
104
- amount_min: number
105
- amount_max: number
106
- }
107
- )
108
- ): number
109
-
110
- function empty_sprite(): object
111
-
112
- // omitted: draw_as_glow
113
- // omitted: remove_tile_references
134
+ function product_amount(product: {
135
+ probability: number
136
+ amount?: number
137
+ amount_min?: number
138
+ amount_max?: number
139
+ }): number
140
+
141
+ function empty_sprite(): SpriteParameters
142
+
143
+ function draw_as_glow<T extends SpriteWithHrVersion>(sprite: T): T
144
+ function remove_tile_references(data: PrototypeData, array_of_tiles_to_remove: readonly string[]): void
114
145
 
115
146
  function remove_from_list<T>(list: T[], value: T): boolean
116
147