Web export or web port: what is the difference
Unity, Godot and Construct can all produce a browser build. Unity has its Web build target, Godot has a web export template, and Construct games are HTML5 from the start. For a game jam entry or a prototype that is usually enough.
Problems show up when the game reaches real players. These are the ones clients bring to us most often:
- A long first load. The player waits for the engine runtime and most of the game data before the menu appears. Poki recommends an initial download of up to 5 MB and 8 MB in total. CrazyGames requires 20 MB or less for a game to be shown on its mobile homepage.
- Stutter on phones. A build that holds a steady frame rate on a laptop can drop frames in Chrome on a mid-range Android phone.
- Memory crashes on iOS. A browser tab gets far less memory than a native app. When the game goes over the limit, Safari reloads the page.
- Silence after the start. Browsers keep audio locked until the first click or tap, so music that plays right away in the editor is not heard in the browser.
- Missing portal features. Ads, rewarded videos, cloud saves and gameplay events need the portal’s SDK, and mobile ad SDKs have no web version.
A web port deals with these problems at the source. We keep what makes the game itself and rebuild the parts that decide how it behaves in a browser.
Codeward: custom games, game porting and playable ads
We are a small studio from Kraków founded by Paweł Jarosz. We make custom games for studios, publishers and brands, port games to new platforms and build playable ads for mobile user acquisition. Defold is our core engine. Paweł is the Community & Content Manager at the Defold Foundation and the author of the official Defold sample for Poki, so we know the engine well, including its HTML5 side.
We have ported many client games to the web. In those projects the Defold version loaded faster and ran more smoothly on weaker phones than the original web build. The techniques we used are the same ones you can see in the open source projects linked below.
Why we port games to Defold for the browser
Defold is a free, source-available engine for 2D and 3D games, with gameplay code written in Lua. We pick it for web ports for practical reasons:
- A small engine. In the app manifest we switch off modules the game does not need, for example 2D physics or video. The Defold build size page shows how much the engine weighs on each platform.
- Deferred content. With Live Update we move levels, music and extra fonts out of the main bundle and download them after the game starts.
- Texture compression. Defold texture profiles support Basis Universal. At runtime such a texture is transcoded to a format the device’s GPU can read.
- One project for many platforms. We build the same Defold project for HTML5, Android, iOS, desktop and consoles. More on that in our article about Defold platforms.
- Portal SDKs. The Starbreaker sample shows the Poki SDK working in a complete Defold game, with ads and gameplay events.
Defold is not the right choice for every game. A 3D game with complex Unity shaders or dozens of Asset Store plugins is often better optimized in Unity than rewritten. We say so after the audit, and in that case we help improve the existing build.
Porting a Unity game to the browser
In a Unity to Defold port we rewrite the gameplay code from C# to Lua. Scenes and prefabs become Defold collections and game objects. Art, sprites and audio move over, usually re-exported at the size the game actually displays them.
Most of the extra work comes from packages. Asset Store plugins for tweening, UI, localization or ads need a Defold equivalent or a short piece of our own code. We rewrite custom shaders as Defold materials in GLSL. We list all of these dependencies during the audit, because they have the biggest effect on how long the port takes.
If you are still choosing an engine for your next game, our Defold vs Unity comparison goes deeper into build size, performance and porting.
Porting a Godot game to the browser
Godot and Defold are both lightweight, open engines, so a port between them is mostly a translation of structure. A tree of nodes in a Godot scene maps to Defold game objects with components. GDScript and Lua are both dynamic scripting languages. Gameplay logic often keeps its shape, even though we rewrite every line.
Clients usually come to us with a Godot game when its web export is too heavy for the portals they target, or when it has to run in the browser on older phones. A Godot web build ships the whole engine as a WebAssembly file, unless someone compiles custom export templates. In Defold we keep only the parts of the engine the game uses.
Signals, autoloads and resources move to Defold patterns: messages, shared Lua modules and data files.
Porting from Construct and other engines
Construct games already run in HTML5, so a port from Construct is rarely about getting into the browser. We do it when a project has outgrown its event sheets, when the same code has to produce native mobile or console versions, or when the game runs badly on cheap phones.
We rewrite event sheet logic as Lua scripts. Sprite animations are repacked into Defold atlases, and layouts become collections and GUI scenes. With the logic in plain Lua files, the project also fits into version control, where every change can be reviewed.
We also port games from older HTML5 frameworks, from other engines and from native iOS and Android code. The process below stays the same.
What we keep and what we rebuild
In every port we reuse as much of the original game as we can. The player should get the same game, only faster to load.
- Game design, level layouts and balancing data. We often convert level files with a script instead of rebuilding them by hand.
- Art and audio, re-exported in sizes and formats that suit the web.
- Texts and translations.
We rebuild the code, the UI layout for touch and mouse, shaders and effects, the loading screen and every SDK integration: ads, analytics, saves and the gameplay events the portal asks for.
Our HTML5 game porting process
- Audit. We run the current build, measure what the player downloads and list the engine features, plugins and SDKs the game depends on.
- A plan for the first minute. We decide what has to be in the initial download and what can wait. Usually that is the menu, the tutorial and the first level.
- First playable in the browser. We port one level first and test it on an older Android phone and on an iPhone in Safari. Problems found at this stage are easy to fix.
- Full port. The rest of the game, the UI and the save system.
- Optimization. Texture compression, atlases, audio, deferred loading and stripping the engine.
- Portal integration and QA. The Poki or CrazyGames SDK with ads and gameplay events, then tests in Chrome, Firefox, Safari and Edge on desktop and on phones.
- Release. We prepare the build for the portal or store and support the launch.
HTML5 best practices we use in every web port
Paweł collected most of them in Starbreaker, the official Defold sample for Poki. It is an open source 3D space shooter, and its code shows each of these techniques in a real game.
- Deferred loading with Live Update. Music and the fonts for Persian, Cyrillic and CJK scripts go into a separate archive. The game downloads it after the start and mounts it only when needed.
- Asynchronous loading. We load collection proxies in the background while the player is still in the menu, so the next level is ready before it is needed.
- Compressed textures with size limits. In the sample the UI atlas uses Basis Universal at up to 1024 px, and small effect textures are capped at 256 px.
- Texture packing. Sprites used together share an atlas. We keep art for later content out of the atlases the first level uses. Otherwise it would end up in the initial download anyway.
- Assets per device. Phones get lighter texture sets than desktop, and each player downloads fonts only for their own language.
- Smaller images and audio. WebP for the HTML loader and thumbnails, Ogg Vorbis for sound, mono effects and short music loops.
Each technique is explained step by step, with a checklist, in our HTML5 game optimization guide.
Testing on mobile browsers
We test every port on phones from the first playable build. Mobile browsers differ from desktop ones in ways that are easy to miss:
- Touch controls and on-screen buttons big enough for a finger, plus support for both orientations or a clear prompt to rotate the phone.
- Audio that starts after the first tap.
- A pause when the player switches tabs or locks the screen, and a return to the game without lost progress.
- Memory use over a whole session. A game that starts fine can still crash after half an hour of play.
When we advise against a port
Sometimes the audit shows that a game should stay in its engine. If the web build already fits portal limits and runs well on phones, improving it in place makes more sense than rewriting the whole game. We tell you this before any porting work starts.
Talk to us about web porting your game
Send us a link to your game or a current build. Tell us which engine it was made in and where you want to publish it. We will look at it and reply with what we would change and how we would approach the port. Use the contact form or write to biuro@paweljarosz.pl.
If your game was made for phones first, also read our guide to porting a mobile game to the web. It covers distribution, controls and web SDKs from the product side.