ElmaJS: JavaScript library for reading and writing level, replay, LGR and state.dat files

Advertise your levels, contests, sites etc.

Moderator: Moporators

Post Reply
User avatar
39mins club
Posts: 768
Joined: 16 Jun 2002, 07:36
Location: Oslo, Norway

ElmaJS: JavaScript library for reading and writing level, replay, LGR and state.dat files

Post by skint0r » 19 Jun 2020, 17:25

I initially made a JS library for Node many years ago, but it was always pretty shit and never properly updated. I started doing a rewrite of this a long time ago, but it's been pretty slow until the last couple of months/weeks when I finally had some motivation and time to work on this again.

The old NPM package was node-elma, and it has now been renamed to elmajs, as it is no longer Node.js specific and it's possible to use it in a browser as well. I rewrote it in TypeScript and it should be somewhat feature complete so that you can do most of what you want with any kind of game file. If you can't, then maybe open an issue. I've tried to add as many tests as possible, but there might be some weird things that slipped through the cracks.

Git repo: https://github.com/elmadev/elmajs
NPM: https://www.npmjs.com/package/elmajs
UMD bundle (e.g. you can paste this in a script tag directly without dealing with NPM or any building/bundling): https://unpkg.com/elmajs@1.0.2/umd/main.js

Some examples from readme file:

Opening and editing a level file in Node.js

Code: Select all

const fs = require('fs');
const { Level } = require('elmajs');

const fileBuffer = fs.readFileSync('C:/EOL/lev/groof89.lev');
const level = Level.from(fileBuffer);
level.name = 'rename level';
level.top10.single = []; // remove single player best times list
fs.writeFileSync('testlev.lev', level.toBuffer());
Using UMD bundle in browser directly

Code: Select all

  <script src="https://unpkg.com/elmajs@1.0.2/umd/main.js"></script>
    (async () => {
      const file = await fetch('https://eol.ams3.digitaloceanspaces.com/replays/vq0y3cwqfn/37Spef5269.rec');
      const buffer = await file.arrayBuffer();
      const rec = ElmaJS.Replay.from(buffer); // the UMD bundle adds a ElmaJS global variable with all functionality

      const info = document.getElementById('info');
      // returns whether ride in replay is finished (has a touch event as the final event)
      // and the time (if finished, exact same of event -- otherwise approximation based on frame count or a touch event)
      const { finished, time, reason } = rec.getTime();
      info.innerHTML = `${rec.level}: ${time}`; // QWQUU037.LEV: 52690

  <div id="info"></div>
Prestigious member of 14.6x Tutor14 club

Post Reply