@quenty/gameconfig 12.49.2 → 12.51.0

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/CHANGELOG.md CHANGED
@@ -3,6 +3,20 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [12.51.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/gameconfig@12.50.0...@quenty/gameconfig@12.51.0) (2026-07-15)
7
+
8
+ **Note:** Version bump only for package @quenty/gameconfig
9
+
10
+ # [12.50.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/gameconfig@12.49.2...@quenty/gameconfig@12.50.0) (2026-07-14)
11
+
12
+ ### Bug Fixes
13
+
14
+ - **lint:** resolve selene unused-self and Rx shadowing from --!strict conversions ([3f4a085](https://github.com/Quenty/NevermoreEngine/commit/3f4a085911808146f10a2435efbe9e89dff8edff))
15
+
16
+ ### Features
17
+
18
+ - **gameconfig:** convert package to --!strict ([360d65c](https://github.com/Quenty/NevermoreEngine/commit/360d65cc66e9cf4e169af175f1914286ccdb789f))
19
+
6
20
  ## [12.49.2](https://github.com/Quenty/NevermoreEngine/compare/@quenty/gameconfig@12.49.1...@quenty/gameconfig@12.49.2) (2026-06-03)
7
21
 
8
22
  **Note:** Version bump only for package @quenty/gameconfig
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/gameconfig",
3
- "version": "12.49.2",
3
+ "version": "12.51.0",
4
4
  "description": "Configuration service to specify Roblox badges, products, and other specific assets.",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -33,31 +33,31 @@
33
33
  "@quenty/attributeutils": "14.30.1",
34
34
  "@quenty/badgeutils": "10.18.1",
35
35
  "@quenty/baseobject": "10.13.0",
36
- "@quenty/binder": "14.36.1",
36
+ "@quenty/binder": "14.37.0",
37
37
  "@quenty/brio": "14.30.1",
38
38
  "@quenty/canceltoken": "11.19.1",
39
- "@quenty/clienttranslator": "14.37.1",
40
- "@quenty/cmdrservice": "13.45.2",
39
+ "@quenty/clienttranslator": "14.39.0",
40
+ "@quenty/cmdrservice": "13.47.0",
41
41
  "@quenty/enums": "1.3.0",
42
42
  "@quenty/instanceutils": "13.30.1",
43
43
  "@quenty/loader": "10.11.0",
44
44
  "@quenty/maid": "3.9.0",
45
- "@quenty/marketplaceutils": "11.20.1",
45
+ "@quenty/marketplaceutils": "11.21.0",
46
46
  "@quenty/nevermore-test-runner": "1.4.0",
47
- "@quenty/observablecollection": "12.38.1",
48
- "@quenty/playerutils": "8.32.1",
47
+ "@quenty/observablecollection": "12.39.0",
48
+ "@quenty/playerutils": "8.33.0",
49
49
  "@quenty/preferredparentutils": "4.4.2",
50
50
  "@quenty/promise": "10.18.1",
51
51
  "@quenty/pseudolocalize": "3.5.2",
52
52
  "@quenty/remotefunctionutils": "10.18.1",
53
53
  "@quenty/remoting": "12.32.1",
54
54
  "@quenty/rx": "13.28.3",
55
- "@quenty/rxbinderutils": "14.36.1",
55
+ "@quenty/rxbinderutils": "14.37.0",
56
56
  "@quenty/servicebag": "11.18.1",
57
57
  "@quenty/statestack": "14.32.1",
58
58
  "@quenty/string": "3.3.7",
59
59
  "@quenty/table": "3.9.2",
60
60
  "@quenty/valueobject": "13.31.1"
61
61
  },
62
- "gitHead": "1acafc712ce34f5dbaa70bb23b16da95e9cd3f82"
62
+ "gitHead": "d577f1529aa03f5e77534145501e878bde07ca98"
63
63
  }
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class GameConfigCommandServiceClient
4
4
  ]=]
@@ -14,8 +14,21 @@ local ServiceBag = require("ServiceBag")
14
14
  local GameConfigCommandServiceClient = {}
15
15
  GameConfigCommandServiceClient.ServiceName = "GameConfigCommandServiceClient"
16
16
 
17
- function GameConfigCommandServiceClient:Init(serviceBag: ServiceBag.ServiceBag)
18
- assert(not self._serviceBag, "Already initialized")
17
+ export type GameConfigCommandServiceClient = typeof(setmetatable(
18
+ {} :: {
19
+ _serviceBag: ServiceBag.ServiceBag,
20
+ _maid: Maid.Maid,
21
+ _cmdrService: any,
22
+ _gameConfigServiceClient: any,
23
+ },
24
+ {} :: typeof({ __index = GameConfigCommandServiceClient })
25
+ ))
26
+
27
+ function GameConfigCommandServiceClient.Init(
28
+ self: GameConfigCommandServiceClient,
29
+ serviceBag: ServiceBag.ServiceBag
30
+ ): ()
31
+ assert(not (self :: any)._serviceBag, "Already initialized")
19
32
  self._serviceBag = assert(serviceBag, "No serviceBag")
20
33
  self._maid = Maid.new()
21
34
 
@@ -23,11 +36,11 @@ function GameConfigCommandServiceClient:Init(serviceBag: ServiceBag.ServiceBag)
23
36
  self._gameConfigServiceClient = self._serviceBag:GetService(require("GameConfigServiceClient"))
24
37
  end
25
38
 
26
- function GameConfigCommandServiceClient:Start()
39
+ function GameConfigCommandServiceClient.Start(self: GameConfigCommandServiceClient): ()
27
40
  self:_setupCommands()
28
41
  end
29
42
 
30
- function GameConfigCommandServiceClient:_setupCommands()
43
+ function GameConfigCommandServiceClient._setupCommands(self: GameConfigCommandServiceClient): ()
31
44
  local picker = self._gameConfigServiceClient:GetConfigPicker()
32
45
  -- TODO: Determine production vs. staging and set cmdr annotation accordingly.
33
46
 
@@ -37,10 +50,10 @@ function GameConfigCommandServiceClient:_setupCommands()
37
50
  local latestConfig = RxStateStackUtils.createStateStack(picker:ObserveActiveConfigsBrio())
38
51
  self._maid:GiveTask(latestConfig)
39
52
 
40
- self._maid:GiveTask(latestConfig
53
+ self._maid:GiveTask((latestConfig :: any)
41
54
  :Observe()
42
55
  :Pipe({
43
- Rx.switchMap(function(config)
56
+ Rx.switchMap(function(config): any
44
57
  if config then
45
58
  return config:ObserveConfigName()
46
59
  else
@@ -59,7 +72,7 @@ function GameConfigCommandServiceClient:_setupCommands()
59
72
  end)
60
73
  end
61
74
 
62
- function GameConfigCommandServiceClient:Destroy()
75
+ function GameConfigCommandServiceClient.Destroy(self: GameConfigCommandServiceClient): ()
63
76
  self._maid:DoCleaning()
64
77
  end
65
78
 
@@ -26,7 +26,7 @@ export type GameConfigClient =
26
26
  & GameConfigBase.GameConfigBase
27
27
 
28
28
  function GameConfigClient.new(folder: Folder, serviceBag: ServiceBag.ServiceBag): GameConfigClient
29
- local self = setmetatable(GameConfigBase.new(folder), GameConfigClient)
29
+ local self: GameConfigClient = setmetatable(GameConfigBase.new(folder) :: any, GameConfigClient)
30
30
 
31
31
  self._serviceBag = assert(serviceBag, "No serviceBag")
32
32
  self._gameConfigBindersClient = self._serviceBag:GetService(GameConfigBindersClient)
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class GameConfigServiceClient
4
4
  ]=]
@@ -12,8 +12,18 @@ local ServiceBag = require("ServiceBag")
12
12
  local GameConfigServiceClient = {}
13
13
  GameConfigServiceClient.ServiceName = "GameConfigServiceClient"
14
14
 
15
- function GameConfigServiceClient:Init(serviceBag: ServiceBag.ServiceBag)
16
- assert(not self._serviceBag, "Already initialized")
15
+ export type GameConfigServiceClient = typeof(setmetatable(
16
+ {} :: {
17
+ _serviceBag: ServiceBag.ServiceBag,
18
+ _maid: Maid.Maid,
19
+ _binders: any,
20
+ _configPicker: GameConfigPicker.GameConfigPicker,
21
+ },
22
+ {} :: typeof({ __index = GameConfigServiceClient })
23
+ ))
24
+
25
+ function GameConfigServiceClient.Init(self: GameConfigServiceClient, serviceBag: ServiceBag.ServiceBag): ()
26
+ assert(not (self :: any)._serviceBag, "Already initialized")
17
27
  self._serviceBag = assert(serviceBag, "No serviceBag")
18
28
  self._maid = Maid.new()
19
29
 
@@ -30,20 +40,21 @@ function GameConfigServiceClient:Init(serviceBag: ServiceBag.ServiceBag)
30
40
  self._configPicker =
31
41
  self._maid:Add(GameConfigPicker.new(self._serviceBag, self._binders.GameConfig, self._binders.GameConfigAsset))
32
42
 
33
- self._serviceBag:GetService(require("GameConfigDataService")):SetConfigPicker(self._configPicker)
43
+ local dataService = self._serviceBag:GetService(require("GameConfigDataService"));
44
+ (dataService :: any):SetConfigPicker(self._configPicker)
34
45
  end
35
46
 
36
- function GameConfigServiceClient:Start() end
47
+ function GameConfigServiceClient.Start(_self: GameConfigServiceClient): () end
37
48
 
38
49
  --[=[
39
50
  Retrieves the game configuration picker for the config service.
40
51
  @return GameConfigPicker
41
52
  ]=]
42
- function GameConfigServiceClient:GetConfigPicker()
53
+ function GameConfigServiceClient.GetConfigPicker(self: GameConfigServiceClient): GameConfigPicker.GameConfigPicker
43
54
  return self._configPicker
44
55
  end
45
56
 
46
- function GameConfigServiceClient:Destroy()
57
+ function GameConfigServiceClient.Destroy(self: GameConfigServiceClient): ()
47
58
  self._maid:DoCleaning()
48
59
  end
49
60
 
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  Handles cmdr integration
4
4
  @class GameConfigCommandService
@@ -16,19 +16,28 @@ local ServiceBag = require("ServiceBag")
16
16
  local GameConfigCommandService = {}
17
17
  GameConfigCommandService.ServiceName = "GameConfigCommandService"
18
18
 
19
- function GameConfigCommandService:Init(serviceBag: ServiceBag.ServiceBag)
20
- assert(not self._serviceBag, "Already initialized")
19
+ export type GameConfigCommandService = typeof(setmetatable(
20
+ {} :: {
21
+ _serviceBag: ServiceBag.ServiceBag,
22
+ _cmdrService: any,
23
+ _gameConfigService: any,
24
+ },
25
+ {} :: typeof({ __index = GameConfigCommandService })
26
+ ))
27
+
28
+ function GameConfigCommandService.Init(self: GameConfigCommandService, serviceBag: ServiceBag.ServiceBag): ()
29
+ assert(not (self :: any)._serviceBag, "Already initialized")
21
30
  self._serviceBag = assert(serviceBag, "No serviceBag")
22
31
 
23
32
  self._cmdrService = self._serviceBag:GetService(require("CmdrService"))
24
33
  self._gameConfigService = self._serviceBag:GetService(require("GameConfigService"))
25
34
  end
26
35
 
27
- function GameConfigCommandService:Start()
36
+ function GameConfigCommandService.Start(self: GameConfigCommandService): ()
28
37
  self:_registerCommands()
29
38
  end
30
39
 
31
- function GameConfigCommandService:_registerCommands()
40
+ function GameConfigCommandService._registerCommands(self: GameConfigCommandService): ()
32
41
  local configPicker = self._gameConfigService:GetConfigPicker()
33
42
  assert(configPicker, "No configPicker")
34
43
 
@@ -28,7 +28,7 @@ export type GameConfig =
28
28
  & GameConfigBase.GameConfigBase
29
29
 
30
30
  function GameConfig.new(obj: Instance, serviceBag: ServiceBag.ServiceBag): GameConfig
31
- local self: GameConfig = setmetatable(GameConfigBase.new(obj) :: any, GameConfig)
31
+ local self: GameConfig = setmetatable(GameConfigBase.new(obj :: Folder) :: any, GameConfig)
32
32
 
33
33
  self._serviceBag = assert(serviceBag, "No serviceBag")
34
34
  self._gameConfigBindersServer = self._serviceBag:GetService(GameConfigBindersServer)
@@ -51,8 +51,13 @@ function GameConfigService:Init(serviceBag: ServiceBag.ServiceBag)
51
51
  self._binders = self._serviceBag:GetService(require("GameConfigBindersServer"))
52
52
 
53
53
  -- Setup picker
54
- self._configPicker =
55
- self._maid:Add(GameConfigPicker.new(self._serviceBag, self._binders.GameConfig, self._binders.GameConfigAsset))
54
+ self._configPicker = self._maid:Add(
55
+ GameConfigPicker.new(
56
+ self._serviceBag,
57
+ (self._binders :: any).GameConfig,
58
+ (self._binders :: any).GameConfigAsset
59
+ )
60
+ )
56
61
 
57
62
  self._getPreferredParent = PreferredParentUtils.createPreferredParentRetriever(ReplicatedStorage, "GameConfigs")
58
63
 
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class MantleConfigProvider
4
4
  ]=]
@@ -18,17 +18,28 @@ local MantleConfigProvider = {}
18
18
  MantleConfigProvider.ClassName = "MantleConfigProvider"
19
19
  MantleConfigProvider.__index = MantleConfigProvider
20
20
 
21
- function MantleConfigProvider.new(container)
22
- local self = setmetatable({}, MantleConfigProvider)
21
+ export type MantleConfigProvider = typeof(setmetatable(
22
+ {} :: {
23
+ _container: Instance,
24
+ _serviceBag: ServiceBag.ServiceBag,
25
+ _gameConfigService: GameConfigService.GameConfigService,
26
+ _gameConfigBindersServer: any,
27
+ _maid: Maid.Maid,
28
+ },
29
+ {} :: typeof({ __index = MantleConfigProvider })
30
+ ))
31
+
32
+ function MantleConfigProvider.new(container: Instance): MantleConfigProvider
33
+ local self: MantleConfigProvider = setmetatable({} :: any, MantleConfigProvider)
23
34
 
24
35
  self._container = assert(container, "No container")
25
36
 
26
37
  return self
27
38
  end
28
39
 
29
- function MantleConfigProvider:Init(serviceBag: ServiceBag.ServiceBag)
40
+ function MantleConfigProvider.Init(self: MantleConfigProvider, serviceBag: ServiceBag.ServiceBag): ()
30
41
  self._serviceBag = assert(serviceBag, "No serviceBag")
31
- self._gameConfigService = self._serviceBag:GetService(GameConfigService)
42
+ self._gameConfigService = self._serviceBag:GetService(GameConfigService :: any)
32
43
  self._gameConfigBindersServer = self._serviceBag:GetService(GameConfigBindersServer)
33
44
  self._maid = Maid.new()
34
45
 
@@ -39,21 +50,21 @@ function MantleConfigProvider:Init(serviceBag: ServiceBag.ServiceBag)
39
50
  end
40
51
  end
41
52
 
42
- function MantleConfigProvider:_loadConfig(item)
43
- local current
53
+ function MantleConfigProvider._loadConfig(self: MantleConfigProvider, item: ModuleScript): ()
54
+ local current: thread? = nil
44
55
 
45
56
  task.spawn(function()
46
57
  current = coroutine.running()
47
- local data = require(item)
58
+ local data = (require :: any)(item)
48
59
  if type(data) == "table" then
49
60
  self:_parseDataToConfig(data, item.Name)
50
61
  end
51
62
  end)
52
63
 
53
- assert(coroutine.status(current) == "dead", "Loading the mantle config yielded")
64
+ assert(coroutine.status(current :: thread) == "dead", "Loading the mantle config yielded")
54
65
  end
55
66
 
56
- function MantleConfigProvider:_parseDataToConfig(mantleConfigData, name)
67
+ function MantleConfigProvider._parseDataToConfig(self: MantleConfigProvider, mantleConfigData: any, name: string)
57
68
  assert(type(mantleConfigData) == "table", "Bad mantleConfigData")
58
69
 
59
70
  -- Just blind unpack these, we'll error if we can't find these.
@@ -63,7 +74,7 @@ function MantleConfigProvider:_parseDataToConfig(mantleConfigData, name)
63
74
  local gameConfig = GameConfigUtils.create(self._gameConfigBindersServer.GameConfig, gameId)
64
75
  gameConfig.Name = name
65
76
 
66
- local function getIcon(mantleType, assetName)
77
+ local function getIcon(mantleType: string, assetName: string)
67
78
  local entryName = mantleType .. "Icon"
68
79
  local entryKey = entryName .. "_" .. assetName
69
80
 
@@ -74,7 +85,7 @@ function MantleConfigProvider:_parseDataToConfig(mantleConfigData, name)
74
85
  return assetId
75
86
  end
76
87
 
77
- local function addAsset(mantleType, assetType, key, value)
88
+ local function addAsset(mantleType: string, assetType: any, key: string, value: any)
78
89
  local data = value[mantleType]
79
90
 
80
91
  if not data then
@@ -114,7 +125,7 @@ function MantleConfigProvider:_parseDataToConfig(mantleConfigData, name)
114
125
  return gameConfig
115
126
  end
116
127
 
117
- function MantleConfigProvider:Destroy()
128
+ function MantleConfigProvider.Destroy(self: MantleConfigProvider): ()
118
129
  self._maid:DoCleaning()
119
130
  end
120
131
 
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class GameConfigCmdrUtils
4
4
  ]=]
@@ -6,19 +6,24 @@
6
6
  local require = require(script.Parent.loader).load(script)
7
7
 
8
8
  local GameConfigAssetTypes = require("GameConfigAssetTypes")
9
+ local GameConfigPicker = require("GameConfigPicker")
9
10
 
10
11
  local GameConfigCmdrUtils = {}
11
12
 
12
- function GameConfigCmdrUtils.registerAssetTypes(cmdr, configPicker)
13
+ function GameConfigCmdrUtils.registerAssetTypes(cmdr: any, configPicker: GameConfigPicker.GameConfigPicker): ()
13
14
  assert(cmdr, "Bad cmdr")
14
15
  assert(configPicker, "Bad configPicker")
15
16
 
16
- for _, assetType in GameConfigAssetTypes do
17
+ for _, assetType in GameConfigAssetTypes:GetValues() do
17
18
  GameConfigCmdrUtils.registerAssetType(cmdr, configPicker, assetType)
18
19
  end
19
20
  end
20
21
 
21
- function GameConfigCmdrUtils.registerAssetType(cmdr, configPicker, assetType: GameConfigAssetTypes.GameConfigAssetType)
22
+ function GameConfigCmdrUtils.registerAssetType(
23
+ cmdr: any,
24
+ configPicker: GameConfigPicker.GameConfigPicker,
25
+ assetType: GameConfigAssetTypes.GameConfigAssetType
26
+ ): ()
22
27
  assert(cmdr, "Bad cmdr")
23
28
  assert(type(assetType) == "string", "Bad assetType")
24
29
  assert(configPicker, "Bad configPicker")
@@ -54,7 +59,7 @@ function GameConfigCmdrUtils.registerAssetType(cmdr, configPicker, assetType: Ga
54
59
  end
55
60
  return stringified
56
61
  end,
57
- Parse = function(keys)
62
+ Parse = function(keys): number?
58
63
  local value = keys[1]
59
64
  if type(value) == "number" then
60
65
  return value
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class GameConfigAssetUtils
4
4
  ]=]
@@ -7,6 +7,7 @@ local require = require(script.Parent.loader).load(script)
7
7
 
8
8
  local AttributeUtils = require("AttributeUtils")
9
9
  local BadgeUtils = require("BadgeUtils")
10
+ local Binder = require("Binder")
10
11
  local GameConfigAssetConstants = require("GameConfigAssetConstants")
11
12
  local GameConfigAssetTypes = require("GameConfigAssetTypes")
12
13
  local MarketplaceServiceCache = require("MarketplaceServiceCache")
@@ -24,7 +25,7 @@ local GameConfigAssetUtils = {}
24
25
  @return Instance
25
26
  ]=]
26
27
  function GameConfigAssetUtils.create(
27
- binder,
28
+ binder: Binder.Binder<any>, -- GameConfigAssetBase.GameConfigAssetBase (require cycle: GameConfigAssetBase requires this module)
28
29
  assetType: GameConfigAssetTypes.GameConfigAssetType,
29
30
  assetKey: string,
30
31
  assetId: number
@@ -56,7 +57,8 @@ function GameConfigAssetUtils.promiseCloudDataForAssetType(
56
57
  assert(type(assetType) == "string", "Bad assetType")
57
58
  assert(type(assetId) == "number", "Bad assetId")
58
59
 
59
- local marketplaceServiceCache = serviceBag:GetService(MarketplaceServiceCache)
60
+ local marketplaceServiceCache: MarketplaceServiceCache.MarketplaceServiceCache =
61
+ serviceBag:GetService(MarketplaceServiceCache) :: any
60
62
 
61
63
  -- We really hope this stuff is cached
62
64
  if assetType == GameConfigAssetTypes.BADGE then
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class GameConfigBase
4
4
  ]=]
@@ -68,7 +68,7 @@ function GameConfigBase.new(folder: Folder): GameConfigBase
68
68
  self._assetTypeToAssetIdMappings = {}
69
69
 
70
70
  -- Setup assetType mappings to key mapping observations
71
- for _, assetType in GameConfigAssetTypes do
71
+ for _, assetType in GameConfigAssetTypes:GetMap() do
72
72
  self._assetTypeToAssetKeyMappings[assetType] = ObservableMapSet.new()
73
73
  self._maid:GiveTask(self._assetTypeToAssetKeyMappings[assetType])
74
74
 
@@ -226,10 +226,10 @@ function GameConfigBase.InitObservation(self: GameConfigBase)
226
226
  self._setupObservation = true
227
227
 
228
228
  local observables = {}
229
- for _, assetType in GameConfigAssetTypes do
229
+ for _, assetType in GameConfigAssetTypes:GetMap() do
230
230
  table.insert(
231
231
  observables,
232
- self:_observeAssetFolderBrio(assetType):Pipe({
232
+ self:_observeAssetFolderBrio(assetType :: GameConfigAssetType):Pipe({
233
233
  RxBrioUtils.switchMapBrio(function(folder)
234
234
  return RxBinderUtils.observeBoundChildClassBrio(self:GetGameConfigAssetBinder(), folder)
235
235
  end),
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  @class GameConfigUtils
4
4
  ]=]
@@ -16,7 +16,7 @@ local RxInstanceUtils = require("RxInstanceUtils")
16
16
 
17
17
  local GameConfigUtils = {}
18
18
 
19
- function GameConfigUtils.create(binder, gameId: number): Folder
19
+ function GameConfigUtils.create(binder: Binder.Binder<any>, gameId: number): Folder
20
20
  assert(Binder.isBinder(binder), "Bad binder")
21
21
  assert(type(gameId) == "number", "Bad gameId")
22
22
 
@@ -25,7 +25,7 @@ function GameConfigUtils.create(binder, gameId: number): Folder
25
25
 
26
26
  AttributeUtils.initAttribute(config, GameConfigConstants.GAME_ID_ATTRIBUTE, gameId)
27
27
 
28
- for _, assetType in GameConfigAssetTypes do
28
+ for _, assetType in GameConfigAssetTypes :: any do
29
29
  GameConfigUtils.getOrCreateAssetFolder(config, assetType)
30
30
  end
31
31
 
@@ -45,12 +45,13 @@ function GameConfigUtils.getOrCreateAssetFolder(
45
45
 
46
46
  local folder = config:FindFirstChild(folderName)
47
47
  if not folder then
48
- folder = Instance.new("Folder")
49
- folder.Name = folderName
50
- folder.Parent = config
48
+ local newFolder = Instance.new("Folder")
49
+ newFolder.Name = folderName
50
+ newFolder.Parent = config
51
+ folder = newFolder
51
52
  end
52
53
 
53
- return folder
54
+ return folder :: Folder
54
55
  end
55
56
 
56
57
  function GameConfigUtils.observeAssetFolderBrio(
@@ -62,7 +63,9 @@ function GameConfigUtils.observeAssetFolderBrio(
62
63
 
63
64
  local folderName = GameConfigAssetTypeUtils.getPlural(assetType)
64
65
 
65
- return RxInstanceUtils.observeLastNamedChildBrio(config, "Folder", folderName)
66
+ return (
67
+ RxInstanceUtils.observeLastNamedChildBrio(config, "Folder", folderName) :: any
68
+ ) :: Observable.Observable<Brio.Brio<Folder>>
66
69
  end
67
70
 
68
71
  return GameConfigUtils
@@ -1,4 +1,4 @@
1
- --!nonstrict
1
+ --!strict
2
2
  --[=[
3
3
  Provides an interface to query game configurations from assets in the world.
4
4
  @class GameConfigPicker
@@ -7,8 +7,8 @@
7
7
  local require = require(script.Parent.loader).load(script)
8
8
 
9
9
  local BaseObject = require("BaseObject")
10
+ local Binder = require("Binder")
10
11
  local Brio = require("Brio")
11
- local GameConfigAssetBase = require("GameConfigAssetBase")
12
12
  local GameConfigAssetTypeUtils = require("GameConfigAssetTypeUtils")
13
13
  local GameConfigAssetTypes = require("GameConfigAssetTypes")
14
14
  local GameConfigAssetUtils = require("GameConfigAssetUtils")
@@ -27,12 +27,14 @@ export type GameConfigPicker =
27
27
  typeof(setmetatable(
28
28
  {} :: {
29
29
  _serviceBag: ServiceBag.ServiceBag,
30
+ _gameConfigBinder: Binder.Binder<any>,
31
+ _gameConfigAssetBinder: Binder.Binder<any>,
32
+ _gameIdToConfigSet: any,
30
33
  },
31
34
  {} :: typeof({ __index = GameConfigPicker })
32
35
  ))
33
36
  & BaseObject.BaseObject
34
- type GameConfigAssetType = GameConfigAssetTypes.GameConfigAssetType
35
- type GameConfigAssetBase = GameConfigAssetBase.GameConfigAssetBase
37
+ type GameConfigAssetBase = any -- GameConfigAssetBase.GameConfigAssetBase (heavy metatable type; old solver overflows when referenced alongside this file's self-type)
36
38
 
37
39
  --[=[
38
40
  Constructs a new game config picker. Should be gotten by [GameConfigService].
@@ -44,10 +46,10 @@ type GameConfigAssetBase = GameConfigAssetBase.GameConfigAssetBase
44
46
  ]=]
45
47
  function GameConfigPicker.new(
46
48
  serviceBag: ServiceBag.ServiceBag,
47
- gameConfigBinder,
48
- gameConfigAssetBinder
49
+ gameConfigBinder: Binder.Binder<any>,
50
+ gameConfigAssetBinder: Binder.Binder<any>
49
51
  ): GameConfigPicker
50
- local self = setmetatable(BaseObject.new(), GameConfigPicker)
52
+ local self: GameConfigPicker = setmetatable(BaseObject.new() :: any, GameConfigPicker)
51
53
 
52
54
  self._gameConfigBinder = assert(gameConfigBinder, "No gameConfigBinder")
53
55
  self._gameConfigAssetBinder = assert(gameConfigAssetBinder, "No gameConfigAssetBinder")
@@ -55,7 +57,7 @@ function GameConfigPicker.new(
55
57
 
56
58
  self._gameIdToConfigSet = self._maid:Add(ObservableMapSet.new())
57
59
 
58
- self._maid:GiveTask(RxBinderUtils.observeAllBrio(self._gameConfigBinder):Subscribe(function(brio)
60
+ self._maid:GiveTask((RxBinderUtils.observeAllBrio(self._gameConfigBinder) :: any):Subscribe(function(brio: any)
59
61
  if brio:IsDead() then
60
62
  return
61
63
  end
@@ -80,8 +82,8 @@ function GameConfigPicker.ObserveActiveAssetOfTypeBrio(
80
82
  ): Observable.Observable<Brio.Brio<GameConfigAssetBase>>
81
83
  assert(GameConfigAssetTypeUtils.isAssetType(assetType), "Bad assetType")
82
84
 
83
- return self:ObserveActiveConfigsBrio(game.GameId):Pipe({
84
- RxBrioUtils.flatMapBrio(function(gameConfig)
85
+ return (self:ObserveActiveConfigsBrio() :: any):Pipe({
86
+ RxBrioUtils.flatMapBrio(function(gameConfig: any): any
85
87
  return gameConfig:ObserveAssetByTypeBrio(assetType)
86
88
  end),
87
89
  })
@@ -107,11 +109,11 @@ function GameConfigPicker.ObserveActiveAssetOfAssetTypeAndKeyBrio(
107
109
  self: GameConfigPicker,
108
110
  assetType: string,
109
111
  assetKey: string
110
- )
112
+ ): Observable.Observable<Brio.Brio<GameConfigAssetBase>>
111
113
  assert(type(assetKey) == "string", "Bad assetKey")
112
114
 
113
- return self:ObserveActiveConfigsBrio(game.GameId):Pipe({
114
- RxBrioUtils.flatMapBrio(function(gameConfig)
115
+ return (self:ObserveActiveConfigsBrio() :: any):Pipe({
116
+ RxBrioUtils.flatMapBrio(function(gameConfig: any): any
115
117
  return gameConfig:ObserveAssetByTypeAndKeyBrio(assetType, assetKey)
116
118
  end),
117
119
  })
@@ -128,11 +130,11 @@ function GameConfigPicker.ObserveActiveAssetOfAssetTypeAndIdBrio(
128
130
  self: GameConfigPicker,
129
131
  assetType: string,
130
132
  assetId: number
131
- )
133
+ ): Observable.Observable<Brio.Brio<GameConfigAssetBase>>
132
134
  assert(type(assetId) == "number", "Bad assetId")
133
135
 
134
- return self:ObserveActiveConfigsBrio(game.GameId):Pipe({
135
- RxBrioUtils.flatMapBrio(function(gameConfig)
136
+ return (self:ObserveActiveConfigsBrio() :: any):Pipe({
137
+ RxBrioUtils.flatMapBrio(function(gameConfig: any): any
136
138
  return gameConfig:ObserveAssetByTypeAndIdBrio(assetType, assetId)
137
139
  end),
138
140
  })
@@ -150,8 +152,8 @@ function GameConfigPicker.ObserveActiveAssetOfAssetIdBrio(
150
152
  ): Observable.Observable<Brio.Brio<GameConfigAssetBase>>
151
153
  assert(type(assetId) == "number", "Bad assetId")
152
154
 
153
- return self:ObserveActiveConfigsBrio(game.GameId):Pipe({
154
- RxBrioUtils.flatMapBrio(function(gameConfig)
155
+ return (self:ObserveActiveConfigsBrio() :: any):Pipe({
156
+ RxBrioUtils.flatMapBrio(function(gameConfig: any): any
155
157
  return gameConfig:ObserveAssetByIdBrio(assetId)
156
158
  end),
157
159
  })
@@ -169,8 +171,8 @@ function GameConfigPicker.ObserveActiveAssetOfKeyBrio(
169
171
  ): Observable.Observable<Brio.Brio<GameConfigAssetBase>>
170
172
  assert(type(assetKey) == "string", "Bad assetKey")
171
173
 
172
- return self:ObserveActiveConfigsBrio(game.GameId):Pipe({
173
- RxBrioUtils.flatMapBrio(function(gameConfig)
174
+ return (self:ObserveActiveConfigsBrio() :: any):Pipe({
175
+ RxBrioUtils.flatMapBrio(function(gameConfig: any): any
174
176
  return gameConfig:ObserveAssetByKeyBrio(assetKey)
175
177
  end),
176
178
  })
@@ -192,7 +194,7 @@ end
192
194
 
193
195
  @return { GameConfigAssetBase }
194
196
  ]=]
195
- function GameConfigPicker.GetActiveConfigs(self: GameConfigPicker): { GameConfigAssetBase }
197
+ function GameConfigPicker.GetActiveConfigs(self: GameConfigPicker): { any }
196
198
  return self:_getConfigsForGameId(game.GameId)
197
199
  end
198
200
 
@@ -230,7 +232,7 @@ end
230
232
  function GameConfigPicker.PromisePriceInRobux(
231
233
  self: GameConfigPicker,
232
234
  assetType: GameConfigAssetTypes.GameConfigAssetType,
233
- assetIdOrKey
235
+ assetIdOrKey: string | number
234
236
  ): Promise.Promise<number>
235
237
  assert(GameConfigAssetTypeUtils.isAssetType(assetType), "Bad assetType")
236
238
  assert(type(assetIdOrKey) == "number" or type(assetIdOrKey) == "string", "Bad assetIdOrKey")
@@ -238,7 +240,7 @@ function GameConfigPicker.PromisePriceInRobux(
238
240
  if type(assetIdOrKey) == "string" then
239
241
  local asset = self:FindFirstActiveAssetOfKey(assetType, assetIdOrKey)
240
242
  if asset then
241
- return asset:PromiseCloudPriceInRobux()
243
+ return (asset :: any):PromiseCloudPriceInRobux()
242
244
  end
243
245
 
244
246
  return Promise.rejected(string.format("Could not turn %q into asset id", tostring(assetIdOrKey)))
@@ -246,17 +248,18 @@ function GameConfigPicker.PromisePriceInRobux(
246
248
  local asset = self:FindFirstActiveAssetOfId(assetType, assetIdOrKey)
247
249
  if asset then
248
250
  -- TODO: Maybe cancel token
249
- return asset:PromiseCloudPriceInRobux()
251
+ return (asset :: any):PromiseCloudPriceInRobux()
250
252
  end
251
253
 
252
- return GameConfigAssetUtils.promiseCloudDataForAssetType(self._serviceBag, assetType, assetIdOrKey)
253
- :Then(function(cloudData)
254
+ return (GameConfigAssetUtils.promiseCloudDataForAssetType(self._serviceBag, assetType, assetIdOrKey) :: any):Then(
255
+ function(cloudData: any): any
254
256
  if type(cloudData.PriceInRobux) == "number" then
255
257
  return cloudData.PriceInRobux
256
258
  else
257
259
  return Promise.rejected()
258
260
  end
259
- end)
261
+ end
262
+ )
260
263
  else
261
264
  error("[GameConfigPicker.PromisePriceInRobux] - Bad assetIdOrKey")
262
265
  end
@@ -295,8 +298,8 @@ end
295
298
  function GameConfigPicker.GetAllActiveAssetsOfType(
296
299
  self: GameConfigPicker,
297
300
  assetType: GameConfigAssetTypes.GameConfigAssetType
298
- )
299
- local assetList = {}
301
+ ): { GameConfigAssetBase }
302
+ local assetList: { GameConfigAssetBase } = {}
300
303
  for _, gameConfig in self:GetActiveConfigs() do
301
304
  for _, gameConfigAsset in gameConfig:GetAssetsOfType(assetType) do
302
305
  table.insert(assetList, gameConfigAsset)
@@ -363,13 +366,13 @@ function GameConfigPicker.ObserveToAssetIdBrio(
363
366
  assert(type(assetIdOrKey) == "number" or type(assetIdOrKey) == "string", "Bad assetIdOrKey")
364
367
 
365
368
  if type(assetIdOrKey) == "string" then
366
- return self:ObserveActiveAssetOfAssetTypeAndKeyBrio(assetType, assetIdOrKey):Pipe({
367
- RxBrioUtils.switchMapBrio(function(asset)
369
+ return (self:ObserveActiveAssetOfAssetTypeAndKeyBrio(assetType, assetIdOrKey) :: any):Pipe({
370
+ RxBrioUtils.switchMapBrio(function(asset): any
368
371
  return asset:ObserveAssetId()
369
372
  end),
370
373
  })
371
374
  elseif type(assetIdOrKey) == "number" then
372
- return RxBrioUtils.of(assetIdOrKey)
375
+ return RxBrioUtils.of(assetIdOrKey) :: any
373
376
  else
374
377
  error("Bad idOrKey")
375
378
  end