tibo.dog Wiki Game v75 Play tibo.dog

Controls

Keyboard

Action Keys
Move W A S D or arrow keys
Dash Space
Pause P or Escape
Pick a level-up card Number keys
Reroll / Skip / Banish R / X / B (while you have charges)

Touch

Action Gesture
Move Drag anywhere
Dash Flick
Pause Tap the pause button
Pick a card Tap it, or Reroll, Skip, Banish

A flick starting on a map tip's Settings button still reaches the movement controls. Settings opens only on a still press; moving more than 6 CSS pixels suppresses its click.[1][2]

With Flashing effects off, poteto's arrival hides its holographic foil instead of painting it.[3]

Source: About tibo.dog and llms.txt.

Other keys

Verified (key map in boot-CPW8VVmR.js and the game's input code):

Key Action
P Pause / resume during a run (Escape also works)
M Mute / unmute
T Auto-advance story lines on or off
Space Skip story lines
R Play again (end screen)
S Share (end screen)
Escape Back
Enter / Space Activate the focused button
Arrow keys Move focus in lists

Cards are numbered 1, 2, 3 (4) in order. The on-screen hint relabels W A S D for AZERTY, QWERTZ, Dvorak and Colemak layouts.

Dash details

Verified: a dash moves 48 units over 9 ticks (0.15 s), each charge recharges in 5 s, Tibo starts with 1 charge and the input is buffered for 6 ticks. Tibo ignores normal damage while dashing (and during dashGrace from Ghost Pepper). A touch flick is a stroke of at least 30 px over the last 120 ms, moving at least 400 px/s when the finger lifts, or 900 px/s while it is still down (dash.flickPx, flickWindowMs, flickPxPerSec, heldFlickPxPerSec).

Gamepad

No gamepad controls were found; the code only records that a gamepad was connected (for analytics).

Settings

Verified from the settings panel (settings-panel-CCcMA-sy.js) and defaults in boot-CPW8VVmR.js. Tabs: Sound, Language, Comfort, Graphics, Privacy.

Setting Options Default
Music volume slider full
Sound volume slider full
Language 27 languages browser language, unless the address has ?lang= (see Languages)
Color-blind mode Off, Protanopia, Deuteranopia, Tritanopia (with a Danger / XP / Health colour preview) Off
Weapon effects slider full
Screen shake Off, Low, Full Full
Flashing effects On / Off On
Damage numbers On / Off On
Hitbox (“Shows where shots hit Tibo.”) On / Off On
Recommended picks On / Off On
Map tips (“Explains each new place on the map once.”) On / Off (Comfort tab) On
Quality Auto, Low, Medium, High Auto
Battery saver Off, On, Auto (Graphics tab) Off
Analytics (“Anonymous gameplay stats help poteto improve the game. No name, account or IP address is recorded.”) On / Off On (off by default in the EU and EEA, per the game's privacy page)

Battery saver

Loading behavior: On now limits drawing immediately, before the extra Battery saver module has downloaded. That module is requested only once a run is active or its intro has started, rather than from the menu. The same pacing object is kept when loading finishes; Auto's power and load checks still need the module. Controlled old/new probes covered Off, Auto and On in the menu, run and both intro states; after loading, On still admitted 30 of 60 callbacks at 60 Hz, versus 60 for Off and idle Auto.[4]

Verified: On targets 30 drawn frames a second; it does not change the simulation's tick rate. Auto saves power while an unplugged battery is at 20% or less, under serious/critical CPU pressure when the browser exposes it, or after 30 hot one-second observation windows during active play. A window is hot when work exceeds 60% of its time or average frames take more than 1.25 times their target interval; a cool window reduces the accumulated count by one. Heat-triggered saving lasts until a new run state. Graphics quality accounts for the intentional slower drawing rather than treating it as an accidental frame-rate drop.[5][6][7]

Measured with this build's actual Battery saver module and controlled frame/power inputs: On admitted 30 of 60 callbacks at 60 Hz, while Off and idle Auto admitted 60. Sustained 11 ms work per 16.67 ms frame activated Auto after about 30.48 s; sustained 25 ms frames against a 16.67 ms target activated it after 30 s. At 9 ms work it stayed off. An unplugged battery at 20.1% did not trigger it; 20.0% did, and charging cleared that trigger. These probes check the controller, not real-device temperature or battery-life improvements.

Map tips explain a nearby, unused point of interest once per kind. Read tips are remembered in this browser across runs; turning tips off does not clear that history. The first tip includes a link to turn them off in Settings. Tips wait while overlays or story scenes block them.[8][9]

Other open tabs pick up a changed Map tips setting the next time they read it. A storage-clear event also clears the cached setting; with no saved value, tips default to On. This synchronizes the setting, not the history of read tips.[10]

The hitbox setting shows a bright green ring with a dark edge on both sides at Tibo's enemy-shot collision centre; it does not change collision size. Color-blind modes give the ring its own color: pink-red for protanopia, teal for deuteranopia and magenta for tritanopia. The colored stroke is 3 CSS pixels wide, or 2 when the viewport's shorter side is 320 CSS pixels or less; the dark stroke underneath is 7 or 5 pixels wide, respectively.[11][12][13]

Updating settings saved before version 3 turns the hitbox on once, even if it was off; you can turn it off again.[14]

If the game closed unexpectedly, it restarts on Low quality: “The game closed unexpectedly last time, so it started on Low. Pick a quality to switch back.” Repeated crashes start lean 3D at half resolution, without adaptive quality or automatic climbing. This is not a 2D renderer.[15]

Graphics recovery

Verified: play stops while the renderer is not ready. The run also waits at the endgame boundary until its lazy content, simulation and view are ready. Failed scene downloads retry after 1 s, then 2 s, 4 s and at most 8 s between attempts. A failed early sprite-page download can be retried too. There is no flat 2D fallback or renderer-selection URL parameter.[16][17]

After WebGL context loss, the game waits up to 5 s for restoration, then tries a fresh context. If that recovery also fails, graphics stop. Scene construction has a separate recovery path: its first failure retries 3D on Low at half resolution, with adaptive quality off; another construction failure stops graphics. The stopped screen says “The 3D graphics stopped” and offers Reload and Copy link; input and audio stop too. Missing WebGL 2 at startup still shows the unsupported-device screen.[18][19][20]

An active intro or landing cutscene ends as skipped if its renderer stops reporting ready.[21]

Updating the game

Verified: the game checks /version.json while the title screen, player pause menu or end-of-run stats screen is open, and every 180 s during active play. It does not force a reload during active play.[22][23][24]

When it finds a different build, it downloads that build's assets in the background for the next reload. Downloads run one at a time at low priority, wait for idle time and include the selected language's files. Save-Data and slow 2G connections skip warming; cross-origin assets are excluded. Download failures do not end the run.[25][26][27]

After an update reload, the first gesture that unlocks audio can fade music in rather than starting it abruptly. This applies when music is not held (paused).[28][29]

On the idle title screen (the Reset screen), a detected update is rechecked and can load automatically. The changelog and a charging Reset button are not idle. A session-storage guard prevents repeatedly auto-reloading into the same offered build; if the guard cannot be saved, or the same update remains after reloading, the title screen offers Update game instead.[30][31]

Starting a non-Story run from the end screen can also load a detected update first, then start the selected difficulty. The saved selection is consumed once and expires after 60 s. If the update or selection cannot be saved, the game starts the run without reloading.[32][33][34]

After a successful update reload, Game updated briefly replaces the title-screen changelog label. A run relaunched after an update gets a temporary HUD changelog button; opening it pauses the run. The label swaps after 3 s and the HUD notice fades after about 30 s. The changelog opens the newest day and the day containing your current build; other dates can be expanded.[35][36]

The pause menu still offers Update game with confirmation: “Your current run will end.” It also shows the current game commit. Updating from a shared-run URL removes its run and stats parameters and returns /r/ to /.[37]

Browser requirements

Verified: WebGL 2 is required. If it is unavailable, the game shows “This device can't run tibo.dog” with a Copy link button, rather than starting the low-detail fallback. If copying is blocked, the screen displays the link for manual copying.[38][39]

Languages

Verified: the game has 27 languages. English is built in; every other language loads an interface file (i18n-<code>-ui) and a game-content file (i18n-<code>-content). Settings → Language lists them by their own names, in this order:

Language In English Code Direction
English English en Left to right
简体中文 Simplified Chinese zh-CN Left to right
繁體中文 Traditional Chinese (Taiwan) zh-TW Left to right
日本語 Japanese ja Left to right
한국어 Korean ko Left to right
Español Spanish es Left to right
हिन्दी Hindi hi Left to right
Deutsch German de Left to right
Français French fr Left to right
Português (Brasil) Brazilian Portuguese pt Left to right
Türkçe Turkish tr Left to right
Bahasa Indonesia Indonesian id Left to right
Русский Russian ru Left to right
Bahasa Melayu Malay ms Left to right
Filipino Filipino fil Left to right
मराठी Marathi mr Left to right
Tiếng Việt Vietnamese vi Left to right
తెలుగు Telugu te Left to right
தமிழ் Tamil ta Left to right
বাংলা Bengali bn Left to right
ไทย Thai th Left to right
Hausa Hausa ha Left to right
Naijá Nigerian Pidgin pcm Left to right
العربية Arabic ar Right to left
فارسی Persian fa Right to left
עברית Hebrew he Right to left
اردو Urdu ur Right to left

How the game picks a language

Verified: when the page loads, the game uses the first of these that gives a supported language:[40]

  1. A lang parameter in the address, for example https://tibo.dog/?lang=de.[41]
  2. The language picked earlier in Settings, saved in this browser.
  3. The browser's preferred languages, in the browser's order.
  4. English.

On a shared-run link (an address with run or stats), the saved language and the browser come first, and the lang parameter is used only when neither gives a supported language.

Codes are matched by language only, so a region is ignored: pt-PT gives Brazilian Portuguese (pt) and es-MX gives Spanish. Chinese in Traditional script (such as zh-TW, zh-HK or Cantonese yue) gives zh-TW; other Chinese gives zh-CN. Unsupported codes are skipped.[42]

Once a language has loaded, the game writes it into the address as ?lang=<code> (and removes the parameter for English), so a copied link opens in the same language. If the translation fails to load, the game starts in English.[43][44]

Switching language

Verified: picking a language in Settings → Language (for example from the pause menu) relabels the game at once, without reloading or ending the run, and saves the choice in this browser's settings (tibo.settings.v1). Clearing site data forgets it.[45][46]

Display details

  • Verified: Arabic, Persian, Hebrew and Urdu switch the page to right-to-left layout.[47]
  • Verified: numbers are formatted with Western digits (0–9) in every language (Unicode locale extension -u-nu-latn).[48]
  • Verified: a text missing from a translation falls back to English. The boss amusing keeps its English name in every language; its title is translated.[49]

Checked in Chromium on the live game (build main-BnCKpQy_.js, whose language code matches the documented build) on 2026-11-05: ?lang=de showed German; ?lang=pt-PT became ?lang=pt; zh-HK and yue became zh-TW; an unknown code fell back to English and dropped the parameter; ?lang=ar set right-to-left layout; a browser preferring Polish, then Japanese, started in Japanese; a language picked in Settings mid-run relabelled the pause menu at once and was used again on the next visit without a parameter; on a shared-run link the saved language beat ?lang=.

Names in other languages

Every weapon, passive, item, dog, enemy, boss, biome and event page has a collapsed Names in other languages table with its in-game name in all 26 other languages, taken from the game's content files. The wiki search also matches these names, and the names of points of interest and Grok Bots, so you can search in your own language.

Sources

Game version 75: main-CSuyb4iv.js / boot-CPW8VVmR.js / sim-BkfBhQfw.js from https://tibo.dog/, researched 2026-11-05. See Versions & updates.

Code references

  1. poi-tips-vFYb3sXD.js Math.hypot(e.clientX-y.x,e.clientY-y.y)>6
  2. poi-tips-vFYb3sXD.js e.stopPropagation(),y.moved||a.openSettings()
  3. run-extras-l2haGSVw.js casefoil:t?this.holo.value?.paint(this.shot,e.frames):this.holo.value?.hide();
  4. boot-CPW8VVmR.js r===void 0?(this.pace.hold(n===`on`),n===`on`&&(e.loop.pace=this.pace)):r.frame(e,t)
  5. battery-saver-D5hqPNwb.js this.hotWindows>=this.cfg.hotWindows&&(this.heat=n?`slow`:`load`)
  6. battery-saver-D5hqPNwb.js t(!r.charging&&r.level<=e)
  7. boot-CPW8VVmR.js batterySaver:{windowSec:1,hotDuty:.6,slowRatio:1.25,hotWindows:30,lowBattery:.2}
  8. boot-CPW8VVmR.js var Io=`tibo.poi-tips-setting.v1`
  9. poi-tips-vFYb3sXD.js key:`tibo.poi-tips.v1`
  10. boot-CPW8VVmR.js e.key!==`tibo.poi-tips-setting.v1`&&e.key!==null||(n=void 0)
  11. scene-B2rwbRKj.js Bne={line:3,halo:7},Vne={line:2,halo:5}
  12. scene-B2rwbRKj.js Hne={off:{line:`#23f000`,halo:Kn},protanopia:{line:`#ee5566`,halo:Kn},deuteranopia:{line:`#11aa88`,halo:Kn},tritanopia:{line:`#ff22ff`,halo:Kn}}
  13. scene-B2rwbRKj.js u=a.cfg.player.hitRadius
  14. boot-CPW8VVmR.js field:`hitbox`,from:3
  15. boot-CPW8VVmR.js return{params:t.params,settings:n,lean:!0}
  16. main-CSuyb4iv.js if(!this.renderer.ready()||(this.endgameWait??=ve({chunks:this.chunks,host:this.hud.root})).holds(this.game.state))returnloading;
  17. hd2d-renderer-t_OyO5wm.js this.retrySec=Math.min(a.renderer.retryMaxSec,2*this.retrySec)
  18. hd2d-renderer-t_OyO5wm.js this.failed?{...n,softwareGl:!0}
  19. boot-CPW8VVmR.js tier:low,scale:xn.minScale,adaptive:!1,climb:!1
  20. no-webgl2-screen-DtaAe71v.js The 3D graphics stopped
  21. boot-CPW8VVmR.js if(this.host.renderer.cutscene()!==ready)return void this.end(!0);
  22. main-CSuyb4iv.js K(this)&&this.updates.playing(e)
  23. boot-CPW8VVmR.js function Nf(e){return e.flow.stage.kind===run&&!e.game.over&&!Mf(e)}
  24. boot-CPW8VVmR.js e-this.lastAt<this.source.recheckSec
  25. boot-CPW8VVmR.js this.live=t,this.source.found?.(t),this.onChange()
  26. warm-update-QoPnnjP0.js var f=new Set([slow-2g,2g])
  27. warm-update-QoPnnjP0.js e.origin===t.origin&&n.add(e.href)
  28. boot-CPW8VVmR.js let n=this.joining&&!this.musicHeld
  29. chip-worklet-C9vAAiRn.js state=fadingIn,n.left=n.inFrames
  30. main-CSuyb4iv.js this.splash.idle&&this.updates.settle(e,()=>this.splash.idle)
  31. boot-CPW8VVmR.js let n=e===this.held||!this.source.remember(e);if(t&&n)return this.held=e,void this.onChange();this.reloadNow()
  32. boot-CPW8VVmR.js n!==this.held&&this.source.remember(n)&&t.arm()?this.reloadNow():t.start()
  33. boot-CPW8VVmR.js maxAgeMs:e});return i.kind===run?i.level:void 0
  34. boot-CPW8VVmR.js update:{url:/version.json,waitSec:5,recheckSec:180,settleSec:15,relaunchSec:60,noteSec:3,hudNoteSec:30}
  35. boot-CPW8VVmR.js swapMs:1e3*T.update.noteSec,fadeMs:1e3*T.update.hudNoteSec-400
  36. main-CSuyb4iv.js this.pause===none&&this.canPause()&&(this.setPause(player),this.menus.openLog())
  37. boot-CPW8VVmR.js t.pathname===/r/&&(t.pathname=/);for(let e of ku)t.searchParams.delete(e)
  38. no-webgl2-screen-DtaAe71v.js This device can't run tibo.dog
  39. no-webgl2-screen-DtaAe71v.js Copy is blocked here. Long-press the link to copy it.
  40. boot-CPW8VVmR.js let t=e.saved??si(e.browser);return(e.sharedRun?t??e.link:e.link??t)??`en`
  41. boot-CPW8VVmR.js lang:zs(t.get(Rs))
  42. boot-CPW8VVmR.js case`zh`:case`yue`:return t.script===`Hant`?`zh-TW`:`zh-CN`;default:return ni.find(e=>e===t.language)
  43. boot-CPW8VVmR.js function Hs(e){Vs({set:Bs(e),drop:e===`en`?[Rs]:[]})}
  44. boot-CPW8VVmR.js catch(t){return e.report(t),await e.use(`en`),`en`}
  45. boot-CPW8VVmR.js async pick(e){await this.set(e),this.app.locale===e&&this.app.changeSettings({locale:e})}
  46. boot-CPW8VVmR.js var pu=`tibo.settings.v1`
  47. boot-CPW8VVmR.js document.documentElement.dir=t?.dir??ri(e)
  48. boot-CPW8VVmR.js -u-nu-latn
  49. boot-CPW8VVmR.js di.has(e)||j.messages[e]===void 0?ci.messages[e]===void 0?void 0:ci._(e):j._(e)