WebGL Game Development

Our video game development company runs independent projects, jointly creates games with the client and provides additional operational services. Expertise of our team allows us to cover all gaming platforms and develop an amazing product that matches the customer’s vision and players preferences.
Showing 1 of 1 servicesAll 242 services
WebGL Game Development
Complex
from 1 week to 2 months
FAQ
Our competencies
What are the stages of Game Development?
Latest works
  • image_games_mortal_motors_495_0.webp
    Game development for Mortal Motors
    663
  • image_games_a_turnbased_strategy_game_set_in_a_fantasy_setting_with_fire_and_sword_603_0.webp
    A turn-based strategy game set in a fantasy setting, With Fire and Sword
    859
  • image_games_second_team_604_0.webp
    Game development for the company Second term
    490
  • image_games_phoenix_ii_606_0.webp
    3D animation - teaser for the game Phoenix 2.
    533

WebGL Game Development

The client wants a game that launches via a link — no installation, no app store, straight in the browser. Sounds simple. In reality, a WebGL game exists in an extremely constrained environment: single thread, limited memory, sandbox without file system access, and Safari, which implements WebGL differently than Chrome.

How WebGL differs from native builds

Memory — the primary constraint

Unity WebGL compiles C# to WebAssembly via IL2CPP and runs everything in a single browser thread. The browser allocates linear memory (Heap) on startup — 256 MB by default. Exceeding this limit results in Out of Memory and page crash.

In practice this means:

  • All assets loaded through Resources.Load or Addressables live in one memory pool along with wasm code and stack.
  • Textures must be compressed aggressively: ETC2 and ASTC are unsupported in WebGL — only DXT (Desktop) and PVRTC (Safari/iOS, with caveats). We use crunch compression + fallback to uncompressed for Safari.
  • AudioClip in WAV format is 40 MB. The same clip in Vorbis (OGG) is 3 MB. In the context of a 256 MB heap this is critical.

For projects with large content volumes we move to a 512 MB limit through PlayerSettings.WebGL.memorySize, but remember: this is reserved immediately on page load, regardless of actual usage.

Lack of multithreading and workarounds

WebAssembly threading requires SharedArrayBuffer, which is blocked on most hosts without proper CORS headers (Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp). In practice in 2024-2025, we enable threading only if we control the server.

Without threading, all tasks — physics, animations, audio decoding — run on the main thread. This limitation forces different architectural thinking:

  • Coroutines with yield instead of heavy Update() loops — distributes calculations across frames.
  • Burst Compiler in WebGL works even without threading — compiles hot paths to SIMD-optimized wasm.
  • Algorithms with O(n²) complexity that are unnoticed on PC kill framerate in the browser.

Build size and load time

A standard Unity WebGL build without optimization weighs 30-60 MB (gzip). Users wait for loading — and leave. We optimize:

  • Code StrippingManaged Stripping Level: High. Removes unused .NET code. Saves 5-15 MB.
  • IL2CPP Code Generation: Faster runtime for production (slower compilation, faster runtime).
  • Brotli compression instead of gzip — server must support Content-Encoding: br. Compression is better by 15-20%.
  • Addressables for assets — load only what's needed for current scene, rest on demand.

Real example: a hyper-casual game for a marketing campaign. Initial build — 48 MB gzip. After stripping, texture optimization, and splitting into Addressable bundles — 11 MB initial load, remaining assets loaded in background. Time to first gameplay dropped from 18 to 4 seconds.

Stack and tools

Engine: Unity 2022 LTS / 2023.x, URP (Built-in pipeline for WebGL is undesirable — legacy). ShaderGraph with limitations: some nodes don't translate to WebGL GLSL correctly, we check through Preview in the editor.

Browser interaction: JavaScript plugins through jslib files in Assets/Plugins/WebGL/. Calling JS from C# through [DllImport("__Internal")]. Calling C# from JS through SendMessage() or Module.dynCall. For complex integrations (OAuth, payment systems, analytics) — a custom JS wrapper on top of Unity.

Multiplayer in WebGL: WebSocket instead of UDP. Mirror with SimpleWebTransport — works through WSS (WebSocket Secure). Photon Fusion supports WebGL via WebSocket relay. Latency is higher than UDP — we factor this into design.

Analytics and ads: UnityAds for WebGL works via iframe. For custom analytics — direct calls via jslib to Google Analytics / Amplitude. Firebase SDK in WebGL — only Firebase Analytics and Firestore (Auth and Realtime Database are limited).

Browser compatibility

Browser WebGL 2.0 Threading Notes
Chrome 100+ Yes Yes (with COOP/COEP) Best support
Firefox 100+ Yes Yes (with COOP/COEP) Good support
Safari 15+ Yes No Memory quirks
Edge (Chromium) Yes Yes (with COOP/COEP) Similar to Chrome
Mobile Chrome Yes No GPU throttling in background
Mobile Safari Partial No Many limitations

We test on real devices. BrowserStack or LambdaTest — for automation.

Development process

Requirements analysis (2-3 days). We determine: target browsers, memory requirements, need for multiplayer, integration with external services (auth, payments, analytics). A WebGL project starts with constraints, not features.

Asset architecture. We plan Addressable Groups from the start — which assets in the initial build, what loads as needed. A mistake — adding Addressables mid-project: this requires refactoring all load paths.

Development and optimization. In parallel with development — regular builds and size measurement via Build Report. Unity Profiler works for WebGL via Development Build + remote profiling from the editor.

QA on target platforms. Essential: real mobile Safari, real Chrome on mid-range Android device. Browser DevTools emulation doesn't reflect real memory consumption and GPU throttling.

Deployment. Nginx with proper MIME types (.wasm → application/wasm, .data → application/octet-stream) and Brotli/gzip. CDN for static assets — loading from an edge node instead of origin significantly reduces time to first frame.

Timelines — from 1-2 weeks for simple casual games to 2 months for midcore projects with multiplayer and complex integration. Cost is calculated after analyzing the specification.