Apps Home
|
Create an App
testrockpaperscissors
Author:
rockpaper
Description
Source Code
Launch App
Current Users
Created by:
Rockpaper
/* Rock Paper Prize v0.1 Simple Chaturbate App: Viewer tips and chooses Rock/Paper/Scissors. Host secretly chooses Rock/Paper/Scissors with chat command. App reveals both choices and announces win/lose prize. No images needed. */ cb.settings_choices = [ { name: 'level1_amount', type: 'int', minValue: 1, maxValue: 9999, defaultValue: 11, label: 'Level 1 token amount' }, { name: 'level1_win', type: 'str', minLength: 1, maxLength: 120, defaultValue: 'Winner gets a sweet shoutout', label: 'Level 1 viewer win prize' }, { name: 'level1_lose', type: 'str', minLength: 1, maxLength: 120, defaultValue: 'Lose prize: a tiny consolation smile', label: 'Level 1 viewer lose prize' }, { name: 'level2_amount', type: 'int', minValue: 1, maxValue: 9999, defaultValue: 25, label: 'Level 2 token amount' }, { name: 'level2_win', type: 'str', minLength: 1, maxLength: 120, defaultValue: 'Winner gets a custom thank-you message', label: 'Level 2 viewer win prize' }, { name: 'level2_lose', type: 'str', minLength: 1, maxLength: 120, defaultValue: 'Lose prize: cute room mention', label: 'Level 2 viewer lose prize' }, { name: 'level3_amount', type: 'int', minValue: 1, maxValue: 9999, defaultValue: 50, label: 'Level 3 token amount' }, { name: 'level3_win', type: 'str', minLength: 1, maxLength: 120, defaultValue: 'Winner gets a bigger custom reward', label: 'Level 3 viewer win prize' }, { name: 'level3_lose', type: 'str', minLength: 1, maxLength: 120, defaultValue: 'Lose prize: small reward anyway', label: 'Level 3 viewer lose prize' }, { name: 'level4_amount', type: 'int', minValue: 1, maxValue: 9999, defaultValue: 100, label: 'Level 4 token amount' }, { name: 'level4_win', type: 'str', minLength: 1, maxLength: 120, defaultValue: 'Winner gets VIP-style prize', label: 'Level 4 viewer win prize' }, { name: 'level4_lose', type: 'str', minLength: 1, maxLength: 120, defaultValue: 'Lose prize: still gets a nice reward', label: 'Level 4 viewer lose prize' }, { name: 'level5_amount', type: 'int', minValue: 1, maxValue: 9999, defaultValue: 250, label: 'Level 5 token amount' }, { name: 'level5_win', type: 'str', minLength: 1, maxLength: 120, defaultValue: 'Winner gets the top prize', label: 'Level 5 viewer win prize' }, { name: 'level5_lose', type: 'str', minLength: 1, maxLength: 120, defaultValue: 'Lose prize: premium consolation prize', label: 'Level 5 viewer lose prize' }, { name: 'tie_prize', type: 'str', minLength: 1, maxLength: 120, defaultValue: 'Tie prize: replay energy! Host may choose a small tie reward.', label: 'Tie prize message' }, { name: 'auto_menu_minutes', type: 'int', minValue: 1, maxValue: 30, defaultValue: 5, label: 'Repeat menu every X minutes' } ]; var pendingGames = []; var currentGame = null; var gamesPlayed = 0; var viewerWins = 0; var hostWins = 0; var ties = 0; var lastResult = 'No games played yet.'; function safeInt(value, fallback) { var n = parseInt(value, 10); if (isNaN(n)) { return fallback; } return n; } function lower(value) { return (value || '').toLowerCase(); } function sendNotice(title, body, kind, toUser) { var bg = '#181828'; var fg = '#ffffff'; if (kind === 'menu') { bg = '#24113d'; fg = '#fff1cc'; } else if (kind === 'host') { bg = '#3d2a10'; fg = '#fff4dc'; } else if (kind === 'win') { bg = '#103820'; fg = '#ecffef'; } else if (kind === 'lose') { bg = '#3a1010'; fg = '#ffecec'; } else if (kind === 'tie') { bg = '#1b3550'; fg = '#ecf6ff'; } else if (kind === 'error') { bg = '#4a1111'; fg = '#ffffff'; } cb.sendNotice( '✂️ 🪨 📄 ' + title + ' 📄 🪨 ✂️\n' + body, toUser || '', bg, fg, 'bold' ); } function getLevels() { return [ { level: 1, amount: safeInt(cb.settings.level1_amount, 11), win: cb.settings.level1_win, lose: cb.settings.level1_lose }, { level: 2, amount: safeInt(cb.settings.level2_amount, 25), win: cb.settings.level2_win, lose: cb.settings.level2_lose }, { level: 3, amount: safeInt(cb.settings.level3_amount, 50), win: cb.settings.level3_win, lose: cb.settings.level3_lose }, { level: 4, amount: safeInt(cb.settings.level4_amount, 100), win: cb.settings.level4_win, lose: cb.settings.level4_lose }, { level: 5, amount: safeInt(cb.settings.level5_amount, 250), win: cb.settings.level5_win, lose: cb.settings.level5_lose } ]; } function getLevelByAmount(amount) { var levels = getLevels(); var i; for (i = 0; i < levels.length; i += 1) { if (amount === levels[i].amount) { return levels[i]; } } return null; } function getChoiceFromMessage(message) { var msg = lower(message); if (msg.indexOf('rock') !== -1) { return 'rock'; } if (msg.indexOf('paper') !== -1) { return 'paper'; } if (msg.indexOf('scissors') !== -1 || msg.indexOf('scissor') !== -1) { return 'scissors'; } return ''; } function choiceEmoji(choice) { if (choice === 'rock') { return '🪨 Rock'; } if (choice === 'paper') { return '📄 Paper'; } if (choice === 'scissors') { return '✂️ Scissors'; } return '❓ Unknown'; } function decideWinner(viewerChoice, hostChoice) { if (viewerChoice === hostChoice) { return 'tie'; } if ( (viewerChoice === 'rock' && hostChoice === 'scissors') || (viewerChoice === 'paper' && hostChoice === 'rock') || (viewerChoice === 'scissors' && hostChoice === 'paper') ) { return 'viewer'; } return 'host'; } function menuText() { var levels = getLevels(); return 'Tip one of these exact amounts and choose Rock, Paper, or Scissors:\n\n' + levels[0].amount + ' tokens — Level 1 prize\n' + levels[1].amount + ' tokens — Level 2 prize\n' + levels[2].amount + ' tokens — Level 3 prize\n' + levels[3].amount + ' tokens — Level 4 prize\n' + levels[4].amount + ' tokens — Level 5 prize\n\n' + 'Viewer wins = win prize.\n' + 'Viewer loses = lose prize.\n' + 'Tie = tie prize.\n\n' + 'Host chooses after the tip, then both choices are revealed.'; } function hostInstructionText() { return 'Host commands:\n' + '/rock\n' + '/paper\n' + '/scissors\n\n' + 'Use one command to answer the current pending game.\n' + 'Use /rpsmenu to show the menu.\n' + 'Use /rpsstatus to see the queue.'; } function showMenu(toUser) { sendNotice( 'ROCK PAPER PRIZE', menuText(), 'menu', toUser || '' ); } function showStatus(toUser) { var queueCount = pendingGames.length; if (currentGame) { queueCount += 1; } sendNotice( 'GAME STATUS', 'Games played: ' + gamesPlayed + '\n' + 'Viewer wins: ' + viewerWins + '\n' + 'Host wins: ' + hostWins + '\n' + 'Ties: ' + ties + '\n' + 'Waiting games: ' + queueCount + '\n\n' + 'Last result:\n' + lastResult, 'menu', toUser || '' ); } function setNextGameIfNeeded() { if (!currentGame && pendingGames.length > 0) { currentGame = pendingGames.shift(); sendNotice( 'HOST CHOOSE NOW', 'New game from: ' + currentGame.username + '\n' + 'Prize Level: ' + currentGame.level.level + '\n' + 'Tip Amount: ' + currentGame.amount + ' tokens\n\n' + 'Type one:\n' + '/rock\n' + '/paper\n' + '/scissors\n\n' + 'Viewer choice is hidden until you choose.', 'host', cb.room_slug ); } } function finishGame(hostChoice) { var result; var prizeText; var title; var kind; var body; if (!currentGame) { sendNotice( 'NO GAME WAITING', 'There is no pending Rock Paper Prize game right now.', 'error', cb.room_slug ); return; } result = decideWinner(currentGame.viewerChoice, hostChoice); gamesPlayed += 1; if (result === 'viewer') { viewerWins += 1; prizeText = currentGame.level.win; title = 'VIEWER WINS'; kind = 'win'; } else if (result === 'host') { hostWins += 1; prizeText = currentGame.level.lose; title = 'HOST WINS'; kind = 'lose'; } else { ties += 1; prizeText = cb.settings.tie_prize; title = 'TIE GAME'; kind = 'tie'; } body = currentGame.username + ' tipped ' + currentGame.amount + ' tokens for Level ' + currentGame.level.level + '.\n\n' + currentGame.username + ' chose: ' + choiceEmoji(currentGame.viewerChoice) + '\n' + 'Host chose: ' + choiceEmoji(hostChoice) + '\n\n' + 'Result: ' + title + '\n' + 'Prize: ' + prizeText; lastResult = body; sendNotice(title, body, kind, ''); currentGame = null; setNextGameIfNeeded(); cb.drawPanel(); } cb.onStart(function() { showMenu(''); sendNotice( 'HOST INFO', hostInstructionText(), 'host', cb.room_slug ); function autoMenu() { showMenu(''); cb.setTimeout(autoMenu, safeInt(cb.settings.auto_menu_minutes, 5) * 60 * 1000); } cb.setTimeout(autoMenu, safeInt(cb.settings.auto_menu_minutes, 5) * 60 * 1000); }); cb.onTip(function(tip) { var amount = safeInt(tip.amount, 0); var username = tip.is_anon_tip ? 'Anonymous' : tip.from_user; var choice = getChoiceFromMessage(tip.message); var level = getLevelByAmount(amount); var game; if (!level) { sendNotice( 'THANK YOU', username + ' tipped ' + amount + ' tokens.\n\n' + 'That is not one of the Rock Paper Prize game amounts, so no game was started.\n\n' + 'Type /rpsmenu to see game amounts.', 'menu', '' ); return; } if (!choice) { sendNotice( 'CHOICE MISSING', username + ' tipped a game amount, but did not choose Rock, Paper, or Scissors.\n\n' + 'Host can still give the Level ' + level.level + ' lose prize manually if desired.', 'error', '' ); return; } game = { username: username, amount: amount, viewerChoice: choice, level: level }; pendingGames.push(game); sendNotice( 'GAME STARTED', username + ' started a Level ' + level.level + ' Rock Paper Prize game!\n\n' + 'Their choice is locked in.\n' + 'Host is choosing now...', 'menu', '' ); setNextGameIfNeeded(); cb.drawPanel(); }); cb.onMessage(function(msg) { var text = lower(msg.m); if (text === '/rpsmenu') { showMenu(msg.user); msg['X-Spam'] = true; return msg; } if (text === '/rpsstatus') { showStatus(msg.user); msg['X-Spam'] = true; return msg; } if (text === '/rock' || text === '/paper' || text === '/scissors') { if (msg.user === cb.room_slug || msg.is_mod) { finishGame(text.replace('/', '')); } msg['X-Spam'] = true; return msg; } return msg; }); cb.tipOptions(function(user) { return { label: 'Rock Paper Prize - choose your move:', options: [ { label: 'Rock' }, { label: 'Paper' }, { label: 'Scissors' } ] }; }); cb.onDrawPanel(function(user) { var waiting = pendingGames.length; if (currentGame) { waiting += 1; } return { template: '3_rows_of_labels', row1_label: 'Rock Paper Prize', row1_value: 'Tip + choose move', row2_label: 'Waiting Games', row2_value: String(waiting), row3_label: 'Record', row3_value: 'V ' + viewerWins + ' / H ' + hostWins + ' / T ' + ties }; }); cb.drawPanel();
© Copyright Chaturbate 2011- 2026. All Rights Reserved.