Cosmetic Robux display editor with abbreviations. 0 delay, So your real robux value never shows after refreshing or opening a new page. Transactions page coming someday.
// ==UserScript==
// @name Roblox Visual Robux Display
// @namespace http://tampermonkey.net/
// @version 4.2
// @description Cosmetic Robux display editor with abbreviations. 0 delay, So your real robux value never shows after refreshing or opening a new page. Transactions page coming someday.
// @match https://www.roblox.com/*
// @match https://web.roblox.com/*
// @grant none
// @run-at document-start
// @license MIT
// ==/UserScript==
(function () {
'use strict';
const UI_ID = 'robux-visual-editor-ui';
const STORAGE_KEY = 'robux_visual_value';
const STORAGE_ENABLED = 'robux_visual_enabled';
let isApplying = false;
let observerStarted = false;
function trimTrailingZero(value) {
return value.replace(/\.0$/, '');
}
function formatRobux(num) {
num = Number(num);
if (isNaN(num)) return String(num);
if (num < 1000) {
return Math.floor(num).toLocaleString();
}
if (num < 1000000) {
const value = num / 1000;
const formatted = value >= 100 ? value.toFixed(0) : value.toFixed(1);
return trimTrailingZero(formatted) + 'K+';
}
const value = num / 1000000;
const formatted = value >= 100 ? value.toFixed(0) : value.toFixed(1);
return trimTrailingZero(formatted) + 'M+';
}
function looksLikeRobuxAmount(text) {
if (!text) return false;
const cleaned = text.trim();
return (
/^\d[\d,]*$/.test(cleaned) ||
/^\d+(\.\d+)?[KM]\+?$/i.test(cleaned)
);
}
function getStrictBalanceElements() {
const elements = new Set();
const navbarAmount = document.getElementById('nav-robux-amount');
if (navbarAmount) elements.add(navbarAmount);
const navbarRoot = document.getElementById('navbar-robux');
if (navbarRoot) {
navbarRoot.querySelectorAll('span').forEach(el => {
if (
el.id !== 'nav-robux' &&
el.id !== 'nav-robux-icon' &&
looksLikeRobuxAmount(el.textContent)
) {
elements.add(el);
}
});
}
const strictPopoverSelectors = [
'.popover',
'.dropdown-menu',
'.rbx-popover-content',
'[role="menu"]'
];
strictPopoverSelectors.forEach(selector => {
document.querySelectorAll(selector).forEach(pop => {
const text = pop.textContent || '';
if (!/robux/i.test(text)) return;
pop.querySelectorAll('span').forEach(el => {
const ownText = (el.textContent || '').trim();
if (
ownText &&
ownText.length <= 12 &&
looksLikeRobuxAmount(ownText)
) {
elements.add(el);
}
});
});
});
return [...elements];
}
function applyVisualValue(value) {
const formatted = formatRobux(value);
const els = getStrictBalanceElements();
if (!els.length) return false;
isApplying = true;
for (const el of els) {
if (el.textContent !== formatted) {
el.textContent = formatted;
}
}
isApplying = false;
return true;
}
function restoreRealValue() {
location.reload();
}
function createUI() {
if (!document.body || document.getElementById(UI_ID)) return;
const ui = document.createElement('div');
ui.id = UI_ID;
ui.style.cssText = `
position: fixed;
top: 100px;
right: 20px;
background: rgba(0, 0, 0, 0.9);
color: white;
padding: 12px;
border-radius: 8px;
z-index: 999999;
width: 220px;
font-family: Arial, sans-serif;
box-shadow: 0 4px 20px rgba(0,0,0,0.4);
transition: opacity 0.25s ease;
`;
ui.innerHTML = `
<h4 style="margin:0 0 8px 0;">Visual Robux Editor</h4>
<label style="font-size:13px;">Amount:</label>
<input
type="number"
min="0"
id="${UI_ID}-val"
style="width:100%;margin:4px 0;padding:5px;border-radius:4px;border:1px solid #555;background:#222;color:white;"
/>
<div style="display:flex;gap:8px;margin-top:8px;">
<button id="${UI_ID}-apply" style="flex:1;background:#007bff;color:white;border:none;border-radius:6px;padding:6px;cursor:pointer;">Apply</button>
<button id="${UI_ID}-reset" style="flex:1;background:#444;color:white;border:none;border-radius:6px;padding:6px;cursor:pointer;">Reset</button>
</div>
<p style="font-size:11px;color:#ccc;margin-top:6px;">
Press "=" or "M" to toggle<br>
Visual only — doesn't change your balance.
</p>
`;
document.body.appendChild(ui);
ui.style.display = 'none';
ui.style.opacity = '0';
const valInput = document.getElementById(`${UI_ID}-val`);
valInput.value = localStorage.getItem(STORAGE_KEY) || '';
document.getElementById(`${UI_ID}-apply`).onclick = () => {
const val = valInput.value.trim();
if (!val) return;
localStorage.setItem(STORAGE_KEY, val);
localStorage.setItem(STORAGE_ENABLED, '1');
applyVisualValue(val);
};
document.getElementById(`${UI_ID}-reset`).onclick = () => {
localStorage.removeItem(STORAGE_KEY);
localStorage.removeItem(STORAGE_ENABLED);
restoreRealValue();
};
}
function toggleUI() {
createUI();
const ui = document.getElementById(UI_ID);
if (!ui) return;
const visible = ui.style.display !== 'none';
if (visible) {
ui.style.opacity = '0';
setTimeout(() => {
ui.style.display = 'none';
}, 250);
} else {
ui.style.display = 'block';
setTimeout(() => {
ui.style.opacity = '1';
}, 10);
}
}
function reapplySavedValue() {
if (isApplying) return false;
const val = localStorage.getItem(STORAGE_KEY);
const enabled = !!localStorage.getItem(STORAGE_ENABLED);
if (val && enabled) {
return applyVisualValue(val);
}
return false;
}
function startObserver() {
if (observerStarted || !document.documentElement) return;
observerStarted = true;
const observer = new MutationObserver(() => {
if (isApplying) return;
reapplySavedValue();
if (!document.getElementById(UI_ID) && document.body) {
createUI();
}
});
observer.observe(document.documentElement, {
childList: true,
subtree: true
});
}
function startFastApplyLoop() {
let tries = 0;
const maxTries = 200;
const timer = setInterval(() => {
tries++;
if (document.body && !document.getElementById(UI_ID)) {
createUI();
}
const applied = reapplySavedValue();
if (applied || tries >= maxTries) {
clearInterval(timer);
}
}, 25);
}
window.addEventListener('keydown', (e) => {
const active = document.activeElement;
if (active && ['INPUT', 'TEXTAREA'].includes(active.tagName)) return;
if (e.key === '=' || e.key.toLowerCase() === 'm') {
e.preventDefault();
toggleUI();
}
});
startObserver();
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
createUI();
reapplySavedValue();
startFastApplyLoop();
});
} else {
createUI();
reapplySavedValue();
startFastApplyLoop();
}
})();