diff --git a/README.md b/README.md new file mode 100644 index 0000000..e5ac3c1 --- /dev/null +++ b/README.md @@ -0,0 +1,378 @@ +# ShaiBot + +A modular **Discord.js** bot with a shared Cookie economy, interactive +Crumb Saucer games, cooperative boss battles, raid planning, and +community interactions. + +> **Status:** Active development. Game balance and individual features +> may change. + +## Features + +### 🍪 Cookie Economy + +Cookies are ShaiBot's shared virtual currency. The economy supports +persistent balances, atomic balance checks, transfers, per-user +cooldowns, and a shared bot/house vault. + +The bot itself acts as the general Cookie vault: gambling losses and +penalties can feed the vault, while wins, heists, and rewards can pay +Cookies back out. + +### 🎰 The Crumb Saucer + +The **Crumb Saucer** is ShaiBot's Cookie-powered entertainment hub. + +#### Slots + +- Multiple Cookie wagers +- Embed-based reel presentation +- Different symbol payouts and jackpots +- Replay support +- Shared Cookie vault + +#### Blackjack + +- Hit, Stand, and Double +- Dealer stands on 17 +- Natural Blackjack pays 3:2 +- Push returns the wager +- Persistent active hands +- Per-player session ownership +- Safe simultaneous sessions + +#### Roulette + +A compact European Roulette implementation using **0--36**. + +Available bets: + +- 🔴 Red +- ⚫ Black +- Odd +- Even +- 🟢 Zero + +Roulette uses repeated edits of the same embed for a +rate-limit-conscious pseudo-animation. Zero loses on Red, Black, Odd, +and Even. + +#### Vault Heist + +Players can attempt to steal directly from ShaiBot's Cookie vault using +different risk/reward approaches such as **Sneak**, **Hack**, and +**Smash**. Heist actions share a per-player cooldown so changing +approach does not bypass it. + +### ⚔️ Crumble Strike + +**Crumble Strike** is a cooperative Cookie-powered boss battle. + +- A player spawns an encounter. +- Other players join during recruitment. +- The author can start after at least **5 players** have joined. +- Players can join an active encounter later. +- Encounters have a limited lifetime. +- Failure can result in committed Cookies being lost. + +Combat actions include: + +- **Strike** --- basic damage and Energy generation. +- **Defend** --- reduces incoming damage at an Energy cost. +- **Heal** --- restores party health at an Energy cost. +- **Revive** --- party-wide revival progress. Normal roles add +1 to + every downed player; Healers add +2. Three progress revives a + player. +- **Limit Break** --- consumes the party's global Limit resource for + major damage. + +Roles are **DPS**, **Tank**, and **Healer**, with role-specific +proficiencies. The general progression theme includes **Sprout → +Adventurer → Warrior of Light**. + +### 🏴 Cookie Stealing + +Normal player-to-player stealing is separate from Vault Heist. Steal +difficulty can account for attacker and target wealth, successful steals +can use a randomized percentage with a cap, and failed attempts can +apply a fee that feeds the bot vault. + +### 📅 Raid Planner + +Raid planning uses Discord embeds and reactions. Participation can be +counted across reactions without automatically removing user reactions, +including a count of unique participants. + +### 👈 Poke + +A lightweight social command can privately poke another guild member +through DMs. Repeated pokes are bounded to a rate-limit-friendly +maximum. + +## Project Structure + +A typical layout: + +``` text +ShaiBot/ +├── buttons/ +│ ├── crumbSaucer/ +│ └── crumbleStrike/ +├── commands/ +│ └── applications/ +├── events/ +├── handlers/ +├── modals/ +├── utils/ +│ ├── cookieEconomy.js +│ ├── crumbBlackjack.js +│ ├── crumbRoulette.js +│ └── crumbleStrike.js +├── index.js +├── package.json +└── .env +``` + +Interaction modules are loaded into Discord.js collections such as: + +``` js +client.commands = new Collection(); +client.legacyCommands = new Collection(); +client.aliases = new Collection(); +client.buttons = new Collection(); +client.selectMenus = new Collection(); +client.modals = new Collection(); +``` + +## Requirements + +- Node.js +- Discord.js +- MongoDB +- A Discord bot application/token +- `dotenv` + +Use the Node.js version required by the dependencies in your +`package.json`. + +## Installation + +Clone the repository: + +``` bash +git clone https://github.com/YOUR_USERNAME/ShaiBot.git +cd ShaiBot +``` + +Install dependencies: + +``` bash +npm install +``` + +Create `.env` in the project root: + +``` env +D_TOKEN=YOUR_DISCORD_BOT_TOKEN +M_URI=YOUR_MONGODB_CONNECTION_STRING +M_DB=YOUR_DATABASE_NAME +``` + +Start the bot: + +``` bash +node index.js +``` + +For PM2, a typical command is: + +``` bash +pm2 start index.js --name ShaiBot +``` + +## MongoDB + +ShaiBot's Cookie economy intentionally does **not** depend on MongoDB +transactions, allowing it to work with deployments that do not support +replica-set transactions. + +If your deployment does not support retryable writes, include: + +``` text +retryWrites=false +``` + +in the connection string, for example: + +``` env +M_URI=mongodb://USER:PASSWORD@HOST:PORT/DATABASE?authSource=admin&retryWrites=false +``` + +Never commit database credentials. + +Important economy collections include: + +``` text +items_cookies +cooldown_cookies +items_games +``` + +`items_cookies` stores balances, `cooldown_cookies` stores action +cooldown timestamps, and `items_games` can store persistent game state. + +### Recommended Indexes + +Run the shared index initializer after MongoDB connects: + +``` js +const { + ensureCookieIndexes +} = require("./utils/cookieEconomy"); + +await mClient.connect(); +await ensureCookieIndexes(); +``` + +The intended unique keys are: + +``` text +items_cookies → userId +cooldown_cookies → userId + guildId +``` + +## Discord Intents + +The current client uses intents including: + +``` js +GatewayIntentBits.Guilds +GatewayIntentBits.GuildMembers +GatewayIntentBits.GuildMessages +GatewayIntentBits.GuildPresences +GatewayIntentBits.GuildMessageReactions +GatewayIntentBits.GuildVoiceStates +GatewayIntentBits.DirectMessages +GatewayIntentBits.MessageContent +``` + +and partials including: + +``` js +Partials.Channel +Partials.Message +Partials.User +Partials.GuildMember +Partials.Reaction +``` + +Enable any required privileged intents in the Discord Developer Portal. + +## Interaction Design + +ShaiBot generally follows these conventions: + +- Public game output uses **embeds**. +- Short private errors/feedback can use **ephemeral messages**. +- Games use **buttons** for interaction. +- Existing messages are edited where practical instead of repeatedly + sending new messages. +- Game/session ownership is preserved so multiple users can play + independently. +- Animation-like effects use rate-limit-conscious message edits. + +## Economy Safety + +Economy operations favor atomic MongoDB updates for balance checks and +debits. + +Transfers avoid MongoDB transactions for deployment compatibility. If a +destination credit fails after a successful debit, the shared economy +utility performs a best-effort compensating credit to the source +account. Administrators should monitor logs for critical compensation +failures. + +When adding games, check that the house vault can cover the maximum +possible payout before accepting a wager. + +## Adding a Crumb Saucer Game + +Preferred pattern: + +1. Put shared game logic in `utils/`. +2. Put individual Discord button handlers in the appropriate `buttons/` + directory. +3. Reuse `cookieEconomy.js` rather than implementing separate balance + logic. +4. Preserve the player/session owner through every screen. +5. Check house liquidity before accepting a wager. +6. Prefer editing the current embed for animation/state transitions. +7. Protect wager resolution against rapid repeated interactions. + +## Roadmap / TODO + +The major planned Cookie systems are implemented or designed. Remaining +work is primarily testing, balancing, and hardening. + +- [ ] Verify Slots replay behavior after deployment +- [ ] Deploy and test limited Roulette +- [ ] Verify Crumble Strike AoE Revive behavior +- [ ] Verify Crumble Strike expiration/failure cleanup survives bot + restarts +- [ ] Balance boss HP, damage, healing, Energy, Limit generation, + entry costs, and rewards +- [ ] Stress-test simultaneous gambling interactions +- [ ] Stress-test repeated/double button presses +- [ ] Test insufficient-balance races +- [ ] Test behavior with a nearly empty house vault +- [ ] Consider dynamic Vault Heist payout caps +- [ ] Consider an economy audit/log collection +- [ ] Add more Crumble Strike bosses, lore, and encounter variety +- [ ] Add more Crumb Saucer attractions + +## Security + +A suitable `.gitignore` should include at least: + +``` gitignore +node_modules/ +.env +*.log +``` + +If a Discord token or MongoDB credential is accidentally committed, +rotate it immediately. + +## Disclaimer + +ShaiBot Cookies are fictional in-bot currency with no real-world +monetary value. Crumb Saucer gambling-style games are entertainment +mechanics using that fictional currency. + +Final Fantasy XIV names and concepts referenced by community game +features belong to their respective rights holders. ShaiBot is not +affiliated with or endorsed by Square Enix. + +## Contributing + +Bug reports, balance suggestions, and contributions are welcome. + +When contributing: + +- Keep commands and button handlers modular. +- Reuse shared economy utilities. +- Avoid blocking the event loop. +- Be mindful of Discord API rate limits. +- Validate interaction ownership. +- Keep database operations safe under concurrent interactions. + +## License + +Add the license used by the repository here. If the project is open +source, include a `LICENSE` file and replace this section with the +chosen license. + +------------------------------------------------------------------------ + +Made for Discord communities that believe every problem can be improved +with a few more Cookies. 🍪