Recent posts

#21
Level Design / Re: How do you get level ideas...
Last post by WillLem - February 11, 2026, 09:38:27 AM
Quote from: Sabriella_Casper on February 10, 2026, 11:42:15 AMIt's wild how much the Amiga version stands out compared to the others. Those special levels really had a unique vibe that the PC/DOS ports just didn't quite capture.

Couldn't agree more, the game is so much better on Amiga. The graphics are better, the colours pop, the Paula sound chip adds stereo enhancements and makes the tunes sound great, and the game itself (whilst flawed) still feels fresh when played today.

Besides, Lemmings was written on Amiga for Amiga, so IMHO that's the 'official' version. All other versions are ports.

Quote from: Sabriella_Casper on February 10, 2026, 11:42:15 AMIf anyone's looking to play them today, the 'Amiga' level packs for NeoLemmix are a lifesaver - they port the levels over perfectly while keeping the modern quality-of-life features.

Whilst it is a fantastic option, NeoLemmix doesn't actually include the original Amiga games. Lemmings Redux is a collection of the best levels from DOS Lemmings, Oh No! and other ported versions (Genesis, PSP, etc).

If you want the closest possible experience to Amiga Lemmings whilst having access to the modern QOL player assists, SuperLemmix is where it's at. It comes bundled with the full unedited Lemmings and Oh No! level packs, it has an Amiga theme which can be applied in settings, the colour scheme is copied bit-by-bit from the Amiga sprites, and it has a "Classic Mode" which can toggle the player assists on and off. Beyond the aesthetics though, some of the actual game physics (top/sides of level behaviour, Builder collision, steel areas) have been specifically modelled on the Amiga version of the game. It even has the old cursor trick (where the cursor flickers when holding it next to a bunch of lems), which has been removed from most modern clones.

I worked hard to endow SuperLemmix with those Amiga vibes, give it a look!
#22
Tech & Research / Re: Rustlings / code generatio...
Last post by WillLem - February 11, 2026, 09:18:11 AM
Nice work, and welcome to the Forums! :thumbsup:
#23
Lemmini / Re: [+][SUG] Add postview jing...
Last post by WillLem - February 11, 2026, 09:13:51 AM
Optional postview jingles have now been added (they're off by default, and can be toggled on in settings).

The sounds are called "pass.wav" and "fail.wav" and can be found in resources/sound. They're the SEGA Master System ones by default, but can be swapped out to anything you like.

Implemented in commit 7cb734b.
#24
Community Edition / Re: [?][SUG][PL] Use "saved/re...
Last post by WillLem - February 11, 2026, 07:30:20 AM
Quote from: Dominator_101 on February 09, 2026, 01:35:09 PMOne option for this would be to display extra saves as '+X'. This could work with both negative and non negative req count really, but for the case of using a positive req counting down adding '+' in front after saving enough helps differentiate it.

Yes, that could work.

However, I can't help but think that the panel display should be as simple as possible. Even with a "+" simple, the question then becomes "added to what?" (it isn't necessarily obvious that it means "added to the save requirement"). Although, admittedly, the "+" would probably be interpreted as "surplus" by the majority of players.

Anyways, I've given this topic a bit more thought and I keep coming back to this idea:

:lemming: Always display a positive number.

:lemming: Count downwards whilst the save requirement hasn't been met - so, at this point, the number is "how many lemmings still need to be saved", which is what the player most needs to know. No "-/+", no asking the player to do sums, just show the information as plainly as possible. And, show this number in either yellow or blue.

:lemming: As soon as the save requirment is met, immediately switch to showing "total saved", and continue to count upwards from there as more lems are saved. And, show this number in green.

All things considered, I think this might be the best possible option.
#25
NeoLemmix Levels / Re: Kids Lemmings : awkward le...
Last post by Guigui - February 11, 2026, 01:23:30 AM
Good job for clearing the pack JawaJuice  :thumbsup:

I love how you take your time to give optimal solutions, like in Max 5 Sky Of The Night where you demonstrate how to slightly isolate a Lemming from the crowd to fill the tiny gap before the crowd comes, of Val's Fire Burn More where you dig at the precise place that allows the pioneer to come back and free the crowd.

Sure you did not solve all of them the way the kids saw it, but we loved to watch your clever solutions, thank you.
#26
Tech & Research / Re: Rustlings / code generatio...
Last post by DirtyHairy - February 10, 2026, 10:49:47 PM
Actually, turns reality is slightly more complicated ;) On my actual copy of lemmings, the code for the next level depends on the percentage of lemmings rescued when completing the current one, and all different codes generated this way work. In addition, there is a variable (that I called "salt" in the listing below), the lowest 4 bit of which are encoded in the code. All different salts generate valid codes, and restoring a code also restores the salt, so subsequent codes will encode the same value. Or, in other words, if you enter a code for a different percentage you'll get the same codes for the next levels, but if you enter a code with a different salt you'll get a different set of codes.

// rating:        0 .. 4
// level:         0 .. 29
// percentage:    0 .. 100
// salt:          0 .. 0x0f
function codeFor(rating, level, percentage = 100, salt = 0x00) {
  const secret = "AJHLDHBBCJ".split("").map((x) => x.charCodeAt(0));

  const levelIndex = 30 * rating + level;
  const code = new Array(10).fill(" ".charCodeAt(0));

  code[0] = ((levelIndex & 0x01) << 3) | secret[0] | ((salt & 0x01) << 1) | ((percentage & 0x01) << 2);
  code[1] = ((levelIndex & 0x02) << 1) | secret[1] | ((percentage & 0x02) >> 1);
  code[2] = (levelIndex & 0x04) | secret[2] | ((percentage & 0x04) >> 1) | ((salt & 0x02) >> 1);
  code[3] = ((levelIndex & 0x08) >> 3) | secret[3] | ((percentage & 0x08) >> 2);
  code[4] = ((levelIndex & 0x10) >> 3) | secret[4] | ((percentage & 0x10) >> 1) | ((salt & 0x04) >> 2);

  code[5] = ((levelIndex & 0x20) >> 5) | secret[5] | ((percentage & 0x20) >> 3) | ((salt & 0x08) >> 2);
  code[6] = ((levelIndex & 0xc0) >> 4) | secret[6] | ((percentage & 0x40) >> 6);
  code[7] = (levelIndex & 0xf) + secret[7];
  code[8] = (levelIndex >> 4) + secret[8];

  code[9] =
    ((code[0] + code[1] + code[2] + code[3] + code[4] + code[5] + code[6] + code[7] + code[8]) & 0xf) + secret[9];

  for (let i = 7 - (levelIndex & 0x07); i > -1; i--) {
    const tmp = code[6];
    code[6] = code[5];
    code[5] = code[4];
    code[4] = code[3];
    code[3] = code[2];
    code[2] = code[1];
    code[1] = code[0];
    code[0] = tmp;
  }

  return code.map((x) => String.fromCharCode(x)).join("");
}
#27
Other Projects / Re: Neon Swarm, lemmings remak...
Last post by crispweed - February 10, 2026, 08:54:27 PM
Another update just went out for this, with a build of the client now running as a web client (so no download or installation required, just run it directly in the browser). You can run this at: https://locksteparcade.com/Client
#28
NeoLemmix Levels / Re: Kids Lemmings : awkward le...
Last post by JawaJuice - February 10, 2026, 07:42:58 PM
This was a fun diversion, @Guigui!

Quite easy of course, but also awkward, as advertised! I've played easier packs made by people a lot older :P There are some surprisingly decent levels here, given that they're designed by your kids. Good job, Val and Max! :thumbsup: Replays attached. Probably backrouted a bunch of em, but hey, that's the way it goes ;)

#29
Tech & Research / Rustlings / code generation al...
Last post by DirtyHairy - February 10, 2026, 06:56:32 PM
Howdy!

I few years ago I wrote a lemmings 1 data decoder and viewer ("rustlings") in an effort to get to know rust. At this point, it is capable to decode the original data files, extract level and graphics data and display sprites and levels. You can find the source here: https://github.com/DirtyHairy/rustlings

A few days ago I started working on it again, with the intend of expanding it into a full game engine. Since then I have spent a bit of time poking the original .exe with Ghidra to reverse a few bits and pieces that I am missing (or do not just want to read off from existing reimplementations), and on the way I also reversed the code generation algorithm. As I couldn't find much about this online, here's a JavaScript version that can generate the codes for all original levels, in case anyone else comes looking for the same thing:

// rating and level both zero based
function codeFor(rating, level) {
  const secret = "AJHLDHBBCJ".split("").map((x) => x.charCodeAt(0));
  const percentage = 100;

  const levelIndex = 30 * rating + level;
  const code = new Array(10).fill(" ".charCodeAt(0));

  code[0] = ((levelIndex & 0x01) << 3) | secret[0] | ((percentage & 0x01) << 2);
  code[1] = ((levelIndex & 0x02) << 1) | secret[1] | ((percentage & 0x02) >> 1);
  code[2] = (levelIndex & 0x04) | secret[2] | ((percentage & 0x04) >> 1);
  code[3] = ((levelIndex & 0x08) >> 3) | secret[3] | ((percentage & 0x08) >> 2);
  code[4] = ((levelIndex & 0x10) >> 3) | secret[4] | ((percentage & 0x10) >> 1);
  code[5] = ((levelIndex & 0x20) >> 5) | secret[5] | ((percentage & 0x20) >> 3);
  code[6] = ((levelIndex & 0xc0) >> 4) | secret[6] | ((percentage & 0x40) >> 6);
  code[7] = (levelIndex & 0xf) + secret[7];
  code[8] = (levelIndex >> 4) + secret[8];
  code[9] =
    ((code[0] + code[1] + code[2] + code[3] + code[4] + code[5] + code[6] + code[7] + code[8]) & 0xf) + secret[9];

  for (let i = 7 - (levelIndex & 0x07); i > -1; i--) {
    const tmp = code[6];
    code[6] = code[5];
    code[5] = code[4];
    code[4] = code[3];
    code[3] = code[2];
    code[2] = code[1];
    code[1] = code[0];
    code[0] = tmp;
  }

  return code.map((x) => String.fromCharCode(x)).join("");
}
#30
Level Design / Re: [DISC] Why is the intended...
Last post by hrb264 - February 10, 2026, 04:01:11 PM
Good point i don't mind back routes, sometimes they are harder/more elaborate than the original solution though. I can see why they would be annoying to the person that designed the level though.

I personally like levels that can be solved many different ways, i like figuring out how to solve it the 'correct' way though.