Dodge the swarm. Let your emoji weapons do the talking.
A Vampire-Survivors-style auto-battler: pick an emoji hero, move to dodge an ever-growing swarm, and your weapons fire themselves. Grab gems to level up, build out a loadout of weapons and passives, and survive 15 minutes to fell the Reaper. Originally built by Frank Force with the LittleJS engine; imported here as an MIT-licensed showcase of a longer-session auto-battler.
Made by Frank Force. Released under the MIT license — original source.
Changes for this platform: Copied games/emojiSurvivors.html to index.html and rewrote its four '../templates/...' script-src paths to './...' (self-contained folder, no path leaves it); also vendored templates/gameFx.js, templates/menus.js, templates/textureGenerator.js, and dist/littlejs.release.js verbatim alongside it (no shared repo-root dist/templates here), except littlejs.release.js's glInit() WebGL2 context now also passes preserveDrawingBuffer:true (upstream passed only {antialias}) so a JS-side canvas readback (the platform's headless checker, same fix this platform's hexgl-racer port needed) doesn't see a blank/cleared buffer outside the exact frame it was drawn in; purely a readback guarantee, nothing visual changes. Changed the title screen's PLAY button to call startRun(currentHero, currentStage) directly (was: pushMenu('heroSelect')) so a single click/tap from the title reaches real gameplay per docs/GAME_RUNTIME.md; added a new HEROES button in its place that opens the original hero-select -> stage-select flow for players who want to choose before starting (nothing removed, the deliberate picker is one tap later instead of mandatory). Renamed the pre-patched templates/engineLoader.ARCADE.js to engineLoader.js (upstream engineLoader.js with its engine path switched from '../dist/' to './', its localStorage-based build-switcher console helper wrapped in try/catch, and a new inline script — injected right after the engine tag, before any game code — that redefines readSaveData/writeSaveData to route through window.ArcadeSDK.storage when present, so LittleJS's best-time/medal persistence works inside the sandboxed iframe instead of hitting a throwing localStorage; falls back to the engine's own already-guarded localStorage behavior when run standalone). Added arcade-bridge.js (new file, nothing in the game patched to add it): calls SDK.ready() the first time menus.js's addPlayingListener fires (synchronously on registration, with the title-screen state); wraps window.engineInit to intercept its gameUpdatePost argument (the only way to hook a per-frame callback the game passes by value at the very end of its own script) and polls elapsedTime each frame, calling SDK.score() only when the whole-second value changes; fires SDK.gameOver({score, won, level}) and SDK.submitScore(score) exactly once per run the instant gameOver or runVictory flips true, with the per-run flag cleared on the next false->true isPlaying() transition; on SDK.onPause shows the existing 'pause' menu via showMenu('pause') (same path Escape already takes through installAutoPause/bindPauseKey) when a run is in progress, SDK.onResume is a deliberate no-op (player resumes via the pause menu's own RESUME button). Added a one-line, unobtrusive Twemoji CC-BY-4.0 credit ('Emoji art: Twemoji, CC-BY 4.0') as a new text item on the game's existing in-game HELP/about screen, since upstream deliberately kept that screen attribution-free (per its own comment) and relied solely on the HTML header comment + TWEMOJI-LICENSE.txt — the full license text still lives only in those two places, this is just a pointer. Copied LICENSE, twemoji.ttf, and TWEMOJI-LICENSE.txt verbatim from the upstream repo root/games folder. No gameplay code, network calls, storage calls, or UI copy were otherwise changed; touch.scheme is 'native' because the game enables LittleJS's own on-screen touch gamepad (touchGamepadEnable/Floating) and the platform shim must not draw a second one.
Comments 0
Log in to comment.