Roblox UtilitiesDevlHub Roblox Documentation

AI on Roblox

Learn how to accelerate your creation workflows with AI.

export const accent = 'var(--color-system-emphasis)'; export const darkSurface = 'var(--color-surface-200)'; export const darkBorder = 'var(--color-stroke-default)'; // Scrim sits over media, so it stays dark in both themes. export const scrimGradient = 'linear-gradient(180deg, transparent 40%, rgba(0,0,0,0.85) 100%)'; export const tileBg = 'var(--color-surface-0)'; export const overlineStyle = { color: accent, fontWeight: 700, letterSpacing: '0.1em', }; export const h2Style = { fontSize: 32, fontWeight: 800, marginBottom: 16 }; export const learnMoreText = 'Learn more';

export const openYouTubeModal = (id) => { const m = document.getElementById(yt-modal-${id}); const f = document.getElementById(yt-iframe-${id}); if (f) { f.src = https://www.youtube-nocookie.com/embed/${id}?autoplay=1&rel=0; } if (m) m.style.display = 'flex'; }; export const closeYouTubeModal = (id) => { const m = document.getElementById(yt-modal-${id}); const f = document.getElementById(yt-iframe-${id}); if (f) f.src = 'about:blank'; if (m) m.style.display = 'none'; };

export const RawImg = 'img';

export const YouTubeEmbed = ({ id, title = 'YouTube video player', noHover = false }) => ( <> <button type="button" className={yt-tile${noHover ? ' yt-tile-plain' : ''}} >

<div id={yt-modal-${id}} className="yt-modal" role="dialog" aria-modal="true" > <iframe id={yt-iframe-${id}} src="about:blank" allow={ 'accelerometer; autoplay; clipboard-write; encrypted-media; ' + 'gyroscope; picture-in-picture; web-share' } allowFullScreen />
</> );

export const linkCardStyles = { default: { borderRadius: 12, padding: '18px 20px', display: 'flex', flexDirection: 'column', width: '100%', height: '100%', }, dark: { background: darkSurface, border: 1px solid ${darkBorder}, borderRadius: 14, height: '100%', padding: '20px 22px 24px', display: 'flex', flexDirection: 'column', }, media: { borderRadius: 16, overflow: 'hidden', display: 'flex', flexDirection: 'column', width: '100%', height: '100%', WebkitMaskImage: 'none', }, };

export const LANDING_PAGE_DATA = { pageSections: { hero: { overline: 'AI on Roblox', title: 'From ideas to published games, faster than ever', description: 'Move faster with tools that help you script, build, and generate assets, while having full control over creative decisions.', ctas: [ { label: 'Download Studio', href: 'https://www.roblox.com/download/studio', rel: 'noopener', variant: 'contained', color: 'primary', size: 'large' }, { label: 'See how to create', variant: 'outlined', size: 'large', href: '#watch-and-learn' } ], flows: [ { id: 'harness', label: 'Bring your own client', steps: [ { num: '1', title: 'Enable AI features', subtitle: 'Enable MCP and AI features in Studio.', detail: `Open Assistant → … → Manage MCP Servers and switch on the Enable Studio as MCP server toggle.

Open File → Beta Features and turn on the features you want. Features that are generally available are always available by default.` }, { num: '2', title: 'Connect your client', subtitle: 'Let your MCP-enabled tools interact with Studio.', detail: 'Point your MCP-aware client at the Studio MCP server. When connected, your client can read the data model, create and run scripts, edit instances, playtest, and more.' }, { num: '3', title: 'Build your first game', subtitle: 'Plan and build your first game using your favorite coding harness.', detail: 'Download the starter project that contains LLM-friendly markdown files for context and have your first game ready in minutes.' }, { num: '4', title: 'Customize your setup', subtitle: 'Build with community and professional tools.', detail: 'With Rojo and Git, you can build and version control your Roblox projects via the file system. Use tools like Blender and other DCC apps to round out your creation workflow.' } ] }, { id: 'studio', label: 'Roblox Studio', steps: [ { num: '1', title: 'Enable AI features', subtitle: 'We're always adding new beta features, so make sure they're enabled.', detail: 'Open File → Beta Features and turn on the features you want. Features that are generally available are always available by default.' }, { num: '2', title: 'Prompt the Assistant', subtitle: 'Describe what you want in the Assistant panel.', detail: 'Tell Assistant to build 3D objects, write and run Luau, generate meshes and materials, and playtest alongside you.' }, { num: '3', title: 'Build your first game', subtitle: 'Learn core concepts and build an obby with the Assistant.', detail: 'Our core curriculum teaches you the basics of building, scripting, and polishing an obby game using the Assistant as your trusted companion.' }, { num: '4', title: 'Customize your setup', subtitle: 'Bring your own API keys to use the model you prefer.', detail: 'Open Assistant → … → Manage API Keys to configure your preferred model from Anthropic, OpenAI, or Google.' } ] } ] }, creation3d: { overline: '3D and AVATAR CREATION', title: 'Generate 3D content from a phrase', description: 'Turn a text prompt into a wide array of 3D content that you can drop right into Studio.', grids: [ { hero: { href: '/parts/procedural-models', title: 'Procedural models', description: 'Generate 3D models that automatically adjust to customizable attributes you define.', media: { src: '/assets/ai-landing/procedural_model_gen.gif', alt: 'Procedural models' } }, tiles: [ { title: 'Interactive 3D models', description: 'Through text prompts and preset schemas, let your players generate both interactive 3D models in your game, such as vehicles that drive, planes that fly, and weapons that shoot.', href: '/parts/model-generation', media: { src: '/assets/modeling/model-generation/Green-Dragon-Car.jpg' } }, { title: 'Avatar Auto-Setup', description: 'Automatically rigs, cages, and segments 3D models into fully functional, animatable Roblox avatars.', href: '/avatar-setup/auto-setup', media: { src: '/assets/art/resources/Archer-Girl-Preview.png', objectPosition: 'top' } } ] }, { layout: 'threeUp', cards: [ { href: '/assistant/guide#generate-meshes', title: 'Mesh generation', description: 'Describe what you need in Assistant or with an MCP command and get a textured MeshPart.', media: { src: '/assets/ai-landing/mesh-gen.jpg', alt: 'Mesh generation' } }, { title: 'Material generator', description: 'Seamless, tiling 2D images that can be saved as MaterialVariants, ideal for large surfaces like terrain, floors, and walls.', href: '/studio/material-generator', media: { src: '/assets/ai-landing/material-generator.png' } }, { title: 'Texture generator', description: 'Smart, context-aware textures that understand the geometry of your mesh to apply realistic patterns and wear.', href: '/studio/texture-generator', media: { src: '/assets/ai-landing/texture-gen.png' } } ] } ] }, naturalLanguage: { overline: 'NATURAL LANGUAGE APIs', title: 'Process text and speech in real time', description: 'Bridge the gap between text and voice, enabling more immersive social interactions and dynamic storytelling.', cardColumns: 4, cards: [ { title: 'Text-to-speech', description: 'Turn written text into spoken audio at runtime with AudioTextToSpeech, whether for narration, UI prompts, or giving your characters a voice.', href: '/tutorials/use-case-tutorials/audio/add-text-to-speech' }, { title: 'Speech-to-text', description: 'Capture what players say through their microphone and turn it into text for voice commands, chat, or captions.', href: '/tutorials/use-case-tutorials/audio/speech-to-text' }, { title: 'Text generation', description: 'Use large language models (LLMs) to power dynamic NPC dialogue. All generated text must be processed through the TextService:FilterStringAsync() method.', href: '/reference/engine/classes/TextGenerator' } ] }, development: { overline: 'DEVELOPMENT ASSISTANCE', title: 'Develop faster with coding and debugging tools', description: 'Keep your momentum while you code. These tools meet you wherever you work, from quick help in the script editor to an agent you can drive from your own editor.', cardColumns: 4, gridStyle: { marginBottom: 56 }, cards: [ { title: 'Code Assist', description: 'Get real-time code completions with suggestions based on the context of your script and comments.', href: '/studio/script-editor', media: { src: '/assets/studio/script-editor/Code-Assist.mp4', objectFit: 'contain' }, isVideo: true }, { title: 'Assistant', description: 'A conversational partner in Roblox Studio that can run and write code, generate materials, meshes, and models, simulate virtual inputs, and playtest your game.', href: '/assistant/guide', media: '/assets/ai-landing/assistant-planning-mode.png' }, { title: 'Studio MCP server', description: 'Connect any MCP client to your open Studio session, then read, edit, and playtest your place from wherever you work.', href: '/studio/mcp', media: '/assets/ai-landing/mcp-server.png' } ] }, watchAndLearn: { overline: 'Watch and Learn', title: 'See how to accelerate your creation workflows', description: 'Follow along with resources from the Roblox team that show how to set up AI workflows and recently released features.', featureTile: { youtubeId: 'v8r1d80DxOY', youtubeTitle: 'AI-assisted Studio workflow' }, secondaryTiles: [ { youtubeId: 'XsY8xhluuZM', youtubeTitle: 'Feature walkthrough' }, { youtubeId: 'ZlXA6QwJrHM', youtubeTitle: 'Creator workflow demo' } ] }, policies: { overline: 'Policies and guidelines', title: 'We value your safety and privacy', description: 'Roblox's AI tools are built with creator trust in mind. You remain in control of how your work and data are used, and every generation runs through the same moderation and Community Standards that apply to the rest of the platform. Review the guidelines below to understand your responsibilities as a creator and to configure how your assets contribute to model training.', cardColumns: 6, cardVariant: 'dark', cards: [ { title: 'Safety best practices', description: 'Generative AI accelerates creation, but you are responsible for the content generated within your games. Follow these guidelines to stay compliant with Roblox Community Standards.', href: '/generative-AI' }, { title: 'Data and privacy', description: 'Roblox is committed to transparency about how creator data is used for AI training. Manage your data sharing preferences on Creator Hub.', href: '/ai-data-sharing' } ] } } };

{(() => { const flexCol = { display: 'flex', flexDirection: 'column' }; const cardPad = { padding: '20px 22px 24px', flex: 1, ...flexCol }; const mb96 = { marginBottom: 96 }; const mediaSrc = (m) => (typeof m === 'string' ? m : m?.src); const mediaAlt = (m, fallback) => (typeof m === 'object' && m?.alt) || fallback; const mediaObjectPosition = (m) => (typeof m === 'object' && m?.objectPosition) || 'center'; const mediaObjectFit = (m) => (typeof m === 'object' && m?.objectFit) || 'cover'; const monoNum = { fontFamily: "'Builder Mono', monospace", fontSize: 12, fontWeight: 700, color: accent, }; const heroTitleStyle = { fontSize: 48, fontWeight: 800, letterSpacing: '-0.03em', lineHeight: 1.0, margin: '6px 0 20px', }; const coverImg = { position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', display: 'block', };

const pageSections = LANDING_PAGE_DATA.pageSections;

// Inline formatting for YAML copy: bold, inline code, and text. // Inline code renders via the site's InlineCode component (the intrinsic // is aliased to it), so its appearance is controlled by the 'main .inline-code' // rule in the

{flows.map((flow, i) => ( <button type="button" id={flow-tab-${flow.id}} className={flow-tab${i === 0 ? ' active' : ''}} > {flow.label} ))}
{flows.map((flow, fi) => ( <div id={flow-panel-${flow.id}} className={flow-panel${fi === 0 ? ' active' : ''}} >
{flow.steps.map((step, i) => ( <div id={acc-item-${flow.id}-${i}} className="acc-item"> <button type="button" className="acc-header" => e.currentTarget.closest('.acc-item')?.classList.toggle('open') } > {step.num}
{step.title} {step.subtitle}
▸
{detailFromMd(step.detail)}
))}
))}

);

const SectionHeader = ({ overline, title, description }) => (

{overline} {title} {renderInline(description, 'sh')}
);

const heroTileStyle = { position: 'relative', borderRadius: 14, overflow: 'hidden', width: '100%', aspectRatio: '24/9', background: tileBg, }; const heroOverlayStyle = { position: 'absolute', left: 24, right: 24, bottom: 24, zIndex: 2 }; const heroDescStyle = { maxWidth: '70%' };

const HeroSection = ({ title, description, media, href, ctas }) => { const src = mediaSrc(media); const hasCtas = Boolean(ctas?.length); const inner = (

{src && }
{title && ( {title} )}
{description && ( {description} )}

); const wrap = { marginBottom: 16 }; if (href && !hasCtas) { return ( {inner} ); } return
{inner}
; };

const linkCardMediaFill = { flex: 1, minHeight: 0 }; const linkCardMediaBox = { aspectRatio: '16/9' };

const LinkCardMedia = ({ media, isVideo, alt, fill }) => { const src = mediaSrc(media); const video = isVideo ?? (typeof media === 'object' && media?.isVideo); const mediaStyle = { width: '100%', height: '100%', objectFit: mediaObjectFit(media), objectPosition: mediaObjectPosition(media), display: 'block', ...(fill ? { position: 'absolute', inset: 0 } : {}), }; const wrapStyle = { width: '100%', background: 'var(--color-surface-0)', position: 'relative', overflow: 'hidden', ...(fill ? linkCardMediaFill : linkCardMediaBox), }; return (

{video ? (
); };

const linkCardTitleMb = { marginBottom: 4 };

const LinkCardBody = ({ card, showLearnMore = true, titleVariant = 'h5' }) => (

{card.title} {renderInline(card.description, 'lc')} {showLearnMore && card.href && (
{learnMoreText}
)}
);

const MediaTile = ({ href, media, youtubeId, youtubeTitle, title, description, fillCell = false, contentHeight = false, titleVariant = 'h4', noHover = false, }) => { const hasBody = Boolean(title || description); const src = mediaSrc(media); const ytTitle = youtubeTitle || title || 'YouTube video'; if (youtubeId && !hasBody && !href) { return

; } const card = { title, description, href }; const isVideoMedia = typeof media === 'object' && media?.isVideo; const cardInner = (

{youtubeId && ( <div style={fillCell ? { flex: 1, minHeight: 0, ...flexCol } : undefined}>

)} {!youtubeId && src && (

)} {hasBody && (

)}

); const tileStyle = contentHeight ? { height: 'auto' } : fillCell ? { height: '100%', width: '100%', flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', } : undefined; if (href) { return ( {cardInner} ); } return (

{cardInner}
); };

const splitGridAlign = (stretch) => ({ alignItems: stretch ? 'stretch' : 'center' }); const featureColStyle = (stretch) => ({ display: 'flex', alignItems: stretch ? 'stretch' : 'center', width: '100%', });

const ThreeUpRow = ({ cards, spacing = 2 }) => (

{cards.map((tile, i) => (

))}

);

const HeroWithTileRow = ({ hero, tiles, spacing = 2 }) => ( <>

{tiles.map((tile, i) => (

))}

</> );

const SplitFeatureGrid = ({ feature, tiles, spacing = 2, stretchFeature = false, noHover = false, stackSecondaryTiles = false, featureMedium = 6, secondaryMedium = 6, }) => (

{tiles.map((tile, i) => (

))}

);

const LinkCardSection = ({ overline, title, description, cards, cardColumns = 4, cardVariant = 'default', gridStyle, }) => (

{cards.map((card, i) => { const hasMedia = Boolean(card.media); const body =

; const cardStyle = linkCardStyles[hasMedia ? 'media' : cardVariant]; return (

{hasMedia && (

)} {hasMedia ?

{body}

: body}

); })}

);

const s = pageSections; return (<>

{s.creation3d.grids.map((grid, i) => (

{grid.layout === 'threeUp' ? (

) : (

)}

))}

); })()}