@idosgames/mcp 0.1.31 → 0.1.33
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/package.json +1 -1
- package/registry/host.json +1 -1
- package/registry/index.json +179 -154
- package/registry/modules/ai.json +7 -7
- package/registry/modules/board-game.json +4 -4
- package/registry/modules/boosts.json +7 -7
- package/registry/modules/character.json +7 -7
- package/registry/modules/chat.json +7 -7
- package/registry/modules/collections.json +7 -7
- package/registry/modules/coop-events.json +7 -7
- package/registry/modules/craft.json +7 -7
- package/registry/modules/deals.json +7 -7
- package/registry/modules/events.json +7 -7
- package/registry/modules/friends.json +7 -7
- package/registry/modules/idle-rpg.json +3 -3
- package/registry/modules/inventory.json +7 -7
- package/registry/modules/invite.json +7 -7
- package/registry/modules/leaderboard.json +7 -7
- package/registry/modules/lootboxes.json +7 -7
- package/registry/modules/mailbox.json +7 -7
- package/registry/modules/marketplace.json +7 -7
- package/registry/modules/mini-game.json +3 -3
- package/registry/modules/multiplayer.json +7 -7
- package/registry/modules/premium.json +7 -7
- package/registry/modules/profile.json +9 -9
- package/registry/modules/pvp.json +7 -7
- package/registry/modules/quests.json +7 -7
- package/registry/modules/rewards.json +7 -7
- package/registry/modules/season.json +7 -7
- package/registry/modules/store.json +7 -7
- package/registry/modules/tutorials.json +7 -7
- package/registry/modules/voxelcraft.json +478 -97
- package/registry/modules/workshop.json +7 -7
- package/registry/skills/idosgames-compose-modules.json +1 -1
- package/registry/skills/idosgames-module-contract.json +2 -2
- package/registry/skills/idosgames-ui-kit.json +1 -1
- package/registry/skills/voxelcraft-characters.json +6 -0
- package/registry/skills/voxelcraft-quests.json +6 -0
- package/registry/skills/voxelcraft-worlds.json +2 -2
package/registry/modules/ai.json
CHANGED
|
@@ -27,15 +27,15 @@
|
|
|
27
27
|
"name": "iDos Games",
|
|
28
28
|
"url": "https://idosgames.com"
|
|
29
29
|
},
|
|
30
|
-
"version": "0.1.
|
|
30
|
+
"version": "0.1.2"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@idosgames/core": "0.21.
|
|
34
|
-
"@idosgames/module-sdk": "0.
|
|
35
|
-
"@idosgames/react": "0.
|
|
33
|
+
"@idosgames/core": "0.21.6",
|
|
34
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
35
|
+
"@idosgames/react": "0.5.0",
|
|
36
36
|
"react": "19.2.7"
|
|
37
37
|
},
|
|
38
|
-
"contentHash": "
|
|
38
|
+
"contentHash": "5f9b6c26d6c6fe550184e636ca1c1f5f1fc426cd54c01277235e93df9a0015c5",
|
|
39
39
|
"files": [
|
|
40
40
|
{
|
|
41
41
|
"path": "AiScreen.tsx",
|
|
@@ -55,11 +55,11 @@
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"path": "module.ts",
|
|
58
|
-
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { configSection } from \"@idosgames/react/ui\";\nimport { AiScreen } from \"./AiScreen\";\nimport { hasTitleData, type AISection } from \"./model\";\nimport { t } from \"./i18n\";\n\n// The AI studio as a feature of the game: the AI features the publisher opened to players. No badge.\n// The engine does not put the \"AI\" section into the client's title config, so the features are read\n// once with their own call (it lands in the same config section, the screen draws from it).\nexport const aiModule: Module = defineModule({\n id: \"ai\",\n meta: { name: \"AI studio\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"ai\",\n label: t(\"title\"),\n icon: \"bulb\",\n group: \"social\",\n order: 80,\n available: false,\n Screen: AiScreen,\n });\n const decide = () =>\n ctx.features.setAvailable(\n \"ai\",\n hasTitleData(configSection<AISection>(ctx.client, \"AI\")),\n \"no AI features for players on the title (AI.Features, none untagged 'hidden')\",\n );\n decide();\n if (!configSection(ctx.client, \"AI\"))\n void ctx.client.ai.getDefinitions().then(decide);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"ai\" }),\n describeActions: {},\n });\n },\n});\n"
|
|
58
|
+
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { configSection } from \"@idosgames/react/ui\";\nimport { AiScreen } from \"./AiScreen\";\nimport { hasTitleData, type AISection } from \"./model\";\nimport { t } from \"./i18n\";\n\n// The AI studio as a feature of the game: the AI features the publisher opened to players. No badge.\n// The engine does not put the \"AI\" section into the client's title config, so the features are read\n// once with their own call (it lands in the same config section, the screen draws from it).\nexport const aiModule: Module = defineModule({\n id: \"ai\",\n meta: { name: \"AI studio\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"ai\",\n label: () => t(\"title\"),\n icon: \"bulb\",\n group: \"social\",\n order: 80,\n available: false,\n Screen: AiScreen,\n });\n const decide = () =>\n ctx.features.setAvailable(\n \"ai\",\n hasTitleData(configSection<AISection>(ctx.client, \"AI\")),\n \"no AI features for players on the title (AI.Features, none untagged 'hidden')\",\n );\n decide();\n if (!configSection(ctx.client, \"AI\"))\n void ctx.client.ai.getDefinitions().then(decide);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"ai\" }),\n describeActions: {},\n });\n },\n});\n"
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
61
|
"path": "module.meta.json",
|
|
62
|
-
"content": "{\n \"id\": \"ai\",\n \"type\": \"feature\",\n \"summary\": \"AI studio for any game: the title's AI features for players — text, pictures, voice, music, video and 3D — with the price and the history.\",\n \"description\": \"A ready AI studio (engine AI, InApp AI) for ANY game, built on the @idosgames/react/ui kit and client.ai. Every AI feature the publisher opened to players (section AI, sanitized by the server: no prompts, no models), grouped by kind — text, picture, voice, music, video, 3D. The player describes what they want, pays the feature's price in in-game resources (or nothing), and the result comes back from a job the server runs (waitForGeneration): text, pictures, a player for sound and video, a download link for 3D. 'My creations' lists the player's generations. A feature tagged 'hidden' is for the game's own code (NPC lines and the like) and is not shown. Registers the 'ai' feature. The money side (publisher credits) is the engine's; see the in-app AI rules.\",\n \"provides\": [\n \"AI studio screen\",\n \"text, image, voice, music, video and 3D generation for players\",\n \"feature price in in-game resources\",\n \"history of the player's generations\"\n ],\n \"tags\": [\"ai\", \"generation\", \"ugc\", \"creative\", \"ui\", \"screen\"],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.
|
|
62
|
+
"content": "{\n \"id\": \"ai\",\n \"type\": \"feature\",\n \"summary\": \"AI studio for any game: the title's AI features for players — text, pictures, voice, music, video and 3D — with the price and the history.\",\n \"description\": \"A ready AI studio (engine AI, InApp AI) for ANY game, built on the @idosgames/react/ui kit and client.ai. Every AI feature the publisher opened to players (section AI, sanitized by the server: no prompts, no models), grouped by kind — text, picture, voice, music, video, 3D. The player describes what they want, pays the feature's price in in-game resources (or nothing), and the result comes back from a job the server runs (waitForGeneration): text, pictures, a player for sound and video, a download link for 3D. 'My creations' lists the player's generations. A feature tagged 'hidden' is for the game's own code (NPC lines and the like) and is not shown. Registers the 'ai' feature. The money side (publisher credits) is the engine's; see the in-app AI rules.\",\n \"provides\": [\n \"AI studio screen\",\n \"text, image, voice, music, video and 3D generation for players\",\n \"feature price in in-game resources\",\n \"history of the player's generations\"\n ],\n \"tags\": [\"ai\", \"generation\", \"ugc\", \"creative\", \"ui\", \"screen\"],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.2\"\n}\n"
|
|
63
63
|
}
|
|
64
64
|
]
|
|
65
65
|
}
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@idosgames/core": "0.21.
|
|
49
|
-
"@idosgames/module-sdk": "0.
|
|
50
|
-
"@idosgames/react": "0.
|
|
51
|
-
"@idosgames/wallet": "0.6.
|
|
48
|
+
"@idosgames/core": "0.21.6",
|
|
49
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
50
|
+
"@idosgames/react": "0.5.0",
|
|
51
|
+
"@idosgames/wallet": "0.6.4",
|
|
52
52
|
"@tanstack/react-query": "5.101.2",
|
|
53
53
|
"react": "19.2.7",
|
|
54
54
|
"three": "0.185.1",
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
"name": "iDos Games",
|
|
29
29
|
"url": "https://idosgames.com"
|
|
30
30
|
},
|
|
31
|
-
"version": "0.1.
|
|
31
|
+
"version": "0.1.1"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@idosgames/core": "0.21.
|
|
35
|
-
"@idosgames/module-sdk": "0.
|
|
36
|
-
"@idosgames/react": "0.
|
|
34
|
+
"@idosgames/core": "0.21.6",
|
|
35
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
36
|
+
"@idosgames/react": "0.5.0",
|
|
37
37
|
"react": "19.2.7"
|
|
38
38
|
},
|
|
39
|
-
"contentHash": "
|
|
39
|
+
"contentHash": "bb17d0684afb6135854bc4abdab52d3c0fcdbc01d45ac23fd1c66dd25fce5d47",
|
|
40
40
|
"files": [
|
|
41
41
|
{
|
|
42
42
|
"path": "BoostsScreen.tsx",
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
"path": "module.ts",
|
|
59
|
-
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { configSection } from \"@idosgames/react/ui\";\nimport { BoostsScreen } from \"./BoostsScreen\";\nimport { hasTitleData } from \"./model\";\nimport { t } from \"./i18n\";\n\n// Boosts as a feature of the game: what runs now (the player's own boosts and the title's global\n// windows) and what can be activated. No badge: a running boost asks nothing of the player.\nexport const boostsModule: Module = defineModule({\n id: \"boosts\",\n meta: { name: \"Boosts\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"boosts\",\n label: t(\"title\"),\n icon: \"energy\",\n group: \"economy\",\n order: 58,\n available: false,\n Screen: BoostsScreen,\n });\n const decide = () =>\n ctx.features.setAvailable(\n \"boosts\",\n hasTitleData(configSection(ctx.client, \"TimedBoost\")),\n \"no boosts on the title (TimedBoost)\",\n );\n decide();\n // The engine does not put TimedBoost into the client's title config: read it once with its own\n // call (it lands in the same config section, so the screen draws from it too). Without this the\n // tab never showed on any title.\n if (!configSection(ctx.client, \"TimedBoost\"))\n void ctx.client.timedBoost.getDefinitions().then(decide);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"boosts\" }),\n describeActions: {},\n });\n },\n});\n"
|
|
59
|
+
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { configSection } from \"@idosgames/react/ui\";\nimport { BoostsScreen } from \"./BoostsScreen\";\nimport { hasTitleData } from \"./model\";\nimport { t } from \"./i18n\";\n\n// Boosts as a feature of the game: what runs now (the player's own boosts and the title's global\n// windows) and what can be activated. No badge: a running boost asks nothing of the player.\nexport const boostsModule: Module = defineModule({\n id: \"boosts\",\n meta: { name: \"Boosts\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"boosts\",\n label: () => t(\"title\"),\n icon: \"energy\",\n group: \"economy\",\n order: 58,\n available: false,\n Screen: BoostsScreen,\n });\n const decide = () =>\n ctx.features.setAvailable(\n \"boosts\",\n hasTitleData(configSection(ctx.client, \"TimedBoost\")),\n \"no boosts on the title (TimedBoost)\",\n );\n decide();\n // The engine does not put TimedBoost into the client's title config: read it once with its own\n // call (it lands in the same config section, so the screen draws from it too). Without this the\n // tab never showed on any title.\n if (!configSection(ctx.client, \"TimedBoost\"))\n void ctx.client.timedBoost.getDefinitions().then(decide);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"boosts\" }),\n describeActions: {},\n });\n },\n});\n"
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"path": "module.meta.json",
|
|
63
|
-
"content": "{\n \"id\": \"boosts\",\n \"type\": \"feature\",\n \"summary\": \"Boosts for any game: timed boosts to activate (×2 rewards and the like), what runs now with timers, and the title's global happy hours.\",\n \"description\": \"A ready boosts screen for ANY game, built on the @idosgames/react/ui kit and client.timedBoost. 'Active now': the player's own boosts with their timers or uses left, and the title's global windows (a scheduled happy hour, a phase of a boost chain) marked 'for everyone'. 'Boosts': every boost of the title with its effect as the server applies it (×2, +50%, +10 — to all rewards, quest rewards, board rewards or costs), its duration and uses, activated for free or for currencies/items. The server applies every boost; the screen only shows. Registers the 'boosts' feature. Ships title-seed.json: a free welcome boost and a paid double-rewards boost.\",\n \"provides\": [\n \"boosts screen\",\n \"activate a boost for free or for currency\",\n \"running boosts with timers\",\n \"global happy hours\"\n ],\n \"tags\": [\n \"boosts\",\n \"multiplier\",\n \"happy-hour\",\n \"monetization\",\n \"ui\",\n \"screen\",\n \"economy\"\n ],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.
|
|
63
|
+
"content": "{\n \"id\": \"boosts\",\n \"type\": \"feature\",\n \"summary\": \"Boosts for any game: timed boosts to activate (×2 rewards and the like), what runs now with timers, and the title's global happy hours.\",\n \"description\": \"A ready boosts screen for ANY game, built on the @idosgames/react/ui kit and client.timedBoost. 'Active now': the player's own boosts with their timers or uses left, and the title's global windows (a scheduled happy hour, a phase of a boost chain) marked 'for everyone'. 'Boosts': every boost of the title with its effect as the server applies it (×2, +50%, +10 — to all rewards, quest rewards, board rewards or costs), its duration and uses, activated for free or for currencies/items. The server applies every boost; the screen only shows. Registers the 'boosts' feature. Ships title-seed.json: a free welcome boost and a paid double-rewards boost.\",\n \"provides\": [\n \"boosts screen\",\n \"activate a boost for free or for currency\",\n \"running boosts with timers\",\n \"global happy hours\"\n ],\n \"tags\": [\n \"boosts\",\n \"multiplier\",\n \"happy-hour\",\n \"monetization\",\n \"ui\",\n \"screen\",\n \"economy\"\n ],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.1\"\n}\n"
|
|
64
64
|
}
|
|
65
65
|
]
|
|
66
66
|
}
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"name": "iDos Games",
|
|
40
40
|
"url": "https://idosgames.com"
|
|
41
41
|
},
|
|
42
|
-
"version": "0.1.
|
|
42
|
+
"version": "0.1.3",
|
|
43
43
|
"events": {
|
|
44
44
|
"emits": [
|
|
45
45
|
{
|
|
@@ -53,12 +53,12 @@
|
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@idosgames/core": "0.21.
|
|
57
|
-
"@idosgames/module-sdk": "0.
|
|
58
|
-
"@idosgames/react": "0.
|
|
56
|
+
"@idosgames/core": "0.21.6",
|
|
57
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
58
|
+
"@idosgames/react": "0.5.0",
|
|
59
59
|
"react": "19.2.7"
|
|
60
60
|
},
|
|
61
|
-
"contentHash": "
|
|
61
|
+
"contentHash": "67dfd554a7670a176d4cc5f842fb1818d3f346997fad93f3ce78a1f622d1abe3",
|
|
62
62
|
"files": [
|
|
63
63
|
{
|
|
64
64
|
"path": "CharacterScreen.tsx",
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
},
|
|
111
111
|
{
|
|
112
112
|
"path": "module.ts",
|
|
113
|
-
"content": "import {\n defineModule,\n type ModuleContext,\n type Module,\n} from \"@idosgames/module-sdk\";\nimport {\n canAfford,\n configSection,\n itemDefinitions,\n type ItemSection,\n} from \"@idosgames/react/ui\";\nimport { makeCharacterScreen } from \"./CharacterScreen\";\nimport {\n bestLoadout,\n gearPieces,\n hasTitleData,\n heroesBadge,\n resolveLadder,\n resolveSlots,\n roster,\n type CharacterModelView,\n type CharacterSection,\n type InstanceView,\n type ItemDefWithGear,\n} from \"./model\";\nimport { t } from \"./i18n\";\nimport { heroSelected } from \"./events\";\nimport { readSelected, resolveSelected } from \"./selection\";\n\n// Heroes as a feature of the game (the Hero button of the Unity project). The badge counts heroes\n// that can be unlocked or ranked up right now, plus \"better gear is available\". The hero the player\n// plays with goes out as `character:hero-selected@1` — once the roster is known, and on every pick.\nexport const characterModule: Module = defineModule({\n id: \"character\",\n meta: { name: \"Heroes\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n let announced: string | null = null;\n const announce = (characterId: string | undefined) => {\n if (!characterId || characterId === announced) return;\n announced = characterId;\n ctx.events.emit(heroSelected, { characterId });\n };\n\n ctx.features.register({\n id: \"character\",\n label: t(\"title\"),\n icon: \"hero\",\n group: \"economy\",\n order: 20,\n primary: true,\n available: false,\n Screen: makeCharacterScreen(ctx.features, announce),\n });\n ctx.features.setAvailable(\n \"character\",\n hasTitleData(configSection<CharacterSection>(ctx.client, \"Character\")),\n \"no heroes on the title (Character definitions are empty)\",\n );\n watchBadge(ctx, announce);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"character\", selected: announced }),\n describeActions: {},\n });\n },\n});\n\nfunction watchBadge(\n ctx: ModuleContext,\n announce: (characterId: string | undefined) => void,\n): void {\n const { client, features } = ctx;\n ctx.effect(() => {\n const update = () => {\n const section = configSection<CharacterSection>(client, \"Character\");\n if (!section) return features.setBadge(\"character\", 0);\n const state = client.data.user.state;\n const owned = (state?.Character?.Characters ?? {}) as Record<\n string,\n CharacterModelView\n >;\n const balances = state?.InventoryV2?.VirtualCurrencies as\n Record<string, { Amount?: number }> | undefined;\n const items = itemDefinitions(\n configSection<ItemSection>(client, \"Item\"),\n ) as Map<string, ItemDefWithGear>;\n const pieces = gearPieces(\n (\n state?.InventoryV2 as\n | { UnstackableItems?: Record<string, InstanceView | null> }\n | undefined\n )?.UnstackableItems,\n items,\n );\n const list = roster(section, owned);\n // The saved hero (or the first playable one) as soon as the roster is known — the game\n // fields it from the first frame. Re-resolved on every update: a hero that just became\n // playable may now be the answer.\n announce(resolveSelected(list, readSelected())?.id);\n const better = list\n .filter((h) => h.state === \"owned\")\n .reduce(\n (n, h) =>\n n +\n bestLoadout(\n h.id,\n h.rank,\n resolveSlots(section, h.def),\n pieces,\n h.model?.Equipment,\n items,\n ).length,\n 0,\n );\n features.setBadge(\n \"character\",\n heroesBadge(\n list,\n (lines) => canAfford(lines, balances),\n (e) => resolveLadder(section, e.def),\n better,\n ),\n );\n };\n // Heroes and gear come with the login state; the central cache asks the server only for what\n // is not there yet (a hero given by default).\n update();\n void client.cache.ensureState([\"Character\"]).then(update);\n return client.on(\"user:anyUpdated\", update);\n });\n}\n"
|
|
113
|
+
"content": "import {\n defineModule,\n type ModuleContext,\n type Module,\n} from \"@idosgames/module-sdk\";\nimport {\n canAfford,\n configSection,\n itemDefinitions,\n type ItemSection,\n} from \"@idosgames/react/ui\";\nimport { makeCharacterScreen } from \"./CharacterScreen\";\nimport {\n bestLoadout,\n gearPieces,\n hasTitleData,\n heroesBadge,\n resolveLadder,\n resolveSlots,\n roster,\n type CharacterModelView,\n type CharacterSection,\n type InstanceView,\n type ItemDefWithGear,\n} from \"./model\";\nimport { t } from \"./i18n\";\nimport { heroSelected } from \"./events\";\nimport { readSelected, resolveSelected } from \"./selection\";\n\n// Heroes as a feature of the game (the Hero button of the Unity project). The badge counts heroes\n// that can be unlocked or ranked up right now, plus \"better gear is available\". The hero the player\n// plays with goes out as `character:hero-selected@1` — once the roster is known, and on every pick.\nexport const characterModule: Module = defineModule({\n id: \"character\",\n meta: { name: \"Heroes\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n let announced: string | null = null;\n const announce = (characterId: string | undefined) => {\n if (!characterId || characterId === announced) return;\n announced = characterId;\n ctx.events.emit(heroSelected, { characterId });\n };\n\n ctx.features.register({\n id: \"character\",\n label: () => t(\"title\"),\n icon: \"hero\",\n group: \"economy\",\n order: 20,\n primary: true,\n available: false,\n Screen: makeCharacterScreen(ctx.features, announce),\n });\n ctx.features.setAvailable(\n \"character\",\n hasTitleData(configSection<CharacterSection>(ctx.client, \"Character\")),\n \"no heroes on the title (Character definitions are empty)\",\n );\n watchBadge(ctx, announce);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"character\", selected: announced }),\n describeActions: {},\n });\n },\n});\n\nfunction watchBadge(\n ctx: ModuleContext,\n announce: (characterId: string | undefined) => void,\n): void {\n const { client, features } = ctx;\n ctx.effect(() => {\n const update = () => {\n const section = configSection<CharacterSection>(client, \"Character\");\n if (!section) return features.setBadge(\"character\", 0);\n const state = client.data.user.state;\n const owned = (state?.Character?.Characters ?? {}) as Record<\n string,\n CharacterModelView\n >;\n const balances = state?.InventoryV2?.VirtualCurrencies as\n Record<string, { Amount?: number }> | undefined;\n const items = itemDefinitions(\n configSection<ItemSection>(client, \"Item\"),\n ) as Map<string, ItemDefWithGear>;\n const pieces = gearPieces(\n (\n state?.InventoryV2 as\n | { UnstackableItems?: Record<string, InstanceView | null> }\n | undefined\n )?.UnstackableItems,\n items,\n );\n const list = roster(section, owned);\n // The saved hero (or the first playable one) as soon as the roster is known — the game\n // fields it from the first frame. Re-resolved on every update: a hero that just became\n // playable may now be the answer.\n announce(resolveSelected(list, readSelected())?.id);\n const better = list\n .filter((h) => h.state === \"owned\")\n .reduce(\n (n, h) =>\n n +\n bestLoadout(\n h.id,\n h.rank,\n resolveSlots(section, h.def),\n pieces,\n h.model?.Equipment,\n items,\n ).length,\n 0,\n );\n features.setBadge(\n \"character\",\n heroesBadge(\n list,\n (lines) => canAfford(lines, balances),\n (e) => resolveLadder(section, e.def),\n better,\n ),\n );\n };\n // Heroes and gear come with the login state; the central cache asks the server only for what\n // is not there yet (a hero given by default).\n update();\n void client.cache.ensureState([\"Character\"]).then(update);\n return client.on(\"user:anyUpdated\", update);\n });\n}\n"
|
|
114
114
|
},
|
|
115
115
|
{
|
|
116
116
|
"path": "selection.ts",
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
},
|
|
119
119
|
{
|
|
120
120
|
"path": "module.meta.json",
|
|
121
|
-
"content": "{\n \"id\": \"character\",\n \"type\": \"feature\",\n \"summary\": \"Heroes screen for any game: roster, ranks and stats with their costs, equipment slots with 'Equip best', item levels and skins.\",\n \"description\": \"A ready heroes screen (the Hero button of the Unity SDK) for ANY game, built on the @idosgames/react/ui kit and client.character. The screen is the selected hero's equipment hub: portrait, class and rarity, rank and server-computed Power, 'Rank up' with its price, gear slots (locked ones show the rank they open at), 'Equip best' when better gear fits, 'Take off all', and the gear the player owns by class. Everything detailed is a popup: the hero list (select, unlock for currency), the stats (level/cap bars, upgrade prices, requirements, 'Upgrade all' — as many levels as the balances cover, cheapest first, in one batch —, and 'where this number comes from' — base, stat levels, rank, gear flat and percent bonuses), a slot's fitting gear, a piece of gear (equip / take off / level up) and skins (wear, buy). Prices and caps follow the title's curves (rank ladder, stat cost curve, StatMaxLevelCurve, item Upgrade); the server re-checks everything. Registers the 'character' feature; the inventory hands equipment to it with ctx.features.open('character', { itemInstanceID }). Its badge counts heroes to unlock or rank up and better gear. Ships title-seed.json: three heroes (Knight free, Archer and Mage for gems) with stats, ranks and slots. Emits character:hero-selected@1 with the hero the player plays with (on start-up and on every pick) so a game can field that hero.\",\n \"provides\": [\n \"hero roster with unlock for currency\",\n \"rank up with price by the rank ladder\",\n \"stat upgrades with costs, caps and requirements\",\n \"upgrade all stats in one batch\",\n \"stat breakdown popup by source\",\n \"equipment slots and equip / take off\",\n \"equip best gear automatically\",\n \"take off all gear\",\n \"item level upgrades\",\n \"character skins\",\n \"demo heroes\",\n \"selected hero for the game (event)\"\n ],\n \"tags\": [\n \"heroes\",\n \"characters\",\n \"rpg\",\n \"stats\",\n \"equipment\",\n \"gear\",\n \"skins\",\n \"ui\",\n \"screen\",\n \"economy\"\n ],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.
|
|
121
|
+
"content": "{\n \"id\": \"character\",\n \"type\": \"feature\",\n \"summary\": \"Heroes screen for any game: roster, ranks and stats with their costs, equipment slots with 'Equip best', item levels and skins.\",\n \"description\": \"A ready heroes screen (the Hero button of the Unity SDK) for ANY game, built on the @idosgames/react/ui kit and client.character. The screen is the selected hero's equipment hub: portrait, class and rarity, rank and server-computed Power, 'Rank up' with its price, gear slots (locked ones show the rank they open at), 'Equip best' when better gear fits, 'Take off all', and the gear the player owns by class. Everything detailed is a popup: the hero list (select, unlock for currency), the stats (level/cap bars, upgrade prices, requirements, 'Upgrade all' — as many levels as the balances cover, cheapest first, in one batch —, and 'where this number comes from' — base, stat levels, rank, gear flat and percent bonuses), a slot's fitting gear, a piece of gear (equip / take off / level up) and skins (wear, buy). Prices and caps follow the title's curves (rank ladder, stat cost curve, StatMaxLevelCurve, item Upgrade); the server re-checks everything. Registers the 'character' feature; the inventory hands equipment to it with ctx.features.open('character', { itemInstanceID }). Its badge counts heroes to unlock or rank up and better gear. Ships title-seed.json: three heroes (Knight free, Archer and Mage for gems) with stats, ranks and slots. Emits character:hero-selected@1 with the hero the player plays with (on start-up and on every pick) so a game can field that hero.\",\n \"provides\": [\n \"hero roster with unlock for currency\",\n \"rank up with price by the rank ladder\",\n \"stat upgrades with costs, caps and requirements\",\n \"upgrade all stats in one batch\",\n \"stat breakdown popup by source\",\n \"equipment slots and equip / take off\",\n \"equip best gear automatically\",\n \"take off all gear\",\n \"item level upgrades\",\n \"character skins\",\n \"demo heroes\",\n \"selected hero for the game (event)\"\n ],\n \"tags\": [\n \"heroes\",\n \"characters\",\n \"rpg\",\n \"stats\",\n \"equipment\",\n \"gear\",\n \"skins\",\n \"ui\",\n \"screen\",\n \"economy\"\n ],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.3\",\n \"events\": {\n \"emits\": [\n {\n \"topic\": \"character:hero-selected@1\",\n \"when\": \"on start-up (the saved or first playable hero, once the roster is known) and whenever the player selects another hero on the Heroes screen\",\n \"payload\": {\n \"characterId\": \"string\"\n }\n }\n ]\n }\n}\n"
|
|
122
122
|
}
|
|
123
123
|
]
|
|
124
124
|
}
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
"name": "iDos Games",
|
|
33
33
|
"url": "https://idosgames.com"
|
|
34
34
|
},
|
|
35
|
-
"version": "0.1.
|
|
35
|
+
"version": "0.1.2"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@idosgames/core": "0.21.
|
|
39
|
-
"@idosgames/module-sdk": "0.
|
|
40
|
-
"@idosgames/react": "0.
|
|
38
|
+
"@idosgames/core": "0.21.6",
|
|
39
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
40
|
+
"@idosgames/react": "0.5.0",
|
|
41
41
|
"react": "19.2.7"
|
|
42
42
|
},
|
|
43
|
-
"contentHash": "
|
|
43
|
+
"contentHash": "8ee2540d83607f36c770ed998f2a3806edac1c0373b89a3425549f3f80f0e9ff",
|
|
44
44
|
"files": [
|
|
45
45
|
{
|
|
46
46
|
"path": "ChatScreen.tsx",
|
|
@@ -80,11 +80,11 @@
|
|
|
80
80
|
},
|
|
81
81
|
{
|
|
82
82
|
"path": "module.ts",
|
|
83
|
-
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { makeChatScreen, watchChat } from \"./ChatScreen\";\nimport { t } from \"./i18n\";\n\n// Chat as a feature of the game. The watcher reads the unread count once per session — a closed\n// chat polls nothing (every request is billed to the publisher). features.open(\"chat\", { userID })\n// opens a private chat with that player.\nexport const chatModule: Module = defineModule({\n id: \"chat\",\n meta: { name: \"Chat\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"chat\",\n label: t(\"title\"),\n icon: \"chat\",\n group: \"social\",\n order: 85,\n available: false,\n Screen: makeChatScreen(ctx.features),\n });\n watchChat(ctx);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"chat\" }),\n describeActions: {},\n });\n },\n});\n"
|
|
83
|
+
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { makeChatScreen, watchChat } from \"./ChatScreen\";\nimport { t } from \"./i18n\";\n\n// Chat as a feature of the game. The watcher reads the unread count once per session — a closed\n// chat polls nothing (every request is billed to the publisher). features.open(\"chat\", { userID })\n// opens a private chat with that player.\nexport const chatModule: Module = defineModule({\n id: \"chat\",\n meta: { name: \"Chat\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"chat\",\n label: () => t(\"title\"),\n icon: \"chat\",\n group: \"social\",\n order: 85,\n available: false,\n Screen: makeChatScreen(ctx.features),\n });\n watchChat(ctx);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"chat\" }),\n describeActions: {},\n });\n },\n});\n"
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
86
|
"path": "module.meta.json",
|
|
87
|
-
"content": "{\n \"id\": \"chat\",\n \"type\": \"feature\",\n \"summary\": \"Chat for any game: channels as tabs, private chats, a feed with earlier messages, slow mode, and report / ignore / write privately in a popup.\",\n \"description\": \"A ready player chat (Unity V2/Runtime/UI/Chat) for ANY game, built on the @idosgames/react/ui kit and client.chat. The title's channels are tabs (names are localization keys) plus 'Private' — 1-on-1 chats (with friends when the title says so). The feed loads its history, pages back to earlier messages, shows the server's copy of what was sent (moderation may mask a word) and counts down the slow mode; a channel the player may not write to shows the server's reason. ONE poll covers every room and runs only while the screen is open, at the interval the server sets; rooms are marked read when the player leaves them. Popups: a message's actions (write privately, report with a reason, ignore the player) and the channel list to join or leave opt-in channels. Registers the 'chat' feature; features.open('chat', { userID }) opens a private chat (the friends card uses it). Its badge is the unread count, read once per session — a closed chat costs nothing. Ships title-seed.json: a world channel, an opt-in trade channel, private chats between friends.\",\n \"provides\": [\n \"chat channels as tabs\",\n \"private chats\",\n \"message feed with earlier messages\",\n \"slow mode countdown\",\n \"report, ignore and write privately\",\n \"join and leave channels\",\n \"chat badge\",\n \"demo channels\"\n ],\n \"tags\": [\"chat\", \"social\", \"messages\", \"dm\", \"moderation\", \"ui\", \"screen\"],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.
|
|
87
|
+
"content": "{\n \"id\": \"chat\",\n \"type\": \"feature\",\n \"summary\": \"Chat for any game: channels as tabs, private chats, a feed with earlier messages, slow mode, and report / ignore / write privately in a popup.\",\n \"description\": \"A ready player chat (Unity V2/Runtime/UI/Chat) for ANY game, built on the @idosgames/react/ui kit and client.chat. The title's channels are tabs (names are localization keys) plus 'Private' — 1-on-1 chats (with friends when the title says so). The feed loads its history, pages back to earlier messages, shows the server's copy of what was sent (moderation may mask a word) and counts down the slow mode; a channel the player may not write to shows the server's reason. ONE poll covers every room and runs only while the screen is open, at the interval the server sets; rooms are marked read when the player leaves them. Popups: a message's actions (write privately, report with a reason, ignore the player) and the channel list to join or leave opt-in channels. Registers the 'chat' feature; features.open('chat', { userID }) opens a private chat (the friends card uses it). Its badge is the unread count, read once per session — a closed chat costs nothing. Ships title-seed.json: a world channel, an opt-in trade channel, private chats between friends.\",\n \"provides\": [\n \"chat channels as tabs\",\n \"private chats\",\n \"message feed with earlier messages\",\n \"slow mode countdown\",\n \"report, ignore and write privately\",\n \"join and leave channels\",\n \"chat badge\",\n \"demo channels\"\n ],\n \"tags\": [\"chat\", \"social\", \"messages\", \"dm\", \"moderation\", \"ui\", \"screen\"],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.2\"\n}\n"
|
|
88
88
|
}
|
|
89
89
|
]
|
|
90
90
|
}
|
|
@@ -31,15 +31,15 @@
|
|
|
31
31
|
"name": "iDos Games",
|
|
32
32
|
"url": "https://idosgames.com"
|
|
33
33
|
},
|
|
34
|
-
"version": "0.1.
|
|
34
|
+
"version": "0.1.2"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@idosgames/core": "0.21.
|
|
38
|
-
"@idosgames/module-sdk": "0.
|
|
39
|
-
"@idosgames/react": "0.
|
|
37
|
+
"@idosgames/core": "0.21.6",
|
|
38
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
39
|
+
"@idosgames/react": "0.5.0",
|
|
40
40
|
"react": "19.2.7"
|
|
41
41
|
},
|
|
42
|
-
"contentHash": "
|
|
42
|
+
"contentHash": "bb88c07207fcc242fa2328e5aece9f7afca487cf8a6e0947de8576f387377a34",
|
|
43
43
|
"files": [
|
|
44
44
|
{
|
|
45
45
|
"path": "CollectionsScreen.tsx",
|
|
@@ -75,11 +75,11 @@
|
|
|
75
75
|
},
|
|
76
76
|
{
|
|
77
77
|
"path": "module.ts",
|
|
78
|
-
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { configSection } from \"@idosgames/react/ui\";\nimport { CollectionsScreen, watchCollections } from \"./CollectionsScreen\";\nimport { hasTitleData } from \"./model\";\nimport { t } from \"./i18n\";\n\n// Collections as a feature of the game: the album, packs and chests, trades with friends. The\n// watcher keeps the badge (set rewards and the grand prize waiting) — only on a title with a\n// collection.\nexport const collectionsModule: Module = defineModule({\n id: \"collections\",\n meta: { name: \"Collections\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"collections\",\n label: t(\"title\"),\n icon: \"star\",\n group: \"events\",\n order: 45,\n available: false,\n Screen: CollectionsScreen,\n });\n const enabled = hasTitleData(configSection(ctx.client, \"Collection\"));\n ctx.features.setAvailable(\n \"collections\",\n enabled,\n \"no collection on the title (Collection)\",\n );\n if (enabled) watchCollections(ctx);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"collections\" }),\n describeActions: {},\n });\n },\n});\n"
|
|
78
|
+
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { configSection } from \"@idosgames/react/ui\";\nimport { CollectionsScreen, watchCollections } from \"./CollectionsScreen\";\nimport { hasTitleData } from \"./model\";\nimport { t } from \"./i18n\";\n\n// Collections as a feature of the game: the album, packs and chests, trades with friends. The\n// watcher keeps the badge (set rewards and the grand prize waiting) — only on a title with a\n// collection.\nexport const collectionsModule: Module = defineModule({\n id: \"collections\",\n meta: { name: \"Collections\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"collections\",\n label: () => t(\"title\"),\n icon: \"star\",\n group: \"events\",\n order: 45,\n available: false,\n Screen: CollectionsScreen,\n });\n const enabled = hasTitleData(configSection(ctx.client, \"Collection\"));\n ctx.features.setAvailable(\n \"collections\",\n enabled,\n \"no collection on the title (Collection)\",\n );\n if (enabled) watchCollections(ctx);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"collections\" }),\n describeActions: {},\n });\n },\n});\n"
|
|
79
79
|
},
|
|
80
80
|
{
|
|
81
81
|
"path": "module.meta.json",
|
|
82
|
-
"content": "{\n \"id\": \"collections\",\n \"type\": \"feature\",\n \"summary\": \"Collections for any game: an album of card sets with set rewards and a grand prize, packs and chests, trading spare cards with friends.\",\n \"description\": \"A ready collections screen (engine Collection) for ANY game, built on the @idosgames/react/ui kit and client.collection. Album: the player's collection with every set in order — the cards held (with how many) and the gaps, a reward to claim per completed set and a grand prize for the whole album. Packs: every pack type with every way to pay, opened once or ten at a time (the server rolls them — new cards and duplicates are shown), and collection chests bought with the points duplicates turn into. Trades: offers from other players (accept / decline), your own offers (cancel), and giving a spare card to a friend. Registers the 'collections' feature; its badge counts set rewards and the grand prize waiting. Ships title-seed.json: a small album with sets, a pack and a chest.\",\n \"provides\": [\n \"collection album with sets\",\n \"set rewards and grand prize\",\n \"card packs, once or ten at a time\",\n \"collection chests for points\",\n \"trading cards with friends\",\n \"badge for rewards waiting\"\n ],\n \"tags\": [\n \"collection\",\n \"album\",\n \"cards\",\n \"stickers\",\n \"trading\",\n \"ui\",\n \"screen\",\n \"events\"\n ],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.
|
|
82
|
+
"content": "{\n \"id\": \"collections\",\n \"type\": \"feature\",\n \"summary\": \"Collections for any game: an album of card sets with set rewards and a grand prize, packs and chests, trading spare cards with friends.\",\n \"description\": \"A ready collections screen (engine Collection) for ANY game, built on the @idosgames/react/ui kit and client.collection. Album: the player's collection with every set in order — the cards held (with how many) and the gaps, a reward to claim per completed set and a grand prize for the whole album. Packs: every pack type with every way to pay, opened once or ten at a time (the server rolls them — new cards and duplicates are shown), and collection chests bought with the points duplicates turn into. Trades: offers from other players (accept / decline), your own offers (cancel), and giving a spare card to a friend. Registers the 'collections' feature; its badge counts set rewards and the grand prize waiting. Ships title-seed.json: a small album with sets, a pack and a chest.\",\n \"provides\": [\n \"collection album with sets\",\n \"set rewards and grand prize\",\n \"card packs, once or ten at a time\",\n \"collection chests for points\",\n \"trading cards with friends\",\n \"badge for rewards waiting\"\n ],\n \"tags\": [\n \"collection\",\n \"album\",\n \"cards\",\n \"stickers\",\n \"trading\",\n \"ui\",\n \"screen\",\n \"events\"\n ],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.2\"\n}\n"
|
|
83
83
|
}
|
|
84
84
|
]
|
|
85
85
|
}
|
|
@@ -29,15 +29,15 @@
|
|
|
29
29
|
"name": "iDos Games",
|
|
30
30
|
"url": "https://idosgames.com"
|
|
31
31
|
},
|
|
32
|
-
"version": "0.1.
|
|
32
|
+
"version": "0.1.2"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@idosgames/core": "0.21.
|
|
36
|
-
"@idosgames/module-sdk": "0.
|
|
37
|
-
"@idosgames/react": "0.
|
|
35
|
+
"@idosgames/core": "0.21.6",
|
|
36
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
37
|
+
"@idosgames/react": "0.5.0",
|
|
38
38
|
"react": "19.2.7"
|
|
39
39
|
},
|
|
40
|
-
"contentHash": "
|
|
40
|
+
"contentHash": "ed7bff8cefd18dfb597b5a09e58c2ee5fc8500dc41e37091fa1e798540307db6",
|
|
41
41
|
"files": [
|
|
42
42
|
{
|
|
43
43
|
"path": "CoopEventsScreen.tsx",
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
59
|
"path": "module.ts",
|
|
60
|
-
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { configSection } from \"@idosgames/react/ui\";\nimport {\n createCoopStore,\n makeCoopEventsScreen,\n watchCoop,\n} from \"./CoopEventsScreen\";\nimport { hasTitleData } from \"./model\";\nimport { t } from \"./i18n\";\n\n// Team events as a feature of the game. The watcher reads the player's group once on start and\n// keeps the badge (object reward and team prize waiting) — only on a title with team events.\nexport const coopEventsModule: Module = defineModule({\n id: \"coop-events\",\n meta: { name: \"Team event\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n const store = createCoopStore(ctx.features);\n ctx.features.register({\n id: \"coop-events\",\n label: t(\"title\"),\n icon: \"friends\",\n group: \"events\",\n order: 28,\n available: false,\n Screen: makeCoopEventsScreen(store),\n });\n const enabled = hasTitleData(configSection(ctx.client, \"CoopEvent\"));\n ctx.features.setAvailable(\n \"coop-events\",\n enabled,\n \"no team events on the title (CoopEvent chains)\",\n );\n if (enabled) watchCoop(ctx, store);\n ctx.exposeToAgent({\n state: () => ({\n ui: \"dom\",\n feature: \"coop-events\",\n group: store.get()?.GroupID ?? null,\n }),\n describeActions: {},\n });\n },\n});\n"
|
|
60
|
+
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { configSection } from \"@idosgames/react/ui\";\nimport {\n createCoopStore,\n makeCoopEventsScreen,\n watchCoop,\n} from \"./CoopEventsScreen\";\nimport { hasTitleData } from \"./model\";\nimport { t } from \"./i18n\";\n\n// Team events as a feature of the game. The watcher reads the player's group once on start and\n// keeps the badge (object reward and team prize waiting) — only on a title with team events.\nexport const coopEventsModule: Module = defineModule({\n id: \"coop-events\",\n meta: { name: \"Team event\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n const store = createCoopStore(ctx.features);\n ctx.features.register({\n id: \"coop-events\",\n label: () => t(\"title\"),\n icon: \"friends\",\n group: \"events\",\n order: 28,\n available: false,\n Screen: makeCoopEventsScreen(store),\n });\n const enabled = hasTitleData(configSection(ctx.client, \"CoopEvent\"));\n ctx.features.setAvailable(\n \"coop-events\",\n enabled,\n \"no team events on the title (CoopEvent chains)\",\n );\n if (enabled) watchCoop(ctx, store);\n ctx.exposeToAgent({\n state: () => ({\n ui: \"dom\",\n feature: \"coop-events\",\n group: store.get()?.GroupID ?? null,\n }),\n describeActions: {},\n });\n },\n});\n"
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
"path": "module.meta.json",
|
|
64
|
-
"content": "{\n \"id\": \"coop-events\",\n \"type\": \"feature\",\n \"summary\": \"Team events for any game: join a group, each member spins the wheel to build their own object, the team shares a grand prize.\",\n \"description\": \"A ready team event screen (engine CoopEvent) for ANY game, built on the @idosgames/react/ui kit and client.coopEvent. Not in a group: the running team events of the title with their timers and team prize, 'Join a team' (the server matches partners, helpers fill the gaps). In a group: every member with their object and its progress, 'Spin' (once or five at a time, free or for currency) to build your own object, the object's reward when it is done, the team prize when every object is done, and leaving the team. The group lives in one shared document on the server — the screen re-reads it after every action. Registers the 'coop-events' feature; its badge counts the object reward and the team prize waiting. Ships title-seed.json: a weekly team build event.\",\n \"provides\": [\n \"team event screen\",\n \"join a team (matchmaking by the server)\",\n \"spin to build your object\",\n \"object reward and team prize\",\n \"badge for rewards waiting\"\n ],\n \"tags\": [\"coop\", \"team\", \"group\", \"events\", \"social\", \"ui\", \"screen\"],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.
|
|
64
|
+
"content": "{\n \"id\": \"coop-events\",\n \"type\": \"feature\",\n \"summary\": \"Team events for any game: join a group, each member spins the wheel to build their own object, the team shares a grand prize.\",\n \"description\": \"A ready team event screen (engine CoopEvent) for ANY game, built on the @idosgames/react/ui kit and client.coopEvent. Not in a group: the running team events of the title with their timers and team prize, 'Join a team' (the server matches partners, helpers fill the gaps). In a group: every member with their object and its progress, 'Spin' (once or five at a time, free or for currency) to build your own object, the object's reward when it is done, the team prize when every object is done, and leaving the team. The group lives in one shared document on the server — the screen re-reads it after every action. Registers the 'coop-events' feature; its badge counts the object reward and the team prize waiting. Ships title-seed.json: a weekly team build event.\",\n \"provides\": [\n \"team event screen\",\n \"join a team (matchmaking by the server)\",\n \"spin to build your object\",\n \"object reward and team prize\",\n \"badge for rewards waiting\"\n ],\n \"tags\": [\"coop\", \"team\", \"group\", \"events\", \"social\", \"ui\", \"screen\"],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.2\"\n}\n"
|
|
65
65
|
}
|
|
66
66
|
]
|
|
67
67
|
}
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
"name": "iDos Games",
|
|
33
33
|
"url": "https://idosgames.com"
|
|
34
34
|
},
|
|
35
|
-
"version": "0.1.
|
|
35
|
+
"version": "0.1.2"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@idosgames/core": "0.21.
|
|
39
|
-
"@idosgames/module-sdk": "0.
|
|
40
|
-
"@idosgames/react": "0.
|
|
38
|
+
"@idosgames/core": "0.21.6",
|
|
39
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
40
|
+
"@idosgames/react": "0.5.0",
|
|
41
41
|
"react": "19.2.7"
|
|
42
42
|
},
|
|
43
|
-
"contentHash": "
|
|
43
|
+
"contentHash": "f4d962e257dc5647a013afc7899b43134964f6505431f9ed1147611c67c4af90",
|
|
44
44
|
"files": [
|
|
45
45
|
{
|
|
46
46
|
"path": "CraftScreen.tsx",
|
|
@@ -60,11 +60,11 @@
|
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"path": "module.ts",
|
|
63
|
-
"content": "import {\n defineModule,\n type Module,\n type ModuleContext,\n} from \"@idosgames/module-sdk\";\nimport {\n configSection,\n itemDefinitions,\n type ItemSection,\n} from \"@idosgames/react/ui\";\nimport { makeCraftScreen } from \"./CraftScreen\";\nimport { craftableRecipes, hasTitleData, ownedCounts, recipes } from \"./model\";\nimport { t } from \"./i18n\";\n\n// Craft as a feature of the game. Badge: recipes the player has enough fitting items for.\nexport const craftModule: Module = defineModule({\n id: \"craft\",\n meta: { name: \"Craft\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"craft\",\n label: t(\"title\"),\n icon: \"hammer\",\n group: \"economy\",\n order: 60,\n available: false,\n Screen: makeCraftScreen(ctx.features),\n });\n ctx.features.setAvailable(\n \"craft\",\n hasTitleData(configSection(ctx.client, \"Craft\")),\n \"no craft recipes on the title (Craft definitions are empty)\",\n );\n watchBadge(ctx);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"craft\" }),\n describeActions: {},\n });\n },\n});\n\nfunction watchBadge(ctx: ModuleContext): void {\n const { client, features } = ctx;\n ctx.effect(() => {\n const update = () => {\n const list = recipes(configSection(client, \"Craft\"));\n const items = itemDefinitions(configSection<ItemSection>(client, \"Item\"));\n features.setBadge(\n \"craft\",\n craftableRecipes(\n list,\n items,\n ownedCounts(client.data.user.state?.InventoryV2 as never),\n ),\n );\n };\n update();\n return client.on(\"user:anyUpdated\", update);\n });\n}\n"
|
|
63
|
+
"content": "import {\n defineModule,\n type Module,\n type ModuleContext,\n} from \"@idosgames/module-sdk\";\nimport {\n configSection,\n itemDefinitions,\n type ItemSection,\n} from \"@idosgames/react/ui\";\nimport { makeCraftScreen } from \"./CraftScreen\";\nimport { craftableRecipes, hasTitleData, ownedCounts, recipes } from \"./model\";\nimport { t } from \"./i18n\";\n\n// Craft as a feature of the game. Badge: recipes the player has enough fitting items for.\nexport const craftModule: Module = defineModule({\n id: \"craft\",\n meta: { name: \"Craft\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"craft\",\n label: () => t(\"title\"),\n icon: \"hammer\",\n group: \"economy\",\n order: 60,\n available: false,\n Screen: makeCraftScreen(ctx.features),\n });\n ctx.features.setAvailable(\n \"craft\",\n hasTitleData(configSection(ctx.client, \"Craft\")),\n \"no craft recipes on the title (Craft definitions are empty)\",\n );\n watchBadge(ctx);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"craft\" }),\n describeActions: {},\n });\n },\n});\n\nfunction watchBadge(ctx: ModuleContext): void {\n const { client, features } = ctx;\n ctx.effect(() => {\n const update = () => {\n const list = recipes(configSection(client, \"Craft\"));\n const items = itemDefinitions(configSection<ItemSection>(client, \"Item\"));\n features.setBadge(\n \"craft\",\n craftableRecipes(\n list,\n items,\n ownedCounts(client.data.user.state?.InventoryV2 as never),\n ),\n );\n };\n update();\n return client.on(\"user:anyUpdated\", update);\n });\n}\n"
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
66
|
"path": "module.meta.json",
|
|
67
|
-
"content": "{\n \"id\": \"craft\",\n \"type\": \"feature\",\n \"summary\": \"Craft screen for any game: trade-up recipes by rarity or collection, a contract of owned items, auto-fill, price options and the result popup.\",\n \"description\": \"A ready craft screen (Unity Alikhan/Craft) for ANY game, built on the @idosgames/react/ui kit and client.craft. The screen lists the title's recipes as cards, lowest rarity first: what goes in (N items of a rarity or a collection) and what can come out. A recipe opens as a popup — the contract: the fitting items the player owns (worn equipment does not count), tap to add, 'Auto' fills from the most plentiful, the price options, and 'Craft'. The server rolls the result (only items with a roll Weight > 0 are promised) and the reward popup shows it flying into the inventory. 'Not enough coins' offers to open the shop (ctx.features.open('store')). Registers the 'craft' feature; its badge counts recipes the player can run now. Ships title-seed.json: 3 Common → Rare for coins and 3 Rare → Legendary for gems.\",\n \"provides\": [\n \"craft screen from the title's recipes\",\n \"trade-up by rarity or collection\",\n \"contract popup with owned items\",\n \"auto-fill of the contract\",\n \"price options\",\n \"craft result with reward animation\",\n \"craft badge for runnable recipes\",\n \"demo recipes\"\n ],\n \"tags\": [\"craft\", \"crafting\", \"trade-up\", \"items\", \"ui\", \"screen\", \"economy\"],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.
|
|
67
|
+
"content": "{\n \"id\": \"craft\",\n \"type\": \"feature\",\n \"summary\": \"Craft screen for any game: trade-up recipes by rarity or collection, a contract of owned items, auto-fill, price options and the result popup.\",\n \"description\": \"A ready craft screen (Unity Alikhan/Craft) for ANY game, built on the @idosgames/react/ui kit and client.craft. The screen lists the title's recipes as cards, lowest rarity first: what goes in (N items of a rarity or a collection) and what can come out. A recipe opens as a popup — the contract: the fitting items the player owns (worn equipment does not count), tap to add, 'Auto' fills from the most plentiful, the price options, and 'Craft'. The server rolls the result (only items with a roll Weight > 0 are promised) and the reward popup shows it flying into the inventory. 'Not enough coins' offers to open the shop (ctx.features.open('store')). Registers the 'craft' feature; its badge counts recipes the player can run now. Ships title-seed.json: 3 Common → Rare for coins and 3 Rare → Legendary for gems.\",\n \"provides\": [\n \"craft screen from the title's recipes\",\n \"trade-up by rarity or collection\",\n \"contract popup with owned items\",\n \"auto-fill of the contract\",\n \"price options\",\n \"craft result with reward animation\",\n \"craft badge for runnable recipes\",\n \"demo recipes\"\n ],\n \"tags\": [\"craft\", \"crafting\", \"trade-up\", \"items\", \"ui\", \"screen\", \"economy\"],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.2\"\n}\n"
|
|
68
68
|
}
|
|
69
69
|
]
|
|
70
70
|
}
|
|
@@ -31,15 +31,15 @@
|
|
|
31
31
|
"name": "iDos Games",
|
|
32
32
|
"url": "https://idosgames.com"
|
|
33
33
|
},
|
|
34
|
-
"version": "0.1.
|
|
34
|
+
"version": "0.1.2"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@idosgames/core": "0.21.
|
|
38
|
-
"@idosgames/module-sdk": "0.
|
|
39
|
-
"@idosgames/react": "0.
|
|
37
|
+
"@idosgames/core": "0.21.6",
|
|
38
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
39
|
+
"@idosgames/react": "0.5.0",
|
|
40
40
|
"react": "19.2.7"
|
|
41
41
|
},
|
|
42
|
-
"contentHash": "
|
|
42
|
+
"contentHash": "4f1608aa1fd90cf3561d8da43160187b46cc15b0f2f22fd0d980142ef90f0ef6",
|
|
43
43
|
"files": [
|
|
44
44
|
{
|
|
45
45
|
"path": "DealsScreen.tsx",
|
|
@@ -59,11 +59,11 @@
|
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
61
|
"path": "module.ts",
|
|
62
|
-
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport {\n createDealsStore,\n makeDealsScreen,\n makeDealsWatcher,\n} from \"./DealsScreen\";\nimport { t } from \"./i18n\";\n\n// Special offers as a feature of the game. The always-on watcher pops a newly started deal up by\n// itself (and records the impression); the screen lists every active deal. Badge: free steps and\n// milestone rewards waiting.\nexport const dealsModule: Module = defineModule({\n id: \"deals\",\n meta: { name: \"Offers\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n const store = createDealsStore(ctx.features);\n ctx.features.register({\n id: \"deals\",\n label: t(\"title\"),\n icon: \"offer\",\n group: \"economy\",\n order: 15,\n available: false,\n Screen: makeDealsScreen(store),\n });\n // The tab shows while a deal is running — the watcher loads them at start.\n store.subscribe(() =>\n ctx.features.setAvailable(\n \"deals\",\n (store.get()?.length ?? 0) > 0,\n \"no active deal right now (DealOffer slots)\",\n ),\n );\n ctx.registerPanel({\n id: \"auto\",\n slot: \"modal\",\n activeOnly: false,\n component: makeDealsWatcher(store),\n });\n ctx.exposeToAgent({\n state: () => ({\n ui: \"dom\",\n feature: \"deals\",\n active: store.get()?.map((s) => s.SlotID) ?? [],\n }),\n describeActions: {},\n });\n },\n});\n"
|
|
62
|
+
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport {\n createDealsStore,\n makeDealsScreen,\n makeDealsWatcher,\n} from \"./DealsScreen\";\nimport { t } from \"./i18n\";\n\n// Special offers as a feature of the game. The always-on watcher pops a newly started deal up by\n// itself (and records the impression); the screen lists every active deal. Badge: free steps and\n// milestone rewards waiting.\nexport const dealsModule: Module = defineModule({\n id: \"deals\",\n meta: { name: \"Offers\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n const store = createDealsStore(ctx.features);\n ctx.features.register({\n id: \"deals\",\n label: () => t(\"title\"),\n icon: \"offer\",\n group: \"economy\",\n order: 15,\n available: false,\n Screen: makeDealsScreen(store),\n });\n // The tab shows while a deal is running — the watcher loads them at start.\n store.subscribe(() =>\n ctx.features.setAvailable(\n \"deals\",\n (store.get()?.length ?? 0) > 0,\n \"no active deal right now (DealOffer slots)\",\n ),\n );\n ctx.registerPanel({\n id: \"auto\",\n slot: \"modal\",\n activeOnly: false,\n component: makeDealsWatcher(store),\n });\n ctx.exposeToAgent({\n state: () => ({\n ui: \"dom\",\n feature: \"deals\",\n active: store.get()?.map((s) => s.SlotID) ?? [],\n }),\n describeActions: {},\n });\n },\n});\n"
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
"path": "module.meta.json",
|
|
66
|
-
"content": "{\n \"id\": \"deals\",\n \"type\": \"feature\",\n \"summary\": \"Special offers for any game: a new deal pops up by itself; single offers, step chains and pick-one gifts with a milestone bar.\",\n \"description\": \"Special offers (Unity Alikhan/DealOffer) for ANY game, built on the @idosgames/react/ui kit and client.dealOffer. An always-on watcher pops a newly started deal up by itself once (and records the impression with recordShow); the 'Offers' screen lists every active deal with its timer and everything it can give. A deal opens as a popup shaped by its node graph: one big offer, a chain of steps (each unlocks the next, the server decides status), or cards to pick one from; free steps, currency prices, store-only steps and the milestone bar with its rewards. Registers the 'deals' feature; its badge counts free steps and milestone rewards waiting. Ships title-seed.json: a three-step starter pack with a bonus and a free pick-one welcome gift.\",\n \"provides\": [\n \"special offers screen\",\n \"auto-popup of a new deal\",\n \"single, chain and pick-one offers\",\n \"offer milestones\",\n \"deals badge\",\n \"demo offers\"\n ],\n \"tags\": [\n \"offers\",\n \"deals\",\n \"starter-pack\",\n \"monetization\",\n \"popup\",\n \"ui\",\n \"screen\",\n \"economy\"\n ],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.
|
|
66
|
+
"content": "{\n \"id\": \"deals\",\n \"type\": \"feature\",\n \"summary\": \"Special offers for any game: a new deal pops up by itself; single offers, step chains and pick-one gifts with a milestone bar.\",\n \"description\": \"Special offers (Unity Alikhan/DealOffer) for ANY game, built on the @idosgames/react/ui kit and client.dealOffer. An always-on watcher pops a newly started deal up by itself once (and records the impression with recordShow); the 'Offers' screen lists every active deal with its timer and everything it can give. A deal opens as a popup shaped by its node graph: one big offer, a chain of steps (each unlocks the next, the server decides status), or cards to pick one from; free steps, currency prices, store-only steps and the milestone bar with its rewards. Registers the 'deals' feature; its badge counts free steps and milestone rewards waiting. Ships title-seed.json: a three-step starter pack with a bonus and a free pick-one welcome gift.\",\n \"provides\": [\n \"special offers screen\",\n \"auto-popup of a new deal\",\n \"single, chain and pick-one offers\",\n \"offer milestones\",\n \"deals badge\",\n \"demo offers\"\n ],\n \"tags\": [\n \"offers\",\n \"deals\",\n \"starter-pack\",\n \"monetization\",\n \"popup\",\n \"ui\",\n \"screen\",\n \"economy\"\n ],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.2\"\n}\n"
|
|
67
67
|
}
|
|
68
68
|
]
|
|
69
69
|
}
|
|
@@ -34,15 +34,15 @@
|
|
|
34
34
|
"name": "iDos Games",
|
|
35
35
|
"url": "https://idosgames.com"
|
|
36
36
|
},
|
|
37
|
-
"version": "0.1.
|
|
37
|
+
"version": "0.1.2"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@idosgames/core": "0.21.
|
|
41
|
-
"@idosgames/module-sdk": "0.
|
|
42
|
-
"@idosgames/react": "0.
|
|
40
|
+
"@idosgames/core": "0.21.6",
|
|
41
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
42
|
+
"@idosgames/react": "0.5.0",
|
|
43
43
|
"react": "19.2.7"
|
|
44
44
|
},
|
|
45
|
-
"contentHash": "
|
|
45
|
+
"contentHash": "c3172782893c86d170bbd96c9a2dfbf9bab9ab5e2780c67d72f598ce8bc43753",
|
|
46
46
|
"files": [
|
|
47
47
|
{
|
|
48
48
|
"path": "EventsScreen.tsx",
|
|
@@ -62,11 +62,11 @@
|
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
"path": "module.ts",
|
|
65
|
-
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport {\n createEventsStore,\n makeEventsScreen,\n watchEvents,\n} from \"./EventsScreen\";\nimport { t } from \"./i18n\";\n\n// Limited-time events as a feature of the game. The always-on watcher keeps the badge current\n// (milestones and VIP top-ups waiting); the screen shows every active event as a tab.\nexport const eventsModule: Module = defineModule({\n id: \"events\",\n meta: { name: \"Events\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n const store = createEventsStore(ctx.features);\n ctx.features.register({\n id: \"events\",\n label: t(\"title\"),\n icon: \"flame\",\n group: \"events\",\n order: 25,\n available: false,\n Screen: makeEventsScreen(store),\n });\n // The tab shows while an event is running — the watcher loads them at start.\n store.subscribe(() =>\n ctx.features.setAvailable(\n \"events\",\n (store.get()?.length ?? 0) > 0,\n \"no active event right now (TimedEvent)\",\n ),\n );\n watchEvents(ctx, store);\n ctx.exposeToAgent({\n state: () => ({\n ui: \"dom\",\n feature: \"events\",\n active: store.get()?.map((e) => e.TimedEventID) ?? [],\n }),\n describeActions: {},\n });\n },\n});\n"
|
|
65
|
+
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport {\n createEventsStore,\n makeEventsScreen,\n watchEvents,\n} from \"./EventsScreen\";\nimport { t } from \"./i18n\";\n\n// Limited-time events as a feature of the game. The always-on watcher keeps the badge current\n// (milestones and VIP top-ups waiting); the screen shows every active event as a tab.\nexport const eventsModule: Module = defineModule({\n id: \"events\",\n meta: { name: \"Events\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n const store = createEventsStore(ctx.features);\n ctx.features.register({\n id: \"events\",\n label: () => t(\"title\"),\n icon: \"flame\",\n group: \"events\",\n order: 25,\n available: false,\n Screen: makeEventsScreen(store),\n });\n // The tab shows while an event is running — the watcher loads them at start.\n store.subscribe(() =>\n ctx.features.setAvailable(\n \"events\",\n (store.get()?.length ?? 0) > 0,\n \"no active event right now (TimedEvent)\",\n ),\n );\n watchEvents(ctx, store);\n ctx.exposeToAgent({\n state: () => ({\n ui: \"dom\",\n feature: \"events\",\n active: store.get()?.map((e) => e.TimedEventID) ?? [],\n }),\n describeActions: {},\n });\n },\n});\n"
|
|
66
66
|
},
|
|
67
67
|
{
|
|
68
68
|
"path": "module.meta.json",
|
|
69
|
-
"content": "{\n \"id\": \"events\",\n \"type\": \"feature\",\n \"summary\": \"Limited-time events for any game: event tabs with a timer, a token bar, a milestone track, claim all and a VIP second prize.\",\n \"description\": \"A ready events screen (Unity Core/Window LimitedTimeEvent) for ANY game, built on the @idosgames/react/ui kit and client.timedEvent. Every active event the server resolves (scheduled, cyclic or chained) is a tab: its name and timer, the token bar toward the next prize and the milestone track in threshold order. A milestone pays its reward and, when the reward has premium tiers, a VIP second prize; a pass bought later tops up the milestones already claimed. 'Claim all' takes everything waiting in one call. How the tokens are earned (the event's token sources with their daily caps) is a popup; 'Get VIP' opens the VIP system (ctx.features.open('premium', { premiumID })) and shows only when it is installed and has a pass. Registers the 'events' feature; its badge counts milestones and VIP top-ups waiting. Tokens come from the game: a round of play is a CustomAction the game grants with client.timedEvent.grantTokens (the mini-game module does it for every active event that lists the action). Ships title-seed.json: a weekly 'Star festival' with five milestones and a VIP prize on each.\",\n \"provides\": [\n \"events screen with a tab per active event\",\n \"event timer and token progress bar\",\n \"milestone track with rewards\",\n \"VIP second prize and top-up after purchase\",\n \"claim all milestones\",\n \"how-to-earn popup with daily caps\",\n \"hand-off to the VIP system\",\n \"events badge\",\n \"demo weekly event\"\n ],\n \"tags\": [\n \"events\",\n \"live-ops\",\n \"limited-time\",\n \"milestones\",\n \"battle-pass\",\n \"vip\",\n \"ui\",\n \"screen\"\n ],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.
|
|
69
|
+
"content": "{\n \"id\": \"events\",\n \"type\": \"feature\",\n \"summary\": \"Limited-time events for any game: event tabs with a timer, a token bar, a milestone track, claim all and a VIP second prize.\",\n \"description\": \"A ready events screen (Unity Core/Window LimitedTimeEvent) for ANY game, built on the @idosgames/react/ui kit and client.timedEvent. Every active event the server resolves (scheduled, cyclic or chained) is a tab: its name and timer, the token bar toward the next prize and the milestone track in threshold order. A milestone pays its reward and, when the reward has premium tiers, a VIP second prize; a pass bought later tops up the milestones already claimed. 'Claim all' takes everything waiting in one call. How the tokens are earned (the event's token sources with their daily caps) is a popup; 'Get VIP' opens the VIP system (ctx.features.open('premium', { premiumID })) and shows only when it is installed and has a pass. Registers the 'events' feature; its badge counts milestones and VIP top-ups waiting. Tokens come from the game: a round of play is a CustomAction the game grants with client.timedEvent.grantTokens (the mini-game module does it for every active event that lists the action). Ships title-seed.json: a weekly 'Star festival' with five milestones and a VIP prize on each.\",\n \"provides\": [\n \"events screen with a tab per active event\",\n \"event timer and token progress bar\",\n \"milestone track with rewards\",\n \"VIP second prize and top-up after purchase\",\n \"claim all milestones\",\n \"how-to-earn popup with daily caps\",\n \"hand-off to the VIP system\",\n \"events badge\",\n \"demo weekly event\"\n ],\n \"tags\": [\n \"events\",\n \"live-ops\",\n \"limited-time\",\n \"milestones\",\n \"battle-pass\",\n \"vip\",\n \"ui\",\n \"screen\"\n ],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.2\"\n}\n"
|
|
70
70
|
}
|
|
71
71
|
]
|
|
72
72
|
}
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
"name": "iDos Games",
|
|
33
33
|
"url": "https://idosgames.com"
|
|
34
34
|
},
|
|
35
|
-
"version": "0.1.
|
|
35
|
+
"version": "0.1.2"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@idosgames/core": "0.21.
|
|
39
|
-
"@idosgames/module-sdk": "0.
|
|
40
|
-
"@idosgames/react": "0.
|
|
38
|
+
"@idosgames/core": "0.21.6",
|
|
39
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
40
|
+
"@idosgames/react": "0.5.0",
|
|
41
41
|
"react": "19.2.7"
|
|
42
42
|
},
|
|
43
|
-
"contentHash": "
|
|
43
|
+
"contentHash": "4e73bcfda1814bd4cc118ca318056e2d32d238e392c5c9cc2002fa892c223433",
|
|
44
44
|
"files": [
|
|
45
45
|
{
|
|
46
46
|
"path": "components/AddFriendPopup.tsx",
|
|
@@ -80,11 +80,11 @@
|
|
|
80
80
|
},
|
|
81
81
|
{
|
|
82
82
|
"path": "module.ts",
|
|
83
|
-
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { makeFriendsScreen, watchFriends } from \"./FriendsScreen\";\nimport { t } from \"./i18n\";\n\n// Friends as a feature of the game. The always-on watcher keeps the badge: requests waiting for an\n// answer (a counter that comes with the player state) and unread notifications.\nexport const friendsModule: Module = defineModule({\n id: \"friends\",\n meta: { name: \"Friends\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"friends\",\n label: t(\"title\"),\n icon: \"friends\",\n group: \"social\",\n order: 80,\n Screen: makeFriendsScreen(ctx.features),\n });\n watchFriends(ctx);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"friends\" }),\n describeActions: {},\n });\n },\n});\n"
|
|
83
|
+
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { makeFriendsScreen, watchFriends } from \"./FriendsScreen\";\nimport { t } from \"./i18n\";\n\n// Friends as a feature of the game. The always-on watcher keeps the badge: requests waiting for an\n// answer (a counter that comes with the player state) and unread notifications.\nexport const friendsModule: Module = defineModule({\n id: \"friends\",\n meta: { name: \"Friends\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"friends\",\n label: () => t(\"title\"),\n icon: \"friends\",\n group: \"social\",\n order: 80,\n Screen: makeFriendsScreen(ctx.features),\n });\n watchFriends(ctx);\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"friends\" }),\n describeActions: {},\n });\n },\n});\n"
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
86
|
"path": "module.meta.json",
|
|
87
|
-
"content": "{\n \"id\": \"friends\",\n \"type\": \"feature\",\n \"inBase\": true,\n \"summary\": \"Friends for any game: the friends list, requests, suggestions and the notification inbox, with a player card and add-by-ID in popups.\",\n \"description\": \"A ready friends screen (Unity Runtime/UI/Friends) for ANY game, built on the @idosgames/react/ui kit and client.social. Tabs: friends, requests (incoming with accept / decline, and the ones you sent), suggestions (players active in this game lately) and news — the notification inbox (attacks, raids, new friends, sales, follows, likes, comments), opened as seen. The player's own ID sits on top with a copy button. Everything detailed is a popup: adding a friend by ID, the player card (level, power; message — opens the chat feature when chat is installed; remove friend; block) and the confirmations. When the title takes friends from idosgames.com only, requests, suggestions and 'Add' disappear and platform friends cannot be removed in the game. Registers the 'friends' feature; its badge counts requests waiting and unread news. No title settings needed.\",\n \"provides\": [\n \"friends list\",\n \"incoming and sent friend requests\",\n \"friend suggestions\",\n \"notification inbox\",\n \"add a friend by ID\",\n \"player card with message, remove and block\",\n \"friends badge\"\n ],\n \"tags\": [\n \"friends\",\n \"social\",\n \"requests\",\n \"inbox\",\n \"notifications\",\n \"ui\",\n \"screen\"\n ],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.
|
|
87
|
+
"content": "{\n \"id\": \"friends\",\n \"type\": \"feature\",\n \"inBase\": true,\n \"summary\": \"Friends for any game: the friends list, requests, suggestions and the notification inbox, with a player card and add-by-ID in popups.\",\n \"description\": \"A ready friends screen (Unity Runtime/UI/Friends) for ANY game, built on the @idosgames/react/ui kit and client.social. Tabs: friends, requests (incoming with accept / decline, and the ones you sent), suggestions (players active in this game lately) and news — the notification inbox (attacks, raids, new friends, sales, follows, likes, comments), opened as seen. The player's own ID sits on top with a copy button. Everything detailed is a popup: adding a friend by ID, the player card (level, power; message — opens the chat feature when chat is installed; remove friend; block) and the confirmations. When the title takes friends from idosgames.com only, requests, suggestions and 'Add' disappear and platform friends cannot be removed in the game. Registers the 'friends' feature; its badge counts requests waiting and unread news. No title settings needed.\",\n \"provides\": [\n \"friends list\",\n \"incoming and sent friend requests\",\n \"friend suggestions\",\n \"notification inbox\",\n \"add a friend by ID\",\n \"player card with message, remove and block\",\n \"friends badge\"\n ],\n \"tags\": [\n \"friends\",\n \"social\",\n \"requests\",\n \"inbox\",\n \"notifications\",\n \"ui\",\n \"screen\"\n ],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.2\"\n}\n"
|
|
88
88
|
}
|
|
89
89
|
]
|
|
90
90
|
}
|
|
@@ -72,9 +72,9 @@
|
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
|
-
"@idosgames/core": "0.21.
|
|
76
|
-
"@idosgames/module-sdk": "0.
|
|
77
|
-
"@idosgames/react": "0.
|
|
75
|
+
"@idosgames/core": "0.21.6",
|
|
76
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
77
|
+
"@idosgames/react": "0.5.0",
|
|
78
78
|
"phaser": "4.2.1",
|
|
79
79
|
"react": "19.2.7"
|
|
80
80
|
},
|
|
@@ -29,15 +29,15 @@
|
|
|
29
29
|
"name": "iDos Games",
|
|
30
30
|
"url": "https://idosgames.com"
|
|
31
31
|
},
|
|
32
|
-
"version": "0.1.
|
|
32
|
+
"version": "0.1.1"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@idosgames/core": "0.21.
|
|
36
|
-
"@idosgames/module-sdk": "0.
|
|
37
|
-
"@idosgames/react": "0.
|
|
35
|
+
"@idosgames/core": "0.21.6",
|
|
36
|
+
"@idosgames/module-sdk": "0.11.0",
|
|
37
|
+
"@idosgames/react": "0.5.0",
|
|
38
38
|
"react": "19.2.7"
|
|
39
39
|
},
|
|
40
|
-
"contentHash": "
|
|
40
|
+
"contentHash": "0b02bc09a1a29ecb6d08fa281dfe316b01f8f341350ba27f386a05572827700e",
|
|
41
41
|
"files": [
|
|
42
42
|
{
|
|
43
43
|
"path": "i18n.ts",
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
59
|
"path": "module.ts",
|
|
60
|
-
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { makeInventoryScreen } from \"./InventoryScreen\";\nimport { t } from \"./i18n\";\n\n// The inventory as a feature of the game. Always in the lobby (owner's decision 29.09.2026), even on a\n// title without items yet — the screen then says so. Chests and keys hand off to the lootboxes system.\nexport const inventoryModule: Module = defineModule({\n id: \"inventory\",\n meta: { name: \"Inventory\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"inventory\",\n label: t(\"title\"),\n icon: \"box\",\n group: \"economy\",\n order: 50,\n primary: true,\n Screen: makeInventoryScreen(ctx.features),\n });\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"inventory\" }),\n describeActions: {},\n });\n },\n});\n"
|
|
60
|
+
"content": "import { defineModule, type Module } from \"@idosgames/module-sdk\";\nimport { makeInventoryScreen } from \"./InventoryScreen\";\nimport { t } from \"./i18n\";\n\n// The inventory as a feature of the game. Always in the lobby (owner's decision 29.09.2026), even on a\n// title without items yet — the screen then says so. Chests and keys hand off to the lootboxes system.\nexport const inventoryModule: Module = defineModule({\n id: \"inventory\",\n meta: { name: \"Inventory\", type: \"app\", engine: \"dom\" },\n setup(ctx) {\n ctx.features.register({\n id: \"inventory\",\n label: () => t(\"title\"),\n icon: \"box\",\n group: \"economy\",\n order: 50,\n primary: true,\n Screen: makeInventoryScreen(ctx.features),\n });\n ctx.exposeToAgent({\n state: () => ({ ui: \"dom\", feature: \"inventory\" }),\n describeActions: {},\n });\n },\n});\n"
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
"path": "module.meta.json",
|
|
64
|
-
"content": "{\n \"id\": \"inventory\",\n \"type\": \"feature\",\n \"inBase\": true,\n \"summary\": \"Inventory screen for any game: owned items by rarity with category tabs and item cards.\",\n \"description\": \"A ready inventory for ANY game, built on the @idosgames/react/ui kit. It shows what the player owns from the SDK's cached inventory (no request of its own): category tabs (equipment, consumables, other), rarity frames, counts and levels, and an item card popup with the description. Equipment hands off to the heroes screen (ctx.features.open('character', { itemInstanceID })) and a chest or key item to the chests screen (ctx.features.open('lootboxes', { itemID })) when those systems are installed. Registers the 'inventory' feature — always shown in the lobby, even before the title has items.\",\n \"provides\": [\n \"owned items grid by rarity\",\n \"category tabs\",\n \"item card popup\",\n \"hand-off of equipment to the heroes screen\",\n \"hand-off of chests and keys to the chests screen\"\n ],\n \"tags\": [\"inventory\", \"items\", \"rarity\", \"ui\", \"screen\", \"economy\"],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.
|
|
64
|
+
"content": "{\n \"id\": \"inventory\",\n \"type\": \"feature\",\n \"inBase\": true,\n \"summary\": \"Inventory screen for any game: owned items by rarity with category tabs and item cards.\",\n \"description\": \"A ready inventory for ANY game, built on the @idosgames/react/ui kit. It shows what the player owns from the SDK's cached inventory (no request of its own): category tabs (equipment, consumables, other), rarity frames, counts and levels, and an item card popup with the description. Equipment hands off to the heroes screen (ctx.features.open('character', { itemInstanceID })) and a chest or key item to the chests screen (ctx.features.open('lootboxes', { itemID })) when those systems are installed. Registers the 'inventory' feature — always shown in the lobby, even before the title has items.\",\n \"provides\": [\n \"owned items grid by rarity\",\n \"category tabs\",\n \"item card popup\",\n \"hand-off of equipment to the heroes screen\",\n \"hand-off of chests and keys to the chests screen\"\n ],\n \"tags\": [\"inventory\", \"items\", \"rarity\", \"ui\", \"screen\", \"economy\"],\n \"author\": {\n \"name\": \"iDos Games\",\n \"url\": \"https://idosgames.com\"\n },\n \"version\": \"0.1.1\"\n}\n"
|
|
65
65
|
}
|
|
66
66
|
]
|
|
67
67
|
}
|