1<!doctype html> 2<html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <!-- FAVICON BLOCK â START 6 The Express SSR (node/index.js) replaces everything between 7 these markers (inclusive) with per-game favicon + 8 apple-touch-icon links on /launch/:gameId and /play/:gameId so 9 the OS shows the game's app icon in the Mac dock, Windows 10 taskbar, iOS home-screen bookmark, and browser tab. On all 11 other routes (and in Vite dev mode where there's no SSR) the 12 block stays as-is and the default Tesana logo is used. --> 13 <link rel="icon" type="image/x-icon" href="/favicon.ico" /> 14 <link rel="icon" type="image/png" href="/logos/logo.png" /> 15 <link rel="apple-touch-icon" href="/apple-touch-icon.png" /> 16 <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" /> 17 <link rel="apple-touch-icon" sizes="512x512" href="/apple-touch-icon.png" /> 18 <!-- FAVICON BLOCK â END --> 19 <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" /> 20 <meta name="theme-color" content="#161616" /> 21 <!-- Apply the saved theme class to <html> before first paint so the 22 initial loader (and the whole app's CSS variables) render in the 23 right theme with no flash. ThemeContext reconciles this on mount. --> 24
24<script> 25 (function () { 26 try { 27 var t = localStorage.getItem('onetap_theme'); 28 if (t !== 'light' && t !== 'dark') { 29 t = window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches 30 ? 'light' 31 : 'dark'; 32 } 33 document.documentElement.classList.add(t); 34 } catch (e) { 35 document.documentElement.classList.add('dark'); 36 } 37 })(); 38 </script>
38 39 <title>Blog | Tesana</title> 40 <meta name="description" content="Read the latest articles about AI game development, vibe coding, and building playable worlds with Tesana." /> 41 <!-- Canonical and share link are separate on purpose: a public game's play 42 addresses point Google at its storefront, while the share card keeps 43 the game's own address so a tap lands in the game (node/index.js). --> 44 <link rel="canonical" href="https://tesana.com/blog" /> 45 46 47 <!-- OpenGraph --> 48 <meta property="og:type" content="website" /> 49 <meta property="og:url" content="https://tesana.com/blog" /> 50 <meta property="og:title" content="Blog | Tesana" /> 51 <meta property="og:description" content="Read the latest articles about AI game development, vibe coding, and building playable worlds with Tesana." /> 52 <meta property="og:image" content="https://tesana.com/og-image.jpg" /> 53 <meta property="og:image:secure_url" content="https://tesana.com/og-image.jpg" /> 54 <meta property="og:image:type" content="image/jpeg" /> 55 <meta property="og:image:width" content="1200" /> 56 <meta property="og:image:height" content="630" /> 57 <meta property="og:image:alt" content="Tesana" /> 58 <meta property="og:site_name" content="Tesana" /> 59 60 <!-- Twitter Card --> 61 <meta name="twitter:card" content="summary_large_image" /> 62 <meta name="twitter:site" content="@TesanaAI" /> 63 <meta name="twitter:title" content="Blog | Tesana" /> 64 <meta name="twitter:description" content="Read the latest articles about AI game development, vibe coding, and building playable worlds with Tesana." /> 65 <meta name="twitter:image" content="https://tesana.com/og-image.jpg" /> 66 <meta name="twitter:image:alt" content="Tesana" /> 67 68 <link rel="alternate" hreflang="en" href="https://tesana.com/blog" /> 69 <link rel="alternate" hreflang="ru" href="https://tesana.com/ru/blog" /> 70 <link rel="alternate" hreflang="zh" href="https://tesana.com/zh/blog" /> 71 <link rel="alternate" hreflang="ja" href="https://tesana.com/ja/blog" /> 72 <link rel="alternate" hreflang="ko" href="https://tesana.com/ko/blog" /> 73 <link rel="alternate" hreflang="pt-BR" href="https://tesana.com/pt-BR/blog" /> 74 <link rel="alternate" hreflang="x-default" href="https://tesana.com/blog" /> 75
75<script type="application/ld+json">{"@context":"https://schema.org","@type":"CollectionPage","name":"Tesana Blog","url":"https://tesana.com/blog","description":"Articles about AI game development, vibe coding, and building playable worlds."}</script>
75 76 77 78 <!-- Warm the connections every page needs before its script asks: the API 79 (CORS requests, hence crossorigin), and the hosts game art and builds 80 come from. dns-prefetch is the fallback where preconnect is not 81 supported. --> 82 <link rel="preconnect" href="https://api.tesana.ai" crossorigin /> 83 <link rel="preconnect" href="https://cdn.tesana.ai" /> 84 <link rel="preconnect" href="https://play.tesana.ai" /> 85 <link rel="dns-prefetch" href="https://api.tesana.ai" /> 86 <link rel="dns-prefetch" href="https://cdn.tesana.ai" /> 87 <link rel="dns-prefetch" href="https://play.tesana.ai" /> 88 89 <!-- Preload critical above-fold assets --> 90 <link rel="preload" href="/fonts/sf-pro-latin.woff2" as="font" type="font/woff2" crossorigin /> 91 <link rel="preload" href="/fonts/sf-pro-expanded-latin.woff2" as="font" type="font/woff2" crossorigin /> 92 <link rel="preload" href="/logos/tessala-logo.svg" as="image" /> 93 94 <!-- Google Tag Manager --> 95
95<script>
vendor: 343 bytes, lines 95-99
95(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 96 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 97 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 98 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 99 })(window,document,'script','dataLayer','
99GTM-MN5SQGK5
vendor: 3 bytes, line 99
99');
99</script>
99 100 <!-- End Google Tag Manager --> 101 102 <!-- Web-only third-party analytics scripts. 103 Skipped entirely when loaded inside the Tauri desktop bundle: 104 - GTM, Mixpanel CDN, and Facebook Pixel all hit endpoints that 105 CORS-reject the `tauri://localhost` origin (3rd-party servers 106 can't add a Tauri-specific allowlist), so they're effectively 107 dead weight in the .app â and worse, they pollute the console 108 with CSP / network errors that drown out our own logs. 109 - The Mixpanel snippet specifically tries to load 110 `//cdn.mxpnl.com/...` which Tauri resolves to `tauri:` scheme 111 (404). Setting MIXPANEL_CUSTOM_LIB_URL would only mask that 112 one error, not the underlying CORS dead-end. 113 The empty `mixpanel` / `dataLayer` / `fbq` globals defined later 114 (inside the if-not-Tauri block) keep app-side `mixpanel.track(â¦)` 115 calls safely no-op'd in Tauri. --> 116
116<script> 117 window.__TESANA_IS_TAURI = !!window.__TAURI_INTERNALS__; 118 if (window.__TESANA_IS_TAURI) { 119 // Tag the document so CSS can target Tauri builds (e.g. to 120 // disable WebKit overscroll/rubberband bounce â see the 121 // `html.tesana-tauri` block in src/styles/index.css). 122 document.documentElement.classList.add('tesana-tauri'); 123 // No-op stubs so app code can keep calling mixpanel.* / fbq() / etc. 124 // without runtime errors. 125 // 126 // CRITICAL: the mixpanel stub MUST be recursive. App code calls 127 // chained APIs like `mixpanel.people.set({...})`, 128 // `mixpanel.register(...)`, `mixpanel.get_group(...).set(...)`. 129 // A flat `{ get: () => fn }` proxy returns a plain function for 130 // `mixpanel.people` and then `.set` on that function is 131 // `undefined` â `TypeError: ...is not a function`. That 132 // TypeError gets caught by `AuthContext.initAuth`'s try/catch 133 // (which only looks for HTTP 401/403 to mean "auth error"), 134 // falls into the generic `else` branch, and triggers the 135 // "Unable to reach our servers" overlay even though every API 136 // call actually succeeded with 200. 137 // 138 // The recursive proxy below makes every property access AND 139 // every call return another no-op proxy, so any chain depth 140 // works. We also nullify `then` so async code that does 141 // `await mixpanel.something()` doesn't accidentally treat the 142 // proxy as a thenable and hang. 143 var __noopProxyHandler = { 144 get: function (target, prop) { 145 if (prop === 'then') return undefined; 146 if (prop === Symbol.toPrimitive) return function () { return '[mixpanel-stub]'; }; 147 return new Proxy(function () {}, __noopProxyHandler); 148 }, 149 // Also return a chainable stub on call so patterns like 150 // `mixpanel.get_group('id').set('k', 'v')` don't crash on the 151 // intermediate `(...)` returning undefined. 152 apply: function () { 153 return new Proxy(function () {}, __noopProxyHandler); 154 }, 155 }; 156 window.mixpanel = new Proxy(function () {}, __noopProxyHandler); 157 window.dataLayer = window.dataLayer || []; 158 window.fbq = function () {}; 159 window.fbq.queue = []; 160 161 // (Removed in Phase A.5, May 2026: the cross-game-relaunch 162 // pre-React overlay. The subprocess libgodot architecture 163 // means cross-game switches no longer require a Tesana 164 // relaunch â `RunnerSupervisor::boot()` kills + respawns 165 // the runner subprocess for the new project, which the 166 // standard "Starting engineâ¦" overlay in 167 // `EmbeddedGameViewport` already covers visually.) 168 } 169 </script>
169 170 171
171<script type="text/javascript"> 172 if (!window.__TESANA_IS_TAURI) { 173 (function(e,c){if(!c.__SV){var l,h;window.mixpanel=c;c._i=[];c.init=function(q,r,f){function t(d,a){var g=a.split(".");2==g.length&&(d=d[g[0]],a=g[1]);d[a]=function(){d.push([a].concat(Array.prototype.slice.call(arguments,0)))}}var b=c;"undefined"!==typeof f?b=c[f]=[]:f="mixpanel";b.people=b.people||[];b.toString=function(d){var a="mixpanel";"mixpanel"!==f&&(a+="."+f);d||(a+=" (stub)");return a};b.people.toString=function(){return b.toString(1)+".people (stub)"};l="disable time_event track track_pageview track_links track_forms track_with_groups add_group set_group remove_group register register_once alias unregister identify name_tag set_config reset opt_in_tracking opt_out_tracking has_opted_in_tracking has_opted_out_tracking clear_opt_in_out_tracking start_batch_senders start_session_recording stop_session_recording people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user people.remove".split(" "); 174 for(h=0;h<l.length;h++)t(b,l[h]);var n="set set_once union unset remove delete".split(" ");b.get_group=function(){function d(p){a[p]=function(){b.push([g,[p].concat(Array.prototype.slice.call(arguments,0))])}}for(var a={},g=["get_group"].concat(Array.prototype.slice.call(arguments,0)),m=0;m<n.length;m++)d(n[m]);return a};c._i.push([q,r,f])};c.__SV=1.2;var k=e.createElement("script");k.type="text/javascript";k.async=!0;k.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?MIXPANEL_CUSTOM_LIB_URL:"file:"=== 175 e.location.protocol&&"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//)?"https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";e=e.getElementsByTagName("script")[0];e.parentNode.insertBefore(k,e)}})(document,window.mixpanel||[]) 176 } 177 178 if (!window.__TESANA_IS_TAURI) { 179 mixpanel.init('58796b6270bbfcff93403caaf515001a', { 180 autocapture: true, 181 track_pageview: false, 182 record_sessions_percent: 25, 183 }) 184 } 185 186 // CRITICAL â Register attribution super properties BEFORE the first $mp_web_page_view 187 // fires. We disable Mixpanel's automatic page view (track_pageview: false) and fire 188 // it manually below, AFTER UTM + click-ID super properties are queued. This guarantees 189 // every Mixpanel event (autocapture included) carries the correct attribution context 190 // for ad-spend measurement. 191 ;(function () { 192 try { 193 var loc = window.location || {} 194 var search = loc.search || '' 195 var params = null 196 try { params = new URLSearchParams(search) } catch (_e) { params = null } 197 198 var ATTR_KEYS = [ 199 'utm_source','utm_medium','utm_campaign','utm_term','utm_content','utm_id', 200 'gclid','fbclid','msclkid','ttclid','twclid','li_fat_id','igshid','yclid','dclid', 201 'wbraid','gbraid','rdt_cid','epik','_kx','ref','referrer','source' 202 ] 203 204 var sessionAttr = { 205 platform: 'web', 206 page_hostname: loc.hostname || null, 207 page_host: loc.host || null, 208 page_origin: loc.origin || null, 209 } 210 var firstTouchAttr = { 211 first_touch_url: loc.href || null, 212 first_touch_path: loc.pathname || null, 213 first_touch_referrer: (document && document.referrer) || null, 214 } 215 216 if (params) { 217 ATTR_KEYS.forEach(function (k) { 218 var v = params.get(k) 219 if (v != null && v !== '' && v !== 'undefined' && v !== 'null') { 220 sessionAttr[k] = v 221 firstTouchAttr['first_touch_' + k] = v 222 } 223 }) 224 } 225 226 if (window.__TESANA_IS_TAURI) { 227 // Skip â Mixpanel doesn't accept tauri://localhost as an origin 228 // and these calls would just queue events that never flush. 229 return 230 } 231 232 mixpanel.register(sessionAttr) 233 mixpanel.register_once(firstTouchAttr) 234 235 // Fire the initial page view AFTER super properties are queued so the very 236 // first $mp_web_page_view carries utm_source / rdt_cid / etc. 237 mixpanel.track_pageview() 238 } catch (e) { 239 // Tracking must never break the page; swallow any errors. 240 } 241 })(); 242 243 </script>
243 244
244<script type="module" crossorigin src="/assets/index-BKzE8EQ8.js"></script>
244 245 <link rel="modulepreload" crossorigin href="/assets/vendor-react-E98sgxjj.js"> 246 <link rel="modulepreload" crossorigin href="/assets/vendor-motion-hRg_q8lq.js"> 247 <link rel="modulepreload" crossorigin href="/assets/vendor-fa-Bn2dnpnC.js"> 248 <link rel="modulepreload" crossorigin href="/assets/vendor-query-bOUN_gKe.js"> 249 <link rel="stylesheet" crossorigin href="/assets/index-36zER57x.css"> 250
250<script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script>
250</head> 251 <body> 252 <!-- Google Tag Manager (noscript) -->
vendor: 72 bytes, lines 252-253
252 253 <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
253GTM-MN5SQGK5
vendor: 91 bytes, lines 253-255
253" 254 height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> 255
255<!-- End Google Tag Manager (noscript) --> 256 257 <div id="root"> 258 <!-- PRERENDER_CONTENT_START --><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false" data-prerender-ready="queries-settled" data-prerender-language="en"></section><div class="min-h-screen bg-background text-foreground"><header data-public-nav="" class="z-50 absolute inset-x-0 top-0"><nav aria-label="Main navigation" class="flex h-14 items-center justify-between gap-2 px-4 md:grid md:h-[72px] md:grid-cols-[1fr_auto_1fr] md:gap-4 md:px-6 lg:px-8"><div class="flex items-center gap-2"><a aria-label="Tesana" class="rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/40" href="/"><span aria-hidden="true" class="block select-none whitespace-nowrap font-expanded text-[24px] font-[650] leading-6 text-foreground">TESANA</span></a></div><div class="hidden items-center gap-2 md:flex"><div class="flex h-10 items-center gap-1 overflow-hidden rounded-full bg-pill/50 p-0.5"><a class="relative isolate flex h-9 items-center gap-2 rounded-full px-4 text-base leading-6 transition-colors lg:px-6 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/40 text-muted-foreground hover:text-foreground" href="/"><svg data-prefix="fas" data-icon="house" class="svg-inline--fa fa-house text-[16px] fa-width-auto" role="img" viewBox="0 0 512 512" aria-hidden="true"><path fill="currentColor" d="M277.8 8.6c-12.3-11.4-31.3-11.4-43.5 0l-224 208c-9.6 9-12.8 22.9-8 35.1S18.8 272 32 272l16 0 0 176c0 35.3 28.7 64 64 64l288 0c35.3 0 64-28.7 64-64l0-176 16 0c13.2 0 25-8.1 29.8-20.3s1.6-26.2-8-35.1l-224-208zM240 320l32 0c26.5 0 48 21.5 48 48l0 96-128 0 0-96c0-26.5 21.5-48 48-48z"></path></svg><span>Home</span></a><a class="relative isolate flex h-9 items-center gap-2 rounded-full px-4 text-base leading-6 transition-colors lg:px-6 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/40 text-muted-foreground hover:text-foreground" href="/play"><svg data-prefix="fas" data-icon="play" class="svg-inline--fa fa-play text-[16px] fa-width-auto" role="img" viewBox="0 0 448 512" aria-hidden="true"><path fill="currentColor" d="M91.2 36.9c-12.4-6.8-27.4-6.5-39.6 .7S32 57.9 32 72l0 368c0 14.1 7.5 27.2 19.6 34.4s27.2 7.5 39.6 .7l336-184c12.8-7 20.8-20.5 20.8-35.1s-8-28.1-20.8-35.1l-336-184z"></path></svg><span>Play</span></a><a class="relative isolate flex h-9 items-center gap-2 rounded-full px-4 text-base leading-6 transition-colors lg:px-6 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/40 text-muted-foreground hover:text-foreground" href="/create"><svg data-prefix="fas" data-icon="hammer" class="svg-inline--fa fa-hammer text-[16px] fa-width-auto" role="img" viewBox="0 0 640 512" aria-hidden="true"><path fill="currentColor" d="M246.9 18.3L271 3.8c21.6-13 46.3-19.8 71.5-19.8 36.8 0 72.2 14.6 98.2 40.7l63.9 63.9c15 15 23.4 35.4 23.4 56.6l0 30.9 19.7 19.7 0 0c15.6-15.6 40.9-15.6 56.6 0s15.6 40.9 0 56.6l-64 64c-15.6 15.6-40.9 15.6-56.6 0s-15.6-40.9 0-56.6L464 240 433.1 240c-21.2 0-41.6-8.4-56.6-23.4l-49.1-49.1c-15-15-23.4-35.4-23.4-56.6l0-12.7c0-11.2-5.9-21.7-15.5-27.4l-41.6-25c-10.4-6.2-10.4-21.2 0-27.4zM50.7 402.7l222.1-222.1 90.5 90.5-222.1 222.1c-25 25-65.5 25-90.5 0s-25-65.5 0-90.5z"></path></svg><span>Create</span></a></div><button type="button" aria-label="Search" title="Search" class="inline-flex h-10 shrink-0 items-center justify-center rounded-full text-base leading-6 transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/40 w-10 bg-pill text-muted-foreground hover:text-foreground"><svg data-prefix="fas" data-icon="magnifying-glass" class="svg-inline--fa fa-magnifying-glass text-[16px]" role="img" viewBox="0 0 512 512" aria-hidden="true"><path fill="currentColor" d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376C296.3 401.1 253.9 416 208 416 93.1 416 0 322.9 0 208S93.1 0 208 0 416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"></path></svg></button></div><div class="flex items-center justify-end gap-2"><button type="button" aria-label="Search" title="Search" class="inline-flex h-10 shrink-0 items-center justify-center rounded-full text-base leading-6 transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground
258/40 w-10 bg-pill text-muted-foreground hover:text-foreground md:hidden"><svg data-prefix="fas" data-icon="magnifying-glass" class="svg-inline--fa fa-magnifying-glass text-[16px]" role="img" viewBox="0 0 512 512" aria-hidden="true"><path fill="currentColor" d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376C296.3 401.1 253.9 416 208 416 93.1 416 0 322.9 0 208S93.1 0 208 0 416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"></path></svg></button><button type="button" class="h-10 shrink-0 items-center justify-center rounded-full text-base leading-6 transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/40 hidden bg-pill px-6 text-muted-foreground hover:text-foreground lg:inline-flex">Log in</button><button type="button" class="inline-flex h-10 shrink-0 items-center justify-center rounded-full text-base leading-6 transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/40 bg-foreground px-6 text-background hover:opacity-85 md:max-lg:px-4">Sign up</button></div></nav></header><nav aria-label="Main navigation" data-public-tabbar="" class="fixed inset-x-0 bottom-0 z-40 border-t border-foreground
258/10 bg-background pb-[env(safe-area-inset-bottom)] md:hidden transition-transform duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:transition-none"><ul class="flex h-16 px-6"><li class="flex flex-1"><a class="relative flex flex-1 flex-col items-center gap-[5px] pt-[9px] text-xs leading-4 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/40 text-tab-inactive hover:text-foreground" href="/"><svg data-prefix="fas" data-icon="house" class="svg-inline--fa fa-house relative h-[22px] text-[22px] fa-width-auto" role="img" viewBox="0 0 512 512" aria-hidden="true"><path fill="currentColor" d="M277.8 8.6c-12.3-11.4-31.3-11.4-43.5 0l-224 208c-9.6 9-12.8 22.9-8 35.1S18.8 272 32 272l16 0 0 176c0 35.3 28.7 64 64 64l288 0c35.3 0 64-28.7 64-64l0-176 16 0c13.2 0 25-8.1 29.8-20.3s1.6-26.2-8-35.1l-224-208zM240 320l32 0c26.5 0 48 21.5 48 48l0 96-128 0 0-96c0-26.5 21.5-48 48-48z"></path></svg><span class="relative">Home</span></a></li><li class="flex flex-1"><a class="relative flex flex-1 flex-col items-center gap-[5px] pt-[9px] text-xs leading-4 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/40 text-tab-inactive hover:text-foreground" href="/play"><svg data-prefix="fas" data-icon="play" class="svg-inline--fa fa-play relative h-[22px] text-[22px] fa-width-auto" role="img" viewBox="0 0 448 512" aria-hidden="true"><path fill="currentColor" d="M91.2 36.9c-12.4-6.8-27.4-6.5-39.6 .7S32 57.9 32 72l0 368c0 14.1 7.5 27.2 19.6 34.4s27.2 7.5 39.6 .7l336-184c12.8-7 20.8-20.5 20.8-35.1s-8-28.1-20.8-35.1l-336-184z"></path></svg><span class="relative">Play</span></a></li><li class="flex flex-1"><a class="relative flex flex-1 flex-col items-center gap-[5px] pt-[9px] text-xs leading-4 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/40 text-tab-inactive hover:text-foreground" href="/create"><svg data-prefix="fas" data-icon="hammer" class="svg-inline--fa fa-hammer relative h-[22px] text-[22px] fa-width-auto" role="img" viewBox="0 0 640 512" aria-hidden="true"><path fill="currentColor" d="M246.9 18.3L271 3.8c21.6-13 46.3-19.8 71.5-19.8 36.8 0 72.2 14.6 98.2 40.7l63.9 63.9c15 15 23.4 35.4 23.4 56.6l0 30.9 19.7 19.7 0 0c15.6-15.6 40.9-15.6 56.6 0s15.6 40.9 0 56.6l-64 64c-15.6 15.6-40.9 15.6-56.6 0s-15.6-40.9 0-56.6L464 240 433.1 240c-21.2 0-41.6-8.4-56.6-23.4l-49.1-49.1c-15-15-23.4-35.4-23.4-56.6l0-12.7c0-11.2-5.9-21.7-15.5-27.4l-41.6-25c-10.4-6.2-10.4-21.2 0-27.4zM50.7 402.7l222.1-222.1 90.5 90.5-222.1 222.1c-25 25-65.5 25-90.5 0s-25-65.5 0-90.5z"></path></svg><span class="relative">Create</span></a></li></ul></nav><main class="container pt-28 md:pt-35 pb-10 md:pb-16"><h1 class="sr-only">Blog</h1><div class="grid gap-2 lg:grid-cols-3"><div class="lg:col-span-2"><div class="lg:sticky lg:top-8"><a class="group flex flex-col overflow-hidden rounded-md bg-foreground
258/6 transition-colors hover:bg-foreground/10" href="/blog/from-godot-to-three-js-faster-better-games-on-tesana"><div class="aspect-[16/9] overflow-hidden bg-surface shrink-0"><picture style="display: contents;"><source srcset="/godot-threejs/godot-threejs-banner-full-blog-image.avif" type="image/avif"><source srcset="/godot-threejs/godot-threejs-banner-full-blog-image.webp" type="image/webp"><img src="/godot-threejs/godot-threejs-banner-full-blog-image.jpg" alt="From Godot to Three.js: Faster, Better Games on Tesana" loading="lazy" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-[1.02]"></picture></div><div class="flex flex-col gap-2 p-5 md:p-6"><p class="text-sm text-muted-foreground">Sep 28, 2026 · Announcement</p><h3 class="text-foreground transition-colors group-hover:text-foreground/85 text-lg">From Godot to Three.js: Faster, Better Games on Tesana</h3><p class="text-sm text-muted-foreground line-clamp-3">We rebuilt Tesana's game engine around Three.js. Games are now web-native, with no editor format and no export step, so they generate faster and play better. Average generation time dropped from around 60 minutes to under 5. Here's why we made the switch and what changes for you.</p><div class="flex items-center gap-2 min-w-0 mt-2"><picture style="display: contents;"><source srcset="/logos/logo.avif" type="image/avif"><source srcset="/logos/logo.webp" type="image/webp"><img src="/logos/logo.png" alt="" aria-hidden="true" loading="lazy" class="w-6 h-6 rounded-full object-cover shrink-0 bg-surface"></picture><span class="text-sm text-muted-foreground truncate">Tesana Team · 3 min read</span></div></div></a></div></div><div class="grid gap-2 content-start"><a class="group flex flex-col overflow-hidden rounded-md bg-foreground
258/6 transition-colors hover:bg-foreground/10" href="/blog/tesana-quality-index-and-ending-the-model-picker"><div class="aspect-[16/9] overflow-hidden bg-surface shrink-0"><picture style="display: contents;"><source srcset="/tqi/tqi-banner-full-blog-image.avif" type="image/avif"><source srcset="/tqi/tqi-banner-full-blog-image.webp" type="image/webp"><img src="/tqi/tqi-banner-full-blog-image.jpg" alt="Tesana Quality Index and Ending the Model Picker" loading="lazy" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-[1.02]"></picture></div><div class="flex flex-col gap-2 p-5"><p class="text-sm text-muted-foreground">Sep 22, 2026 · Announcement</p><h3 class="text-foreground transition-colors group-hover:text-foreground/85 text-base">Tesana Quality Index and Ending the Model Picker</h3><p class="text-sm text-muted-foreground line-clamp-3">Models are moving targets, so we built the Tesana Quality Index â our benchmark for agentic game building â to decide which model builds each part of your game. That's why we're removing the model picker and retiring Muranyi and Atomos. Here's how TQI and the Director work.</p><div class="flex items-center gap-2 min-w-0 mt-2"><picture style="display: contents;"><source srcset="/logos/logo.avif" type="image/avif"><source srcset="/logos/logo.webp" type="image/webp"><img src="/logos/logo.png" alt="" aria-hidden="true" loading="lazy" class="w-6 h-6 rounded-full object-cover shrink-0 bg-surface"></picture><span class="text-sm text-muted-foreground truncate">Tesana Team · 6 min read</span></div></div></a><a class="group flex flex-col overflow-hidden rounded-md bg-foreground
258/6 transition-colors hover:bg-foreground/10" href="/blog/introducing-image-to-game"><div class="aspect-[16/9] overflow-hidden bg-surface shrink-0"><picture style="display: contents;"><source srcset="/explore/explore-banner-full-blog-image.avif" type="image/avif"><source srcset="/explore/explore-banner-full-blog-image.webp" type="image/webp"><img src="/explore/explore-banner-full-blog-image.jpg" alt="Introducing Image to Game" loading="lazy" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-[1.02]"></picture></div><div class="flex flex-col gap-2 p-5"><p class="text-sm text-muted-foreground">Sep 12, 2026 · Announcement</p><h3 class="text-foreground transition-colors group-hover:text-foreground/85 text-base">Introducing Image to Game</h3><p class="text-sm text-muted-foreground line-clamp-3">Any image can become a game. Bring a picture from the Explore wall, upload your own, or drop in a screenshot â Tesana builds a playable game with the same look and feel, usually in about five minutes. Here's how it works and what it made.</p><div class="flex items-center gap-2 min-w-0 mt-2"><picture style="display: contents;"><source srcset="/logos/logo.avif" type="image/avif"><source srcset="/logos/logo.webp" type="image/webp"><img src="/logos/logo.png" alt="" aria-hidden="true" loading="lazy" class="w-6 h-6 rounded-full object-cover shrink-0 bg-surface"></picture><span class="text-sm text-muted-foreground truncate">Tesana Team · 3 min read</span></div></div></a></div></div><div class="mt-15 md:mt-24"><form class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between md:gap-8"><p class="text-sm md:text-base text-muted-foreground">Subscribe to our newsletter for blog updates and original content</p><div class="flex items-center gap-2 h-11 w-full md:max-w-[460px] rounded-md border border-border 259 bg-card px-4 transition-colors focus-within:border-border-hover"><input type="email" required="" placeholder="Email address" aria-label="Email address" class="flex-1 min-w-0 bg-transparent border-none outline-none text-sm 260 text-foreground placeholder:text-muted-foreground" value=""><button type="submit" class="shrink-0 inline-flex items-center gap-1.5 text-sm text-muted-foreground 261 hover:text-foreground transition-colors cursor-pointer">Subscribe<svg data-prefix="far" data-icon="arrow-right" class="svg-inline--fa fa-arrow-right text-xs" role="img" viewBox="0 0 512 512" aria-hidden="true"><path fill="currentColor" d="M505 273c9.4-9.4 9.4-24.6 0-33.9L337 71c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l127 127-406.1 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l406.1 0-127 127c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0L505 273z"></path></svg></button></div></form></div><div class="mt-16 md:mt-24">
261<div class="rounded-md bg-foreground/6 overflow-hidden"><ul><li><a class="group grid gap-x-6 gap-y-1 px-5 py-4 transition-colors hover:bg-foreground/4 262 md:grid-cols-[minmax(0,14rem)_minmax(0,1fr)_minmax(0,11rem)_2.5rem] md:items-center" href="/blog/introducing-loop"><span class="text-sm text-muted-foreground order-2 md:order-none"><span class="md:hidden">Jul 23, 2026 · Announcement · Tesana Team · 3m</span><span class="hidden md:inline">Jul 23, 2026 · Announcement</span></span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85 order-1 md:order-none">Introducing Loop</span><span class="hidden md:block text-sm text-muted-foreground truncate">Tesana Team</span><span class="hidden md:block text-sm text-muted-foreground text-right tabular-nums">3m</span></a></li><li class="border-t border-foreground/8"><a class="group grid gap-x-6 gap-y-1 px-5 py-4 transition-colors hover:bg-foreground/4 263 md:grid-cols-[minmax(0,14rem)_minmax(0,1fr)_minmax(0,11rem)_2.5rem] md:items-center" href="/blog/introducing-atomos"><span class="text-sm text-muted-foreground order-2 md:order-none"><span class="md:hidden">Jun 24, 2026 · Announcement · Tesana Team · 3m</span><span class="hidden md:inline">Jun 24, 2026 · Announcement</span></span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85 order-1 md:order-none">Introducing Atomos</span><span class="hidden md:block text-sm text-muted-foreground truncate">Tesana Team</span><span class="hidden md:block text-sm text-muted-foreground text-right tabular-nums">3m</span></a></li>
263<li class="border-t border-foreground/8"><a class="group grid gap-x-6 gap-y-1 px-5 py-4 transition-colors hover:bg-foreground/4 264 md:grid-cols-[minmax(0,14rem)_minmax(0,1fr)_minmax(0,11rem)_2.5rem] md:items-center" href="/blog/introducing-muranyi-3"><span class="text-sm text-muted-foreground order-2 md:order-none"><span class="md:hidden">May 17, 2026 · Announcement · Tesana Team · 6m</span><span class="hidden md:inline">May 17, 2026 · Announcement</span></span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85 order-1 md:order-none">Introducing Muranyi-3</span><span class="hidden md:block text-sm text-muted-foreground truncate">Tesana Team</span><span class="hidden md:block text-sm text-muted-foreground text-right tabular-nums">6m</span></a></li><li class="border-t border-foreground/8"><a class="group grid gap-x-6 gap-y-1 px-5 py-4 transition-colors hover:bg-foreground/4 265 md:grid-cols-[minmax(0,14rem)_minmax(0,1fr)_minmax(0,11rem)_2.5rem] md:items-center" href="/blog/tesana-create-ai-games-and-grow-a-community"><span class="text-sm text-muted-foreground order-2 md:order-none"><span class="md:hidden">Feb 6, 2026 · Announcement · Tesana Team · 8m</span><span class="hidden md:inline">Feb 6, 2026 · Announcement</span></span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85 order-1 md:order-none">Tesana: Create AI Games and Grow a Community</span><span class="hidden md:block text-sm text-muted-foreground truncate">Tesana Team</span><span class="hidden md:block text-sm text-muted-foreground text-right tabular-nums">8m</span></a></li>
265<li class="border-t border-foreground/8"><a class="group grid gap-x-6 gap-y-1 px-5 py-4 transition-colors hover:bg-foreground/4 266 md:grid-cols-[minmax(0,14rem)_minmax(0,1fr)_minmax(0,11rem)_2.5rem] md:items-center" href="/blog/can-i-make-games-with-lovable-(and-why-tesana-is-better-for-vibe-coding-actual-games)"><span class="text-sm text-muted-foreground order-2 md:order-none"><span class="md:hidden">Feb 5, 2026 · Guide · Michael Shan · 14m</span><span class="hidden md:inline">Feb 5, 2026 · Guide</span></span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85 order-1 md:order-none">Can I Make Games With Lovable? (And Why Tesana Is Better for Vibe-Coding Actual Games)</span><span class="hidden md:block text-sm text-muted-foreground truncate">Michael Shan</span><span class="hidden md:block text-sm text-muted-foreground text-right tabular-nums">14m</span></a></li><li class="border-t border-foreground/8"><a class="group grid gap-x-6 gap-y-1 px-5 py-4 transition-colors hover:bg-foreground
266/4 267 md:grid-cols-[minmax(0,14rem)_minmax(0,1fr)_minmax(0,11rem)_2.5rem] md:items-center" href="/blog/vibe-code-games-create-playable-worlds-with-ai"><span class="text-sm text-muted-foreground order-2 md:order-none"><span class="md:hidden">Feb 4, 2026 · Guide · Michael Shan · 20m</span><span class="hidden md:inline">Feb 4, 2026 · Guide</span></span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85 order-1 md:order-none">Vibe Code Games: Create Playable Worlds with AI</span><span class="hidden md:block text-sm text-muted-foreground truncate">Michael Shan</span><span class="hidden md:block text-sm text-muted-foreground text-right tabular-nums">20m</span></a></li><li class="border-t border-foreground/8"><a class="group grid gap-x-6 gap-y-1 px-5 py-4 transition-colors hover:bg-foreground/4 268 md:grid-cols-[minmax(0,14rem)_minmax(0,1fr)_minmax(0,11rem)_2.5rem] md:items-center" href="/blog/best-ai-game-development-tool-why-tesana-belongs-at-the-top"><span class="text-sm text-muted-foreground order-2 md:order-none"><span class="md:hidden">Feb 4, 2026 · Guide · Michael Shan · 18m</span><span class="hidden md:inline">Feb 4, 2026 · Guide</span></span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85 order-1 md:order-none">Best AI Game Development Tool: Why Tesana Belongs at the Top</span><span class="hidden md:block text-sm text-muted-foreground truncate">Michael Shan</span><span class="hidden md:block text-sm text-muted-foreground text-right tabular-nums">18m</span></a></li>
268<li class="border-t border-foreground/8"><a class="group grid gap-x-6 gap-y-1 px-5 py-4 transition-colors hover:bg-foreground/4 269 md:grid-cols-[minmax(0,14rem)_minmax(0,1fr)_minmax(0,11rem)_2.5rem] md:items-center" href="/blog/vibe-code-games-with-ai-from-first-prompt-to-playable-world"><span class="text-sm text-muted-foreground order-2 md:order-none"><span class="md:hidden">Feb 4, 2026 · Guide · Michael Shan · 19m</span><span class="hidden md:inline">Feb 4, 2026 · Guide</span></span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85 order-1 md:order-none">Vibe Code Games with AI: From First Prompt to Playable World</span><span class="hidden md:block text-sm text-muted-foreground truncate">Michael Shan</span><span class="hidden md:block text-sm text-muted-foreground text-right tabular-nums">19m</span></a></li><li class="border-t border-foreground/8"><a class="group grid gap-x-6 gap-y-1 px-5 py-4 transition-colors hover:bg-foreground/4 270 md:grid-cols-[minmax(0,14rem)_minmax(0,1fr)_minmax(0,11rem)_2.5rem] md:items-center" href="/blog/how-to-vibe-code-games-(fast)-with-ai-tesana"><span class="text-sm text-muted-foreground order-2 md:order-none"><span class="md:hidden">Feb 4, 2026 · Guide · Michael Shan · 22m</span><span class="hidden md:inline">Feb 4, 2026 · Guide</span></span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85 order-1 md:order-none">How to Vibe Code Games (Fast) with AI & Tesana</span><span class="hidden md:block text-sm text-muted-foreground truncate">Michael Shan</span><span class="hidden md:block text-sm text-muted-foreground text-right tabular-nums">22m</span></a></li>
270<li class="border-t border-foreground/8"><a class="group grid gap-x-6 gap-y-1 px-5 py-4 transition-colors hover:bg-foreground/4 271 md:grid-cols-[minmax(0,14rem)_minmax(0,1fr)_minmax(0,11rem)_2.5rem] md:items-center" href="/blog/ai-game-generator-turn-ideas-into-playable-worlds"><span class="text-sm text-muted-foreground order-2 md:order-none"><span class="md:hidden">Feb 4, 2026 · Guide · Michael Shan · 17m</span><span class="hidden md:inline">Feb 4, 2026 · Guide</span></span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85 order-1 md:order-none">AI Game Generator: Turn Ideas Into Playable Worlds</span><span class="hidden md:block text-sm text-muted-foreground truncate">Michael Shan</span><span class="hidden md:block text-sm text-muted-foreground text-right tabular-nums">17m</span></a></li><li class="border-t border-foreground/8"><a class="group grid gap-x-6 gap-y-1 px-5 py-4 transition-colors hover:bg-foreground/4 272 md:grid-cols-[minmax(0,14rem)_minmax(0,1fr)_minmax(0,11rem)_2.5rem] md:items-center" href="/blog/ai-game-builder-create-complete-games-with-artificial-intelligence"><span class="text-sm text-muted-foreground order-2 md:order-none"><span class="md:hidden">Feb 4, 2026 · Guide · Michael Shan · 14m</span><span class="hidden md:inline">Feb 4, 2026 · Guide</span></span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85 order-1 md:order-none">AI Game Builder: Create Complete Games With Artificial Intelligence</span><span class="hidden md:block text-sm text-muted-foreground truncate">Michael Shan</span><span class="hidden md:block text-sm text-muted-foreground text-right tabular-nums">14m</span></a></li>
272<li class="border-t border-foreground/8"><a class="group grid gap-x-6 gap-y-1 px-5 py-4 transition-colors hover:bg-foreground/4 273 md:grid-cols-[minmax(0,14rem)_minmax(0,1fr)_minmax(0,11rem)_2.5rem] md:items-center" href="/blog/genie-3-vs-unreal-engine-how-ai-world-models-compare-to-aaa-game-engines"><span class="text-sm text-muted-foreground order-2 md:order-none"><span class="md:hidden">Feb 1, 2026 · Guide · Michael Shan · 3m</span><span class="hidden md:inline">Feb 1, 2026 · Guide</span></span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85 order-1 md:order-none">Genie 3 vs Unreal Engine: How AI World Models Compare to AAA Game Engines</span><span class="hidden md:block text-sm text-muted-foreground truncate">Michael Shan</span><span class="hidden md:block text-sm text-muted-foreground text-right tabular-nums">3m</span></a></li></ul><button type="button" class="w-full border-t border-foreground/8 px-5 py-4 text-sm text-muted-foreground 274 transition-colors hover:bg-foreground
274/4 hover:text-foreground cursor-pointer 275 flex items-center justify-center gap-2">View more<svg data-prefix="far" data-icon="arrow-down" class="svg-inline--fa fa-arrow-down text-xs" role="img" viewBox="0 0 384 512" aria-hidden="true"><path fill="currentColor" d="M175.5 505c9.4 9.4 24.6 9.4 33.9 0l168-168c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-127 127 0-406.1c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 406.1-127-127c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l168 168z"></path></svg></button></div></div><section class="mt-16 md:mt-24 text-center"><blockquote class="text-h3-sm md:text-h3 text-foreground max-w-[760px] mx-auto text-balance">âThe hardest part of making a game has never been the code â itâs knowing what it should look like.â</blockquote><p class="mt-5 text-sm text-muted-foreground">From "Introducing Image to Game" <a class="inline-flex items-center gap-1.5 text-accent hover:opacity-80 transition-opacity" href="/blog/introducing-image-to-game">Read more<svg data-prefix="far" data-icon="arrow-right" class="svg-inline--fa fa-arrow-right text-xs" role="img" viewBox="0 0 512 512" aria-hidden="true"><path fill="currentColor" d="M505 273c9.4-9.4 9.4-24.6 0-33.9L337 71c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l127 127-406.1 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l406.1 0-127 127c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0L505 273z"></path></svg></a></p></section><section class="mt-15 md:mt-24"><h2 class="text-base text-foreground mb-4">Changelog</h2><div class="grid gap-2 sm:grid-cols-2 lg:grid-cols-4">
275<a class="group flex flex-col gap-1 rounded-md bg-foreground/6 p-4 min-h-[104px] transition-colors hover:bg-foreground/10" href="/changelog/simpler-credits-cheaper-prompts"><span class="text-sm text-muted-foreground">Aug 14, 2026</span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85">Simpler credits, cheaper prompts</span></a><a class="group flex flex-col gap-1 rounded-md bg-foreground/6 p-4 min-h-[104px] transition-colors hover:bg-foreground/10" href="/changelog/introducing-atomos-our-most-capable-model"><span class="text-sm text-muted-foreground">Aug 14, 2026</span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85">Introducing Atomos â our most capable model</span></a><a class="group flex flex-col gap-1 rounded-md bg-foreground/6 p-4 min-h-[104px] transition-colors hover:bg-foreground/10" href="/changelog/introducing-muranyi-3"><span class="text-sm text-muted-foreground">Aug 14, 2026</span><span class="text-sm text-foreground transition-colors group-hover:text-foreground/85">Introducing Muranyi-3</span></a></div><div class="mt-4"><a class="inline-flex items-center gap-1.5 text-sm text-accent hover:opacity-80 transition-opacity" href="/changelog">See what's new in Tesana<svg data-prefix="far" data-icon="arrow-right" class="svg-inline--fa fa-arrow-right text-xs" role="img" viewBox="0 0 512 512" aria-hidden="true"><path fill="currentColor" d="M505 273c9.4-9.4 9.4-24.6 0-33.9L337 71c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l127 127-406.1 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l406.1 0-127 127c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0L505 273z"></path></svg></a></div></section><section class="mt-15 md:mt-24"><h2 class="text-base text-foreground mb-4">Videos</h2><div class="grid gap-2 sm:grid-cols-2 lg:grid-cols-4"><a href="https://www.youtube.com/watch?v=g_1VYJqObCY" target="_blank" rel="noopener noreferrer" class="group flex flex-col overflow-hidden rounded-md bg-foreground
275/6 transition-colors hover:bg-foreground/10"><div class="aspect-video overflow-hidden bg-surface"><picture style="display: contents;"><source srcset="/blog-videos/g_1VYJqObCY.avif" type="image/avif"><source srcset="/blog-videos/g_1VYJqObCY.webp" type="image/webp"><img src="/blog-videos/g_1VYJqObCY.jpg" alt="" aria-hidden="true" loading="lazy" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-[1.02]"></picture></div><div class="flex flex-col gap-1 p-4"><h3 class="text-sm text-foreground">How to build a game with AI - Tesana</h3><p class="text-sm text-muted-foreground">3 months ago · 0:52</p><span class="mt-2 inline-flex items-center gap-1.5 text-sm text-accent">Watch on YouTube<svg data-prefix="far" data-icon="arrow-up-right" class="svg-inline--fa fa-arrow-up-right text-xs" role="img" viewBox="0 0 384 512" aria-hidden="true"><path fill="currentColor" d="M360 64c13.3 0 24 10.7 24 24l0 240c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-182.1-295 295c-9.4 9.4-24.6 9.4-33.9 0S-2.3 416.4 7 407l295-295-182.1 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l240 0z"></path></svg></span></div></a><a href="https://www.youtube.com/watch?v=HINSXJ5FtEQ" target="_blank" rel="noopener noreferrer" class="group flex flex-col overflow-hidden rounded-md bg-foreground
275/6 transition-colors hover:bg-foreground/10"><div class="aspect-video overflow-hidden bg-surface"><picture style="display: contents;"><source srcset="/blog-videos/HINSXJ5FtEQ.avif" type="image/avif"><source srcset="/blog-videos/HINSXJ5FtEQ.webp" type="image/webp"><img src="/blog-videos/HINSXJ5FtEQ.jpg" alt="" aria-hidden="true" loading="lazy" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-[1.02]"></picture></div><div class="flex flex-col gap-1 p-4"><h3 class="text-sm text-foreground">Welcome to Tesana</h3><p class="text-sm text-muted-foreground">4 months ago · 0:38</p><span class="mt-2 inline-flex items-center gap-1.5 text-sm text-accent">Watch on YouTube<svg data-prefix="far" data-icon="arrow-up-right" class="svg-inline--fa fa-arrow-up-right text-xs" role="img" viewBox="0 0 384 512" aria-hidden="true"><path fill="currentColor" d="M360 64c13.3 0 24 10.7 24 24l0 240c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-182.1-295 295c-9.4 9.4-24.6 9.4-33.9 0S-2.3 416.4 7 407l295-295-182.1 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l240 0z"></path></svg></span></div></a><a href="https://www.youtube.com/watch?v=l4WcqhU270k" target="_blank" rel="noopener noreferrer" class="group flex flex-col overflow-hidden rounded-md bg-foreground
275/6 transition-colors hover:bg-foreground/10"><div class="aspect-video overflow-hidden bg-surface"><picture style="display: contents;"><source srcset="/blog-videos/l4WcqhU270k.avif" type="image/avif"><source srcset="/blog-videos/l4WcqhU270k.webp" type="image/webp"><img src="/blog-videos/l4WcqhU270k.jpg" alt="" aria-hidden="true" loading="lazy" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-[1.02]"></picture></div><div class="flex flex-col gap-1 p-4"><h3 class="text-sm text-foreground">Spark Rider - Made with Atomos-1</h3><p class="text-sm text-muted-foreground">3 months ago · 0:50</p><span class="mt-2 inline-flex items-center gap-1.5 text-sm text-accent">Watch on YouTube<svg data-prefix="far" data-icon="arrow-up-right" class="svg-inline--fa fa-arrow-up-right text-xs" role="img" viewBox="0 0 384 512" aria-hidden="true"><path fill="currentColor" d="M360 64c13.3 0 24 10.7 24 24l0 240c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-182.1-295 295c-9.4 9.4-24.6 9.4-33.9 0S-2.3 416.4 7 407l295-295-182.1 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l240 0z"></path></svg></span></div></a><a href="https://www.youtube.com/watch?v=WzmOqCbqrVE" target="_blank" rel="noopener noreferrer" class="group flex flex-col overflow-hidden rounded-md bg-foreground
275/6 transition-colors hover:bg-foreground/10"><div class="aspect-video overflow-hidden bg-surface"><picture style="display: contents;"><source srcset="/blog-videos/WzmOqCbqrVE.avif" type="image/avif"><source srcset="/blog-videos/WzmOqCbqrVE.webp" type="image/webp"><img src="/blog-videos/WzmOqCbqrVE.jpg" alt="" aria-hidden="true" loading="lazy" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-[1.02]"></picture></div><div class="flex flex-col gap-1 p-4"><h3 class="text-sm text-foreground">Nova Atlas - Tesana Loop Mode</h3><p class="text-sm text-muted-foreground">2 months ago · 1:03</p><span class="mt-2 inline-flex items-center gap-1.5 text-sm text-accent">Watch on YouTube<svg data-prefix="far" data-icon="arrow-up-right" class="svg-inline--fa fa-arrow-up-right text-xs" role="img" viewBox="0 0 384 512" aria-hidden="true"><path fill="currentColor" d="M360 64c13.3 0 24 10.7 24 24l0 240c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-182.1-295 295c-9.4 9.4-24.6 9.4-33.9 0S-2.3 416.4 7 407l295-295-182.1 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l240 0z"></path></svg></span></div></a></div><div class="mt-4"><a href="https://www.youtube.com/@TesanaAI" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-1.5 text-sm text-accent hover:opacity-80 transition-opacity">Visit our YouTube channel<svg data-prefix="far" data-icon="arrow-up-right" class="svg-inline--fa fa-arrow-up-right text-xs" role="img" viewBox="0 0 384 512" aria-hidden="true"><path fill="currentColor" d="M360 64c13.3 0 24 10.7 24 24l0 240c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-182.1-295 295c-9.4 9.4-24.6 9.4-33.9 0S-2.3 416.4 7 407l295-295-182.1 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l240 0z"></path></svg></a></div></section></main><footer class="bg-background"><div><div class="container py-20 md:py-28 flex flex-col items-center text-center"><h2 class="text-h2-sm md:text-h2 text-foreground max-w-[900px]">Try Tesana now.</h2><button class="mt-8 h-11 px-4 rounded-md text-base bg-foreground text-background hover:opacity-80 transition-all cursor-pointer">Get started</button></div></div><div class="bg-surface"><div class="container py-16"><div class="grid grid-cols-2 gap-x-8 gap-y-10 md:grid-cols-3 lg:grid-cols-5"><nav aria-label="Product" class="flex flex-col gap-3"><h3 class="text-sm text-muted-foreground">Product</h3><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/play">Play</a><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/create">Create</a><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/explore">Explore</a><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/pricing">Pricing</a><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/enterprise">Enterprise</a><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/download">Download</a></nav><nav aria-label="Resources" class="flex flex-col gap-3"><h3 class="text-sm text-muted-foreground">Resources</h3><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/faq">FAQ</a><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/help">Help center</a><a href="https://docs.tesana.ai" target="_blank" rel="noopener noreferrer" class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit">Docs</a><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/getting-started">Getting started</a></nav><nav aria-label="Company" class="flex flex-col gap-3"><h3 class="text-sm text-muted-foreground">Company</h3><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/about">About</a><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/blog">Blog</a><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/changelog">Changelog</a></nav><nav aria-label="Socials" class="flex flex-col gap-3"><h3 class="text-sm text-muted-foreground">Socials</h3><a href="https://discord.gg/6uqbFsdhSM" target="_blank" rel="noopener noreferrer" class="text-sm text-foreground
275/85 hover:text-foreground transition-colors w-fit">Discord</a><a href="https://x.com/TesanaAI" target="_blank" rel="noopener noreferrer" class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit">X</a><a href="https://www.linkedin.com/company/tesana" target="_blank" rel="noopener noreferrer" class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit">LinkedIn</a><a href="https://www.youtube.com/@TesanaAI" target="_blank" rel="noopener noreferrer" class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit">YouTube</a></nav><nav aria-label="Legal" class="flex flex-col gap-3"><h3 class="text-sm text-muted-foreground">Legal</h3><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/terms">Terms of Service</a><a class="text-sm text-foreground/85 hover:text-foreground transition-colors w-fit" href="/privacy">Privacy Policy</a></nav></div><div class="mt-16 flex flex-col items-start gap-6 sm:flex-row sm:items-center sm:justify-between"><span class="text-sm text-muted-foreground">2026 Dreamsands, Inc.</span><div class="flex items-center gap-2"><div role="radiogroup" aria-label="Theme" class="flex items-center gap-0.5 rounded-md bg-foreground
275/6 p-0.5"><button type="button" role="radio" aria-checked="true" title="System theme" aria-label="System theme" class="w-7 h-7 rounded-md flex items-center justify-center text-xs transition-colors cursor-pointer bg-foreground/10 text-foreground"><svg data-prefix="far" data-icon="desktop" class="svg-inline--fa fa-desktop" role="img" viewBox="0 0 512 512" aria-hidden="true"><path fill="currentColor" d="M448 80c8.8 0 16 7.2 16 16l0 176-416 0 0-176c0-8.8 7.2-16 16-16l384 0zm16 240l0 32c0 8.8-7.2 16-16 16L64 368c-8.8 0-16-7.2-16-16l0-32 416 0zM64 32C28.7 32 0 60.7 0 96L0 352c0 35.3 28.7 64 64 64l115.7 0-8 48-51.7 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l272 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-51.7 0-8-48 115.7 0c35.3 0 64-28.7 64-64l0-256c0-35.3-28.7-64-64-64L64 32zM220.3 464l8-48 55.3 0 8 48-71.3 0z"></path></svg></button><button type="button" role="radio" aria-checked="false" title="Light theme" aria-label="Light theme" class="w-7 h-7 rounded-md flex items-center justify-center text-xs transition-colors cursor-pointer text-muted-foreground hover:text-foreground"><svg data-prefix="far" data-icon="sun-bright" class="svg-inline--fa fa-sun-bright" role="img" viewBox="0 0 576 512" aria-hidden="true"><path fill="currentColor" d="M288 432c13.3 0 24 10.7 24 24l0 64c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-64c0-13.3 10.7-24 24-24zM129.6 380.4c9.4-9.4 24.6-9.4 34 0s9.4 24.6 0 34l-45.3 45.3c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l45.2-45.3zm282.8 0c9.4-9.4 24.6-9.4 34 0l45.3 45.3c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-45.3-45.3c-9.4-9.4-9.4-24.6 0-34zM288 384a128 128 0 1 1 0-256 128 128 0 1 1 0 256zm0-208a80 80 0 1 0 0 160 80 80 0 1 0 0-160zM88 232c13.3 0 24 10.7 24 24s-10.7 24-24 24l-64 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l64 0zm464 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-64 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l64 0zM84.3 52.3c9.4-9.4 24.6-9.4 33.9 0l45.3 45.2c9.4 9.4 9.4 24.6 0 34s-24.6 9.4-34 0L84.3 86.3c-9.4-9.4-9.4-24.6 0-33.9zm373.4 0c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-45.3 45.3c-9.4 9.4-24.6 9.4-34 0s-9.4-24.6 0-34l45.3-45.2zM288-32c13.3 0 24 10.7 24 24l0 64c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-64c0-13.3 10.7-24 24-24z"></path></svg></button><button type="button" role="radio" aria-checked="false" title="Dark theme" aria-label="Dark theme" class="w-7 h-7 rounded-md flex items-center justify-center text-xs transition-colors cursor-pointer text-muted-foreground hover:text-foreground"><svg data-prefix="far" data-icon="moon" class="svg-inline--fa fa-moon" role="img" viewBox="0 0 512 512" aria-hidden="true"><path fill="currentColor" d="M239.3 48.7c-107.1 8.5-191.3 98.1-191.3 207.3 0 114.9 93.1 208 208 208 33.3 0 64.7-7.8 92.6-21.7-103.4-23.4-180.6-115.8-180.6-226.3 0-65.8 27.4-125.1 71.3-167.3zM0 256c0-141.4 114.6-256 256-256 19.4 0 38.4 2.2 56.7 6.3 9.9 2.2 17.3 10.5 18.5 20.5s-4 19.8-13.1 24.4c-60.6 30.2-102.1 92.7-102.1 164.8 0 101.6 82.4 184 184 184 5 0 9.9-.2 14.8-.6 10.1-.8 19.6 4.8 23.8 14.1s2 20.1-5.3 27.1C387.3 484.8 324.8 512 256 512 114.6 512 0 397.4 0 256z"></path></svg></button></div><div class="relative"><button type="button" aria-haspopup="listbox" aria-expanded="false" aria-label="Language" class="h-8 pl-3 pr-2.5 rounded-md bg-foreground
275/6 hover:bg-foreground/10 flex items-center gap-2 text-sm text-foreground transition-colors cursor-pointer"><svg data-prefix="far" data-icon="globe" class="svg-inline--fa fa-globe text-xs" role="img" viewBox="0 0 512 512" aria-hidden="true"><path fill="currentColor" d="M303.2 413c-21.5 43.7-41.4 51-47.2 51s-25.7-7.3-47.2-51c-17-34.5-29.2-81.6-32.1-133l158.6 0c-3 51.5-15.2 98.6-32.1 133zm32.1-181l-158.6 0c3-51.5 15.2-98.6 32.1-133 21.5-43.7 41.4-51 47.2-51s25.7 7.3 47.2 51c17 34.5 29.2 81.6 32.1 133zm48.1 48l79.2 0c-8.6 74.6-56.7 137.3-122.8 166.4 24-42.8 40.3-102.4 43.6-166.4zm79.2-48l-79.2 0c-3.3-64-19.6-123.6-43.6-166.4 66.1 29.2 114.2 91.8 122.8 166.4zm-334 0l-79.2 0c8.6-74.6 56.7-137.3 122.8-166.4-24 42.8-40.3 102.4-43.6 166.4zM49.4 280l79.2 0c3.3 64 19.6 123.6 43.6 166.4-66.1-29.2-114.2-91.8-122.8-166.4zM256 512a256 256 0 1 0 0-512 256 256 0 1 0 0 512z"></path></svg><span>English</span><svg data-prefix="far" data-icon="chevron-down" class="svg-inline--fa fa-chevron-down text-[10px] text-muted-foreground transition-transform duration-200" role="img" viewBox="0 0 448 512" aria-hidden="true"><path fill="currentColor" d="M207.5 409c9.4 9.4 24.6 9.4 33.9 0l200-200c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-183 183-183-183c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l200 200z"></path></svg></button></div></div></div></div></div></footer></div><!-- PRERENDER_CONTENT_END --> 276 </div> 277
277<script> 278 (function () { 279 try { 280 if (document.documentElement.classList.contains('light')) { 281 var v = document.getElementById('initial-loader-video'); 282 var loader = document.getElementById('initial-loader'); 283 var overlay = document.getElementById('initial-loader-overlay'); 284 if (v) v.src = '/loading/tesana-loading-128-white.mp4'; 285 if (loader) loader.style.background = '#ffffff'; 286 if (overlay) overlay.style.display = 'none'; 287 } 288 } catch (e) {} 289 })(); 290 </script>
290 291 292 <!-- Deferred: Mixpanel CDN + init, Facebook Pixel (loaded after first paint) --> 293
293<script> 294 function __loadDeferredAnalytics() { 295 if (window.__analyticsLoaded) return; 296 if (window.__TESANA_IS_TAURI) return; // see comment in <head> 297 window.__analyticsLoaded = true; 298 299 // Facebook Pixel
vendor: 471 bytes, lines 299-308
299 300 !function(f,b,e,v,n,t,s) 301 {if(f.fbq)return;n=f.fbq=function(){n.callMethod? 302 n.callMethod.apply(n,arguments):n.queue.push(arguments)}; 303 if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0'; 304 n.queue=[];t=b.createElement(e);t.async=!0; 305 t.src=v;s=b.getElementsByTagName(e)[0]; 306 s.parentNode.insertBefore(t,s)}(window, document,'script', 307 'https://connect.facebook.net/en_US/fbevents.js'); 308 fbq('init', '
3081570988284201631
vendor: 44 bytes, lines 308-310
308'); 309 fbq('track', 'PageView'); 310
310} 311 if ('requestIdleCallback' in window) { 312 requestIdleCallback(__loadDeferredAnalytics, { timeout: 4000 }); 313 } else { 314 setTimeout(__loadDeferredAnalytics, 3000); 315 } 316 </script>
316 317 <noscript> 318 <img height="1" width="1" style="display:none" 319 src="https://www.facebook.com/tr?id=1570988284201631&ev=PageView&noscript=1" 320 ></img> 321 </noscript> 322 </body> 323</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.