PageSourceSearch

https://tesana.com/blog

html tesana.com collected 2026-10-09 22:39:33 UTC 59,883 bytes, 323 lines download raw bytes

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 &amp; 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.