diff --git a/docs/CONTRACTS.md b/docs/CONTRACTS.md index 4e3ae1f..f5cbd6c 100644 --- a/docs/CONTRACTS.md +++ b/docs/CONTRACTS.md @@ -449,14 +449,14 @@ Viewer sprites (server/sprites.ts): between them in 24 h already): no Elo or dollars." - An active duel with no action for `inactivityMs` is cancelled without scoring. Cancelled duels return both players to maxHp. -- Upgrades (server/upgrades.ts): every win earns one point and check-ins add more (`bonus`), at most 20 together, spent on power (+4% damage dealt per point), guard (-4% damage taken) and luck (4% per point that a quick-duel miss lands as a hit), at most 8 each. Profiles carry `bonus` (check-in points), `checkins` and `streak`; the profile answer's `upgrades` has `points`, `fromWins` and `fromCheckins`. Points can be moved while the fighter is not in a duel. Hats are cosmetic; some unlock at a number of wins. A rank reset clears Elo and wins but keeps `bonus`. +- Upgrades (server/upgrades.ts): every win earns one point and check-ins add more (`bonus`), with no cap. Points buy levels in power (damage dealt), guard (damage taken) and luck (the chance a quick-duel miss lands as a hit). Levels 1-8 cost 1 point each and give 4% each; the cost doubles every 8 levels (9-16 cost 2, 17-24 cost 4), and above level 8 the effect closes in on a ceiling (power and guard 60%, luck 50%; level 16 gives about 44.2%). Stored levels stop at 200. The channel's `maxStatLevel` caps the levels that count in its duels; levels above it stay saved. A rank reset that leaves too few points takes levels off luck, then guard, then power. Profiles carry `bonus` (check-in points), `checkins` and `streak`; the profile answer's `upgrades` has `points`, `fromWins`, `fromCheckins` and `maxLevel`. The fighter page offers suggested builds (`PRESETS`) that fill the levels from the points; the viewer still saves. Points can be moved while the fighter is not in a duel. Hats are cosmetic; some unlock at a number of wins. A rank reset clears Elo and wins but keeps `bonus`. - Dollars: every finished ranked duel pays `winDollars` to the winner and `lossDollars` to the loser, saved fighters only. game.ts records it as `duel.payout` and the room adds it to `profiles.dollars` once, in the same transaction (`duel.paid`). Like Elo, a payout stays out of `!wallet`, `/api/profile` and the leaderboard until the stream has shown the fight. Profiles carry `dollars` (at most 1,000,000). Check-ins give points, not dollars. A rank reset, a profile save and a re-save keep dollars; removing a viewer deletes them. -- `!wallet` (the StreamElements `wallet` action, also while duels are paused): "@x: $N PixFray dollars, P of 20 upgrade points, S-stream streak." Reasons: `wallet`, `no_fighter`. -- Pets and the shop (server/pets.ts): 14 built-in pets in 5 tiers, plus up to 24 uploaded per channel. A fighter owns any number of pets (`owned_items`) and brings one (`profiles.pet`); hats can be bought too. A pet's boost is added after the upgrade limits: common and uncommon +1 to one stat, rare +2, epic +2 and +1 to a second stat, legendary +1 to every stat. Pets cost `petPrice` dollars; a hat whose wins aren't reached costs `hatPricePerWin` times the wins it needs. The overlay draws the pet behind its fighter at about 40% of its height; epic and legendary pets sparkle, legendary pets hover. Snapshot players and `/api/looks` carry `pet` and `petTier`; players also carry `petBoost`. +- `!wallet` (the StreamElements `wallet` action, also while duels are paused): "@x: $N PixFray dollars, P upgrade points, S-stream streak." Reasons: `wallet`, `no_fighter`. +- Pets and the shop (server/pets.ts): 14 built-in pets in 5 tiers, plus up to 24 uploaded per channel. A fighter owns any number of pets (`owned_items`) and brings one (`profiles.pet`); hats can be bought too. A pet's boost is added after the channel's `maxStatLevel` cap: common and uncommon +1 to one stat, rare +2, epic +2 and +1 to a second stat, legendary +1 to every stat. Pets cost `petPrice` dollars; a hat whose wins aren't reached costs `hatPricePerWin` times the wins it needs. The overlay draws the pet behind its fighter at about 40% of its height; epic and legendary pets sparkle, legendary pets hover. Snapshot players and `/api/looks` carry `pet` and `petTier`; players also carry `petBoost`. - Cosmetics and builds (server/cosmetics.ts, drawn by src/served/cosmetics.ts): recolor (a CSS filter on the fighter), pet color (the same 8 tints on the pet), accessories, walking trails, win effects (about 3 s over the winner when the overlay shows the result), win taunts (a speech bubble then) and titles (under the nameplate). Each kind has one config price. Owned cosmetics are `owned_items` rows; the worn ones are profile columns. Build slots: 1 free, the 2nd costs `buildSlotPrice`, the 3rd to 5th `buildSlotPriceMore` each. Each slot keeps its own loadout in the `builds` table; saving to a slot makes it the one on stream, and every build can spend the full point pool. Removing a viewer deletes their builds; a rank reset keeps them. - `!pet [@name]` (the `pet` action): "@x's pet: Fox (rare), +2 power." Reasons: `pet`, `no_pet` (with the site link for the sender's own), `no_fighter`. - `!pay @name amount` (the `give` action; on a channel the PixFray bot reads, it's `!give` and `!pay` stays an alias; `a=` is `20` or `$20`): moves dollars between two saved fighters while the channel is live (the same Twitch check as check-ins). In order it refuses with `give_off` (config `giveEnabled` false), `no_fighter`, `give_usage` (no target or no whole amount of at least 1), `target_not_found`, `self_give`, `twitch_error`, `not_live`, `too_few_duels` (fewer than `giveMinDuels` finished duels, `{duels, need}`), `give_cap` (already gave `giveMaxPerStream` this stream), `over_cap` (`{left}`), `not_enough` (`{dollars}`) and `target_full` (`{to, room}`: the receiver's wallet can't hold the amount, so nothing moves). Hidden duel results and payouts don't count yet. The limit is per Twitch stream id (`profiles.give_stream`, `given_in_stream`). Success is `given` with `{amount, to, dollars, left}`; the command log stores the amount. -- Check-ins (the StreamElements `checkin` action; the test site's dev chat also takes `!checkin`, Twitch EventSub chat does not): once per stream, only while Twitch's Helix `/streams` says the channel is live (cached 60 s; a Twitch error answers "try again" and is not cached). Gives `checkinPoints` (bonus capped at 1000). The streak counts the channel's streams in a row that had any check-in; one missed stream is forgiven once every 7 days. With `streakBonus`, a streak of 3, 7, 14 or 30 gives +1 more. Reasons: `checked_in`, `already_checked_in`, `not_live`, `no_fighter`, `twitch_error`. On the test Worker, `POST /api/devtools//live` with `{live, streamId?}` (DEV_TOOLS_TOKEN only) replaces the Twitch answer: `true` is live, `false` is offline, and `null` goes back to asking Twitch. +- Check-ins (the StreamElements `checkin` action; the test site's dev chat also takes `!checkin`, Twitch EventSub chat does not): once per stream, only while Twitch's Helix `/streams` says the channel is live (cached 60 s; a Twitch error answers "try again" and is not cached). Gives `checkinPoints` (bonus capped at 1,000,000). The streak counts the channel's streams in a row that had any check-in; one missed stream is forgiven once every 7 days. With `streakBonus`, a streak of 3, 7, 14 or 30 gives +1 more, 60 gives +2, 100 gives +3, 200 gives +5 and 365 gives +10. The reply names the total and what is unspent: "@x checked in: +2 points (7-stream streak, streak bonus). 18 points, 3 unspent. Spend them at ", or "…, all spent." with no link. Reasons: `checked_in`, `already_checked_in`, `not_live`, `no_fighter`, `twitch_error`. On the test Worker, `POST /api/devtools//live` with `{live, streamId?}` (DEV_TOOLS_TOKEN only) replaces the Twitch answer: `true` is live, `false` is offline, and `null` goes back to asking Twitch. - Ranked play needs a saved profile (`ranked_sign_in_required`). - Reason codes: `active_player_cap`, `challenge_not_found`, `channel_full`, `config_version_conflict`, `config_version_not_found`, `cooldown` (+`retryAt`), `duel_not_found`, @@ -485,7 +485,8 @@ Viewer sprites (server/sprites.ts): | initialElo | 1000 | 0 to 10000 | | eloK | 24 | 1 to 100 | | checkinPoints | 1 | 0 to 3 (upgrade points per check-in) | -| streakBonus | true | boolean (+1 point at a streak of 3, 7, 14 and 30 streams) | +| streakBonus | true | boolean (+1 point at a streak of 3, 7, 14 and 30 streams, +2 at 60, +3 at 100, +5 at 200, +10 at 365) | +| maxStatLevel | 16 | 1 to 200 (the highest level of each upgrade stat that counts in this channel's duels) | | winDollars | 5 | 0 to 100 (PixFray dollars for a win) | | lossDollars | 3 | 0 to 100 (dollars for a loss) | | giveEnabled | true | boolean (`!pay` on or off) | diff --git a/docs/DUELS.md b/docs/DUELS.md index 3863ec6..b1a497b 100644 --- a/docs/DUELS.md +++ b/docs/DUELS.md @@ -35,8 +35,12 @@ The duel is rolled at once, the moment the challenge is accepted. ## Upgrades, hats and check-ins -- Each win earns an upgrade point (power, guard, luck) and unlocks hats. -- `!checkin`, once per live stream, adds a point too, with streak bonuses. +- Each win earns an upgrade point (power, guard, luck) and unlocks hats. Points have no cap. +- Levels 1-8 of a stat cost 1 point each; the cost doubles every 8 levels after that, and each level + adds less as the stat nears its ceiling. Mods set the highest level that counts on their channel + (16 by default); levels above it stay saved. +- `!checkin`, once per live stream, adds a point too, with streak bonuses: +1 at 3, 7, 14 and 30 + streams, +2 at 60, +3 at 100, +5 at 200 and +10 at 365. - `!pet` shows a fighter's pet. ## PixFray dollars diff --git a/docs/STREAMER_SETUP.md b/docs/STREAMER_SETUP.md index 9a4d14f..db33165 100644 --- a/docs/STREAMER_SETUP.md +++ b/docs/STREAMER_SETUP.md @@ -59,6 +59,8 @@ once you allowed the bot or made it a moderator. it, click **Connect mod access** and approve the permission while signed in to Twitch as yourself. Moderators can edit chat commands, use Clear arena, change the balance and review viewer sprites. +The Rules tab's Check-ins group has **Highest stat level that counts** (16 by default): fighters' upgrade levels above it +stay saved but don't count in your channel's duels. Only you (or the site owner) can click **Reset all ranks**, **Turn PixFray off** or move chat from another site. diff --git a/index.html b/index.html index 5ce158e..7258705 100644 --- a/index.html +++ b/index.html @@ -134,8 +134,9 @@

Your fighter in %SITE_CHANNEL%'s chat

Upgrades -

Each win and each stream check-in (!checkin in chat) gives a point, up to 20. Move points between stats whenever you're not in a duel.

+

Each win and each stream check-in (!checkin in chat) gives a point. Move points between stats whenever you're not in a duel.

+
@@ -180,7 +181,7 @@

Your fighter in %SITE_CHANNEL%'s chat