Skip to content

Lionheart Remake in the browser (TeaVM)

Choose a tag to compare

@ray77 ray77 released this 28 Jul 21:25
· 10 commits to web since this release

The game runs in a browser — no plugin, no JVM in the page. The Java bytecode is translated to JavaScript ahead of time with TeaVM, on top of a new graphics, input, media and audio backend (lionengine-core-web).

Measured

Frame rate 60/s, game logic at the original 50 Hz
Translated output 7.3 MB of JavaScript
Chip music sc68 compiled to WebAssembly, 151 KB
Sound effects 55 of 55 decoded
Playable stages 1–14

For comparison: the same attempt with a JVM in the browser (CheerpJ) reached 3 frames a second.

Trying it

Download, unpack, start a server in that folder — the page fetches its assets over HTTP, so opening index.html directly will not work:

python3 -m http.server 8000

Then open http://localhost:8000/. Arrow keys to move, space to jump, X to attack.

What was added

  • Browser backend lionengine-core-web: canvas drawing, input, assets from one pack instead of from files, frame loop on requestAnimationFrame using TeaVM coroutines.
  • Chip music: sc68 compiled to WebAssembly and driven pull based — tracks stay at a few dozen kilobytes and loop seamlessly, rather than being pre-rendered.
  • A score in the HUD, which the game did not keep before (distance, talismans, lives).
  • Widescreen 370×208, the size the backgrounds are drawn for.
  • Test entry ?trainer=true&x=370&y=12#level=07: pick a stage, set a spawn point, take no damage.

Bugs found while porting

All platform independent, all included in the branch:

  • Math.round disagrees with Java on negative halves — map chunks landed 257 instead of 256 pixels apart, and the background showed through the seam.
  • An object moved by another object never noticed: whether it had already backed up its position depended on iteration order. The swinging platforms carried nobody.
  • clearRect makes a canvas transparent, not black — so everything not drawn showed the previous frame.
  • Reading a canvas back from the graphics card cost 77 ms a frame until the context was created with willReadFrequently.
  • Unboxing null raises a JavaScript error that no catch (NullPointerException) will see.

The build is described in the web branch. Engine: ray77/lionengine, branch web.

GPL, as the originals by b3dgs.