@idosgames/mcp 0.1.20 → 0.1.21

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.
Files changed (36) hide show
  1. package/package.json +1 -1
  2. package/registry/host.json +10 -10
  3. package/registry/index.json +107 -107
  4. package/registry/modules/ai.json +6 -6
  5. package/registry/modules/board-game.json +2 -2
  6. package/registry/modules/boosts.json +2 -2
  7. package/registry/modules/character.json +6 -6
  8. package/registry/modules/chat.json +6 -6
  9. package/registry/modules/collections.json +6 -6
  10. package/registry/modules/coop-events.json +6 -6
  11. package/registry/modules/craft.json +6 -6
  12. package/registry/modules/deals.json +6 -6
  13. package/registry/modules/events.json +6 -6
  14. package/registry/modules/friends.json +6 -6
  15. package/registry/modules/idle-rpg.json +2 -2
  16. package/registry/modules/inventory.json +2 -2
  17. package/registry/modules/invite.json +6 -6
  18. package/registry/modules/leaderboard.json +6 -6
  19. package/registry/modules/lootboxes.json +2 -2
  20. package/registry/modules/mailbox.json +2 -2
  21. package/registry/modules/marketplace.json +6 -6
  22. package/registry/modules/mini-game.json +6 -6
  23. package/registry/modules/multiplayer.json +6 -6
  24. package/registry/modules/premium.json +6 -6
  25. package/registry/modules/profile.json +6 -6
  26. package/registry/modules/pvp.json +2 -2
  27. package/registry/modules/quests.json +2 -2
  28. package/registry/modules/rewards.json +6 -6
  29. package/registry/modules/season.json +6 -6
  30. package/registry/modules/store.json +6 -6
  31. package/registry/modules/tutorials.json +6 -6
  32. package/registry/modules/voxelcraft.json +5 -5
  33. package/registry/modules/workshop.json +6 -6
  34. package/registry/skills/idosgames-module-contract.json +1 -1
  35. package/registry/skills/idosgames-project-structure.json +1 -1
  36. package/registry/skills/idosgames-ui-kit.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "idosgames-ui-kit",
3
3
  "description": "Build and restyle game screens with the iDosGames UI kit (@idosgames/react/ui) and the ready system modules (store, character, inventory, …): change colours, animations and sounds in ONE file (src/ui.config.ts), install a shop / VIP / heroes / inventory / chests / boosts / leaderboard / daily rewards / quests / collections / craft / marketplace / offers / events / team event / season / friends / chat / invite / arena / multiplayer rooms / profile / tutorials / workshop / AI studio system instead of writing it, open another module's screen with ctx.features.open, register a new screen (a lobby tab) with ctx.features.register and hide it while the title has no data (setAvailable), split a dense screen into popups (Popup, ConfirmPopup, bottom sheet on a phone), play UI sounds, celebrate a reward (icons fly to the balance counters), mark elements for tutorial hints (data-tutorial-anchor), and read the player's sound / motion prefs. Use this whenever the user asks to change how the game's interface looks, sounds or animates, to add or build a game screen or menu, a popup, a reward animation, a bottom navigation, a \"More\" menu, a settings screen, or touches @idosgames/react/ui, defineUiConfig, ui.config.ts, ctx.features, FeatureScreenProps, useCelebrate, usePlayerPrefs, Popup, Tabs or ResourceList.",
4
- "content": "---\nname: idosgames-ui-kit\ndescription: >-\n Build and restyle game screens with the iDosGames UI kit (@idosgames/react/ui) and the ready\n system modules (store, character, inventory, …): change colours, animations and sounds in ONE file (src/ui.config.ts),\n install a shop / VIP / heroes / inventory / chests / boosts / leaderboard / daily rewards / quests /\n collections / craft / marketplace / offers / events / team event / season / friends / chat / invite /\n arena / multiplayer rooms / profile / tutorials / workshop / AI studio system instead of writing it, open another module's screen with ctx.features.open, register a new screen (a lobby\n tab) with ctx.features.register and hide it while the title has no data (setAvailable), split a dense screen into popups (Popup, ConfirmPopup, bottom sheet on a\n phone), play UI sounds, celebrate a reward (icons fly to the balance counters), mark elements for\n tutorial hints (data-tutorial-anchor), and read the player's sound / motion prefs. Use this\n whenever the user asks to change how the game's interface looks, sounds or animates, to add or\n build a game screen or menu, a popup, a reward animation, a bottom navigation, a \"More\" menu, a\n settings screen, or touches @idosgames/react/ui, defineUiConfig, ui.config.ts, ctx.features,\n FeatureScreenProps, useCelebrate, usePlayerPrefs, Popup, Tabs or ResourceList.\n---\n\n# The UI kit and the system modules\n\nThe app's interface is the base's lobby (`src/base/`) plus **system modules**, all on one **UI kit**:\n\n- `@idosgames/react/ui` — the kit: components (buttons, tabs, popups, resource lists, item tiles,\n progress bars, timers), the reward popup, toasts, UI sounds (synthesized, no files), animations,\n and the player's own sound / motion prefs.\n- system modules — the platform's systems, each a whole `feature` module (its screen = a lobby\n tab, its client logic, its demo settings). The base installs six of them into every new project\n (`inBase`: profile, inventory, invite, friends, quests, mailbox); the rest are installed only when the app\n needs them (a game's `uses`, or a task that needs what they `provide`). ONE system per player-facing module of the engine\n (`API/Client/v2/<Module>`) — the owner's rule since 29.09.2026. The module id is the feature id:\n\n| Module | Engine module | Screen |\n| ------------- | -------------- | ------------------------------------------------------------- |\n| `store` | Store+Purchase | shop: stores as tabs, offers, purchase popup |\n| `premium` | Premium | VIP passes: benefits, timer, free trial, buy / extend |\n| `character` | Character | heroes: gear slots, \"Equip best\", stats, ranks, skins |\n| `inventory` | Item | items by rarity, item card (always shown, even with no items) |\n| `lootboxes` | Lootbox | chests: every way to open, ×1 / ×10, opening animation |\n| `boosts` | TimedBoost | running boosts + global happy hours, activate a boost |\n| `leaderboard` | Leaderboard | tables, my place, rank rewards, last cycle's prize |\n| `rewards` | Reward | daily login calendar, greeting popup |\n| `quests` | Quest | quests by cycle, details, claim all, points track |\n| `collections` | Collection | album of sets, packs, chests for points, card trades |\n| `craft` | Craft | recipes, contract popup |\n| `marketplace` | Marketplace | lots, auctions, selling, trades |\n| `deals` | DealOffer | special offers, auto-popup of a new deal |\n| `events` | TimedEvent | limited-time events, milestones, VIP prize |\n| `coop-events` | CoopEvent | team event: join a group, spin to build, team prize |\n| `season` | Season | season tiers, VIP prize |\n| `friends` | Social | friends, requests, suggestions, news |\n| `chat` | Chat | channels, private chats |\n| `invite` | Referral | own code and link, friend's code, rewards (always shown) |\n| `pvp` | Match | duels, strategy, fight replay |\n| `multiplayer` | Multiplayer | rooms: list, create / join by code, ready, chat, host \"Play\" |\n| `profile` | User | name, sound, language, consent, delete account |\n| `tutorials` | Tutorial | hint overlay + replay list |\n| `workshop` | Workshop | players' and the publisher's content: catalog, publish |\n| `ai` | AI | AI studio: the title's AI features for players, history |\n\nNot a system on purpose: Currency, Authentication, Blockchain (the base — balances, sign-in,\nwallet); GameLoop (the `board-game` game); CommunityMarketing (idosgames.com only); Mailbox and\nAdvertising (no client handler / no web ad network); Analytics, Experiment, Push, Localization,\nCloudCode, DataCollections, TitleCustomData, UserCustomData (services the systems and games call).\n\nHand-offs between systems go through `ctx.features.open(id, args)`: inventory → `character`\n(`{ itemInstanceID }`) and → `lootboxes` (`{ itemID }` of a chest or key); events / season →\n`premium` (`{ premiumID }`). Multiplayer: the `multiplayer` system owns the rooms; a game registers\nin `ctx.multiplayer` and takes the room in `start(room)` (skill **multiplayer-realtime**); the lobby\nshows \"With friends\" next to such a game's \"Play\".\n\n**Need one of these? Install the module — don't write the screen.** Every screen follows the\nserver's rules and ships demo title settings (`title-seed.json`). The app does not need one → remove it\nfrom `src/modules.ts`, its tab is gone. The lobby itself (tabs, balances, wallet, profile, \"Play\") is\nthe base, `src/base/lobby/`.\n\n## Change the look, animations and sounds — only in `src/ui.config.ts`\n\n```ts\nimport { defineUiConfig } from \"@idosgames/react/ui\";\n\nexport default defineUiConfig({\n theme: {\n bgTop: \"#10263f\",\n panel: \"#1b3a5c\",\n gold: \"#ffcc33\",\n radius: 12,\n rarity: { Mythic: \"#ff3df5\" },\n },\n motion: { speed: 1.5, intensity: 0.5, particles: false },\n sound: {\n volume: 0.4,\n events: {\n click: \"tab\",\n countTick: false,\n reward: { url: \"https://…/win.mp3\" },\n },\n },\n});\n```\n\n- Every field is optional; what you leave out keeps its default. The host passes the file to\n `mountHost({ ui })`, and every module on the kit follows it at once.\n- ⚠ **Never restyle a catalog module by editing it.** An edited module is marked \"customized\" and\n stops getting catalog updates. Colours, radii, fonts, animation speed and sounds are all here.\n- Theme tokens: `bgTop`, `bgBottom`, `panel`, `panelDeep`, `panelEdge`, `text`, `textDim`, `gold`,\n `goldDeep`, `green`, `greenDeep`, `blue`, `blueDeep`, `red`, `shadow`, `backdrop`, `radius`,\n `buttonRadius`, `font`, `rarity` (rarity id → frame colour).\n- Motion: `enabled`, `speed` (2 = twice as fast), `intensity` (0 = no bounce), `rewardFlight`,\n `particles`, `stagger`, `respectReducedMotion`.\n- Sound events: `click`, `tab`, `open`, `close`, `reward`, `coin`, `purchase`, `claim`, `error`,\n `notify`, `lootbox`, `levelUp`, `countTick`. Each: another event's name, `{ url }`, `{ synth: {\nnotes: [{ freq, dur, wave }] } }` or `false`.\n- The PLAYER's own sound / volume / \"fewer animations\" live on the device (the profile module draws\n them):\n `const [prefs, setPrefs] = usePlayerPrefs()` → `{ muted, volume, reducedMotion }`.\n\n## Features: screens that find each other\n\nA module registers a **feature**; whoever draws the menu shows it — the base's lobby as tabs (phone:\n4 + \"More\", tablet: more, desktop: a side rail; the base takes the shared-UI role `\"menu\"`), or the\nhost's floating ☰ when nobody takes the role. Tab order and main tabs can be overridden in\n`src/app.config.ts` (`lobby.order`, `lobby.primary`).\n\n```ts\n// module.ts\nsetup(ctx) {\n ctx.features.register({\n id: \"forge\", label: \"Forge\", icon: \"hammer\", group: \"economy\", order: 60,\n primary: false, // true = a main tab of the lobby\n Screen: ForgeScreen, // (props: FeatureScreenProps) => ReactNode; props.args, props.close()\n available: false, // hidden until the title has something for it — see below\n });\n // Badge (\"something to claim\"): ctx.features.setBadge(\"forge\", 2)\n // The title has forge recipes → show the tab; the reason is for the AI Coder's agent only:\n ctx.features.setAvailable(\"forge\", hasRecipes(configSection(ctx.client, \"Craft\")), \"no forge recipes\");\n}\n```\n\n- Open another module's screen without importing it: `ctx.features.open(\"store\")`,\n `ctx.features.open(\"chat\", { userID })`. It returns `false` when the module is not installed or its\n tab is hidden (`ctx.features.get(\"store\")?.available`). From a game (the lobby is off screen) the\n host shows the screen in a window.\n- A screen that depends on title data registers with `available: false` and calls\n `ctx.features.setAvailable(id, ok, reason)` once it knows — from the client config\n (`configSection(client, \"Store\")`) or a read it makes anyway (a badge watcher); no extra request\n at start-up: every module's first reads arrive together and brush the per-player rate limit.\n- Groups: `economy`, `events`, `social`, `profile`. Icons are kit glyph names (`shop`, `hero`,\n `bag`, `trophy`, `gift`, `hammer`, `market`, `offer`, `flame`, `friends`, `chat`, `link`,\n `swords`, `user`, `bulb`, …) or an image URL.\n- Something that must be on screen all the time (a daily auto-popup, a badge watcher, an overlay) is\n a panel: `ctx.registerPanel({ id, slot: \"modal\", activeOnly: false, component })`.\n\n## Building a screen on the kit\n\nKeep the screen a short list; put every detail in a **popup**.\n\n```tsx\nimport {\n Button,\n Popup,\n ResourceList,\n Tabs,\n useCelebrate,\n useToast,\n useUiKit,\n errorText,\n grantedBy,\n panel,\n outlined,\n v,\n} from \"@idosgames/react/ui\";\n\nfunction ForgeScreen(): ReactNode {\n const [open, setOpen] = useState<string | null>(null);\n return (\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"minmax(0, 1fr)\",\n gap: 12,\n }}\n >\n {/* rows… onClick={() => setOpen(id)} */}\n {open ? (\n <Popup title=\"Forge\" onClose={() => setOpen(null)} width={420}>\n …\n </Popup>\n ) : null}\n </div>\n );\n}\n```\n\n- `Popup` is a bottom sheet on a phone and a centred window elsewhere (`variant=\"center\"` forces\n centred); it animates in and out and plays open/close sounds. Close from inside with\n `usePopupClose()`. `ConfirmPopup` for yes/no. A popup that opens BY ITSELF (not on a tap) passes\n `queued` — auto-popups then show one at a time instead of stacking.\n- `useCelebrate()(lines)` shows \"You got\" and flies the icons to any element marked\n `data-resource-counter=\"{currencyID}\"` (the lobby's balances are). Build the lines\n from a response with `grantedBy(data)`; a reward with premium (VIP) bundles needs them added.\n- `useUiKit().play(\"claim\")`, `useUiKit().fx.burst(element)` — a sound and a particle burst.\n- `useToast()(text, \"error\")` for refusals; show `errorText(res.error)`, never re-check server rules.\n- Lines of resources: `grantLines(grant)`, `costLines(cost)`, `bundleLines(bundle)`,\n `canAfford(lines, balances)`, `<ResourceList lines={…} />`. Names and icons: `useCatalog()`.\n- Words: `makeT(EN, RU)` for your strings, `plural(n, \"лот|лота|лотов\")` for counts.\n- ⚠ A root `display: grid` with a wide child (a row of tabs) grows past a phone screen — give it\n `gridTemplateColumns: \"minmax(0, 1fr)\"`.\n\n## Tutorial hints\n\nThe `tutorials` module highlights any element marked `data-tutorial-anchor=\"…\"` — the lobby's tabs\nare `tab:{featureID}`, its profile button `lobby:profile`, its wallet `lobby:wallet`, a game's \"Play\"\nbutton `play:{modeID}`. Mark the controls of your own screen the same\nway; the publisher points tutorial steps at them in LiveOps (Tutorial → step → AnchorID).\n",
4
+ "content": "---\nname: idosgames-ui-kit\ndescription: >-\n Build and restyle game screens with the iDosGames UI kit (@idosgames/react/ui) and the ready\n system modules (store, character, inventory, …): change colours, animations and sounds in ONE file (src/ui.config.ts),\n install a shop / VIP / heroes / inventory / chests / boosts / leaderboard / daily rewards / quests /\n collections / craft / marketplace / offers / events / team event / season / friends / chat / invite /\n arena / multiplayer rooms / profile / tutorials / workshop / AI studio system instead of writing it, open another module's screen with ctx.features.open, register a new screen (a lobby\n tab) with ctx.features.register and hide it while the title has no data (setAvailable), split a dense screen into popups (Popup, ConfirmPopup, bottom sheet on a\n phone), play UI sounds, celebrate a reward (icons fly to the balance counters), mark elements for\n tutorial hints (data-tutorial-anchor), and read the player's sound / motion prefs. Use this\n whenever the user asks to change how the game's interface looks, sounds or animates, to add or\n build a game screen or menu, a popup, a reward animation, a bottom navigation, a \"More\" menu, a\n settings screen, or touches @idosgames/react/ui, defineUiConfig, ui.config.ts, ctx.features,\n FeatureScreenProps, useCelebrate, usePlayerPrefs, Popup, Tabs or ResourceList.\n---\n\n# The UI kit and the system modules\n\nThe app's interface is the base's lobby (`src/base/`) plus **system modules**, all on one **UI kit**:\n\n- `@idosgames/react/ui` — the kit: components (buttons, tabs, popups, resource lists, item tiles,\n progress bars, timers), the reward popup, toasts, UI sounds (synthesized, no files), animations,\n and the player's own sound / motion prefs.\n- system modules — the platform's systems, each a whole `feature` module (its screen = a lobby\n tab, its client logic, its demo settings). The base installs six of them into every new project\n (`inBase`: profile, inventory, invite, friends, quests, mailbox); the rest are installed only when the app\n needs them (a game's `uses`, or a task that needs what they `provide`). ONE system per player-facing module of the engine\n (`API/Client/v2/<Module>`) — the owner's rule since 29.09.2026. The module id is the feature id:\n\n| Module | Engine module | Screen |\n| ------------- | -------------- | ------------------------------------------------------------- |\n| `store` | Store+Purchase | shop: stores as tabs, offers, purchase popup |\n| `premium` | Premium | VIP passes: benefits, timer, free trial, buy / extend |\n| `character` | Character | heroes: gear slots, \"Equip best\", stats, ranks, skins |\n| `inventory` | Item | items by rarity, item card (always shown, even with no items) |\n| `lootboxes` | Lootbox | chests: every way to open, ×1 / ×10, opening animation |\n| `boosts` | TimedBoost | running boosts + global happy hours, activate a boost |\n| `leaderboard` | Leaderboard | tables, my place, rank rewards, last cycle's prize |\n| `rewards` | Reward | daily login calendar, greeting popup |\n| `quests` | Quest | quests by cycle, details, claim all, points track |\n| `collections` | Collection | album of sets, packs, chests for points, card trades |\n| `craft` | Craft | recipes, contract popup |\n| `marketplace` | Marketplace | lots, auctions, selling, trades |\n| `deals` | DealOffer | special offers, auto-popup of a new deal |\n| `events` | TimedEvent | limited-time events, milestones, VIP prize |\n| `coop-events` | CoopEvent | team event: join a group, spin to build, team prize |\n| `season` | Season | season tiers, VIP prize |\n| `friends` | Social | friends, requests, suggestions, news |\n| `chat` | Chat | channels, private chats |\n| `invite` | Referral | own code and link, friend's code, rewards (always shown) |\n| `pvp` | Match | duels, strategy, fight replay |\n| `multiplayer` | Multiplayer | rooms: list, create / join by code, ready, chat, host \"Play\" |\n| `profile` | User | name, sound, language, consent, delete account |\n| `tutorials` | Tutorial | hint overlay + replay list |\n| `workshop` | Workshop | players' and the publisher's content: catalog, publish |\n| `ai` | AI | AI studio: the title's AI features for players, history |\n\nNot a system on purpose: Currency, Authentication, Blockchain (the base — balances, sign-in,\nwallet); GameLoop (the `board-game` game); CommunityMarketing (idosgames.com only); Mailbox and\nAdvertising (no client handler / no web ad network); Analytics, Experiment, Push, Localization,\nCloudCode, DataCollections, TitleCustomData, UserCustomData (services the systems and games call).\n\nHand-offs between systems go through `ctx.features.open(id, args)`: inventory → `character`\n(`{ itemInstanceID }`) and → `lootboxes` (`{ itemID }` of a chest or key); events / season →\n`premium` (`{ premiumID }`). Multiplayer: the `multiplayer` system owns the rooms; a game registers\nin `ctx.multiplayer` and takes the room in `start(room)` (skill **multiplayer-realtime**); the lobby\nshows \"With friends\" next to such a game's \"Play\".\n\n**Need one of these? Install the module — don't write the screen.** Every screen follows the\nserver's rules and ships demo title settings (`title-seed.json`). The app does not need one → remove it\nfrom `src/modules.ts`, its tab is gone. The lobby itself (tabs, balances, wallet, profile, \"Play\") is\nthe base, `src/base/lobby/`.\n\n## Change the look, animations and sounds — only in `src/ui.config.ts`\n\n```ts\nimport { defineUiConfig } from \"@idosgames/react/ui\";\n\nexport default defineUiConfig({\n theme: {\n bgTop: \"#10263f\",\n panel: \"#1b3a5c\",\n gold: \"#ffcc33\",\n radius: 12,\n rarity: { Mythic: \"#ff3df5\" },\n },\n motion: { speed: 1.5, intensity: 0.5, particles: false },\n sound: {\n volume: 0.4,\n events: {\n click: \"tab\",\n countTick: false,\n reward: { url: \"https://…/win.mp3\" },\n },\n },\n});\n```\n\n- Every field is optional; what you leave out keeps its default. The host passes the file to\n `mountHost({ ui })`, and every module on the kit follows it at once.\n- ⚠ **Never restyle a catalog module by editing it.** An edited module is marked \"customized\" and\n stops getting catalog updates. Colours, radii, fonts, animation speed and sounds are all here.\n- **One theme for the WHOLE app:** sign-in (`src/base/login/`), the lobby, every system and the host's\n own screens all draw from these tokens. A new look — even a light theme — is an edit of this file\n ONLY: never recolour `LoginScreen.tsx`, the logo, icons or `index.html` by hand (the logo and the\n sign-in icons are painted with the theme's colours, the page background follows `bgBottom`).\n- Theme tokens: `bgTop`, `bgBottom`, `panel`, `panelDeep`, `panelEdge`, `text`, `textDim`, `gold`,\n `goldDeep`, `green`, `greenDeep`, `blue`, `blueDeep`, `red`, `redDeep`, `shadow`, `backdrop`,\n `radius`, `buttonRadius`, `font`, `rarity` (rarity id → frame colour).\n- **Derived tokens — usually leave them out.** They are computed from the colours above: set a light\n `panel` and dark `text`, and the dark text outline disappears (`textOutline`), lines and recesses\n turn faint-dark instead of white/black (`line`, `well`, `wellSoft`, `wellShadow`, `edge`), cards get a\n soft shadow (`panelShadow`), and buttons of a pastel tone get dark text (`onGreen`, `onGold`,\n `onBlue`, `onRed`). Set one only to override the computed value.\n- A light theme is just colours:\n `theme: { bgTop: \"#f4fcf8\", bgBottom: \"#d9f0e6\", panel: \"#ffffff\", panelDeep: \"#f1faf5\",\npanelEdge: \"#bfe6d3\", text: \"#1f3b30\", textDim: \"#5f7d71\", green: \"#7ee0b5\", greenDeep: \"#4cc493\" }`.\n- Motion: `enabled`, `speed` (2 = twice as fast), `intensity` (0 = no bounce), `rewardFlight`,\n `particles`, `stagger`, `respectReducedMotion`.\n- Sound events: `click`, `tab`, `open`, `close`, `reward`, `coin`, `purchase`, `claim`, `error`,\n `notify`, `lootbox`, `levelUp`, `countTick`. Each: another event's name, `{ url }`, `{ synth: {\nnotes: [{ freq, dur, wave }] } }` or `false`.\n- The PLAYER's own sound / volume / \"fewer animations\" live on the device (the profile module draws\n them):\n `const [prefs, setPrefs] = usePlayerPrefs()` → `{ muted, volume, reducedMotion }`.\n\n## Features: screens that find each other\n\nA module registers a **feature**; whoever draws the menu shows it — the base's lobby as tabs (phone:\n4 + \"More\", tablet: more, desktop: a side rail; the base takes the shared-UI role `\"menu\"`), or the\nhost's floating ☰ when nobody takes the role. Tab order and main tabs can be overridden in\n`src/app.config.ts` (`lobby.order`, `lobby.primary`).\n\n```ts\n// module.ts\nsetup(ctx) {\n ctx.features.register({\n id: \"forge\", label: \"Forge\", icon: \"hammer\", group: \"economy\", order: 60,\n primary: false, // true = a main tab of the lobby\n Screen: ForgeScreen, // (props: FeatureScreenProps) => ReactNode; props.args, props.close()\n available: false, // hidden until the title has something for it — see below\n });\n // Badge (\"something to claim\"): ctx.features.setBadge(\"forge\", 2)\n // The title has forge recipes → show the tab; the reason is for the AI Coder's agent only:\n ctx.features.setAvailable(\"forge\", hasRecipes(configSection(ctx.client, \"Craft\")), \"no forge recipes\");\n}\n```\n\n- Open another module's screen without importing it: `ctx.features.open(\"store\")`,\n `ctx.features.open(\"chat\", { userID })`. It returns `false` when the module is not installed or its\n tab is hidden (`ctx.features.get(\"store\")?.available`). From a game (the lobby is off screen) the\n host shows the screen in a window.\n- A screen that depends on title data registers with `available: false` and calls\n `ctx.features.setAvailable(id, ok, reason)` once it knows — from the client config\n (`configSection(client, \"Store\")`) or a read it makes anyway (a badge watcher); no extra request\n at start-up: every module's first reads arrive together and brush the per-player rate limit.\n- Groups: `economy`, `events`, `social`, `profile`. Icons are kit glyph names (`shop`, `hero`,\n `bag`, `trophy`, `gift`, `hammer`, `market`, `offer`, `flame`, `friends`, `chat`, `link`,\n `swords`, `user`, `bulb`, …) or an image URL.\n- Something that must be on screen all the time (a daily auto-popup, a badge watcher, an overlay) is\n a panel: `ctx.registerPanel({ id, slot: \"modal\", activeOnly: false, component })`.\n\n## Building a screen on the kit\n\nKeep the screen a short list; put every detail in a **popup**.\n\n```tsx\nimport {\n Button,\n Popup,\n ResourceList,\n Tabs,\n useCelebrate,\n useToast,\n useUiKit,\n errorText,\n grantedBy,\n panel,\n outlined,\n v,\n} from \"@idosgames/react/ui\";\n\nfunction ForgeScreen(): ReactNode {\n const [open, setOpen] = useState<string | null>(null);\n return (\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"minmax(0, 1fr)\",\n gap: 12,\n }}\n >\n {/* rows… onClick={() => setOpen(id)} */}\n {open ? (\n <Popup title=\"Forge\" onClose={() => setOpen(null)} width={420}>\n …\n </Popup>\n ) : null}\n </div>\n );\n}\n```\n\n- `Popup` is a bottom sheet on a phone and a centred window elsewhere (`variant=\"center\"` forces\n centred); it animates in and out and plays open/close sounds. Close from inside with\n `usePopupClose()`. `ConfirmPopup` for yes/no. A popup that opens BY ITSELF (not on a tap) passes\n `queued` — auto-popups then show one at a time instead of stacking.\n- `useCelebrate()(lines)` shows \"You got\" and flies the icons to any element marked\n `data-resource-counter=\"{currencyID}\"` (the lobby's balances are). Build the lines\n from a response with `grantedBy(data)`; a reward with premium (VIP) bundles needs them added.\n- `useUiKit().play(\"claim\")`, `useUiKit().fx.burst(element)` — a sound and a particle burst.\n- **Notifications — `useNotify()`** (the same system as a module's `ctx.notifications`):\n `notify.toast({ level: \"success\", title: \"Saved\" })` — a toast at the top that goes by itself;\n `await notify.alert({ level: \"warning\", title, message, actions })` — a window the player must\n answer, queued one at a time. Levels `info | success | warning | error | reward` pick the colour,\n icon, sound and how long a toast stays (errors longest). `icon` (a glyph, emoji or URL), `image` (a\n thumbnail / a big picture in the window), `source` (a feature id — its name on the card, a tap opens\n it), `key` (the same key replaces instead of stacking; identical toasts merge into \"×2\"),\n `duration` (`0` — until closed), `actions`. Refusals: `notify.toast({ level: \"error\", message:\nerrorText(res.error) })`; never re-check server rules. `useToast()(text, kind)` is the old short\n form of the same thing.\n- Lines of resources: `grantLines(grant)`, `costLines(cost)`, `bundleLines(bundle)`,\n `canAfford(lines, balances)`, `<ResourceList lines={…} />`. Names and icons: `useCatalog()`.\n- Words: `makeT(EN, RU)` for your strings, `plural(n, \"лот|лота|лотов\")` for counts.\n- ⚠ A root `display: grid` with a wide child (a row of tabs) grows past a phone screen — give it\n `gridTemplateColumns: \"minmax(0, 1fr)\"`.\n- ⚠ **No colour literals in a screen** (`\"#fff\"`, `\"rgba(0,0,0,.3)\"`, `\"#5a3fd0\"`): they break the\n moment the theme changes (white text on a light panel, a black stripe under a pastel button). Use\n the tokens: text `v.text` / `v.textDim` (or `...outlined`), surfaces `panel` / `well` / `v.wellSoft`,\n lines `v.line`, dimming `v.backdrop`. A coloured banner, \"your row\", a highlighted day →\n `...toneSurface(\"blue\" | \"green\" | \"gold\" | \"red\")`: it fills with that tone AND switches the text\n inside it to the tone's own readable colour. Text on a filled button — `ON_TONE[tone]`. A blend:\n `` `color-mix(in srgb, ${v.gold} 20%, transparent)` ``.\n\n## Tutorial hints\n\nThe `tutorials` module highlights any element marked `data-tutorial-anchor=\"…\"` — the lobby's tabs\nare `tab:{featureID}`, its profile button `lobby:profile`, its wallet `lobby:wallet`, a game's \"Play\"\nbutton `play:{modeID}`. Mark the controls of your own screen the same\nway; the publisher points tutorial steps at them in LiveOps (Tutorial → step → AnchorID).\n",
5
5
  "references": []
6
6
  }