Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - roltemurto

#1
Congratulations on the 3.1 Update!!!
Personally I think it's a work of art!

Will fully utilize it in the following days.
But even at a first glance it looks so powerful.

I immediately tried the pieces list and it works like a charm with a level consisting of 200+ pieces. It is SO useful especially with non-repeated, uniquely named custom pieces, it is such a dream!

You cared, you listened and you gifted. I can only hope that you are enjoying as well, the fruits of your love as much as I do.
Sorry for my belated response, had been away from my home and my pc for the past few days and I JUST noticed your release, looking at the github commits.

May life put a smile on your face. Have a wonderful day!
#2
Hello again WillLem,

BAD NEWS: I can confirm the "Could not read editor options" error has returned, even with RC version that I'm using right now.
GOOD NEWS: I think I found what causes it and may have a possible solution.

I believe it may be related to crashed exits and it is most probably connected to the monitor-off crash I reported in the other topic (BUG: Editor crashes when monitor turned off).

Here is my new error log entry, translated to English:

System.NullReferenceException: Object reference not set to an instance of an object.
  at SLXEditor.SLXEditForm.ReadLevelInfoFromForm(Boolean allowWriteBack)
  at SLXEditor.SLXEditForm.CommitLevelChanges()
  at SLXEditor.SLXEditForm.textbox_Leave(Object sender, EventArgs e)
  at SLXEditor.SLXEditForm.chk_Lvl_AutoStart_Leave(Object sender, EventArgs e)
  at System.Windows.Forms.CheckBox.OnCheckedChanged(EventArgs e)
  at System.Windows.Forms.CheckBox.set_CheckState(CheckState value)
  at System.Windows.Forms.CheckBox.set_Checked(Boolean value)
  at SLXEditor.Settings.ReadSettingsFromFile()

The previous crash (Bitmap region already locked / form resize on monitor wake-up) was an abnormal termination. The editor was killed mid-operation without going through its normal shutdown sequence, which means the settings file was almost certainly either left incomplete or not updated at all with the session's final state.

When I launched the editor first time since that crash, ReadSettingsFromFile() attempted to load that potentially corrupt or incomplete SLXEditorSettings.ini. I suspect that when it hits the UseAutostart = True line, it sets chk_Lvl_AutoStart.Checked = true, which fires the OnCheckedChanged > chk_Lvl_AutoStart_Leave > textbox_Leave > ReadLevelInfoFromForm event chain at a point where the form is not yet fully initialized, causing the NullReferenceException.

While the origin of the initial error may still have ties to the "İ" problem, the error seems intermittent because it manifested again after an abnormal shutdown leaves the settings file in a bad state.
So far, under normal operation (clean close and reopen), the settings load fine.

You already solved the other topic by implementing a proper lock guard so the editor does not die mid-operation and leave files in an inconsistent state.
But any future abnormal termination (power cut, OS crash, etc.) can still trigger the same settings-read failure.

So perhaps you may wanna take a look at this;
  • The settings reader ReadSettingsFromFile() should suppress checkbox event handlers while loading, to prevent UI events from firing before the form is ready. Standard WinForms pattern:

chk_Lvl_AutoStart.CheckedChanged -= chk_Lvl_AutoStart_Leave;
chk_Lvl_AutoStart.Checked = value;
chk_Lvl_AutoStart.CheckedChanged += chk_Lvl_AutoStart_Leave;

Hope this helps narrow it down. Happy to provide any further info.
#3
Quote from: WillLem on April 07, 2026, 10:39:10 PMAlways happy to accept help wherever offered! It's good to not have to always figure these things out on my own :)

Besides, I figured that some re-rendering prevention guard is what was needed. You helped pin it down to exactly where the guard needed to be - this is much appreciated!
I am SO happy to hear this.
I vigorously follow your commits at;
https://github.com/Willicious/SuperLemmixEditor/commits/master/SLXEditor
and must admit; these may seem some small changes but I really think the editor is becoming such a robust and bulletproof piece of software. This excites me very much while at the same time brining me serenity. I don't know if you experience similar feelings whenever you improve or fix something with your own software...

Thanks for everything...
#4
Quote from: WillLem on April 07, 2026, 03:45:11 PMNot sure exactly why the exception occurred though. Maybe more resolution-specific guards need to be in place.

I hope I don't overstep my boundaries by doing this but I just want to be helpful.
So I gave the errors to an AI and explained the situation.
Here's how it diagnosed it and came up with possible solutions;


Diagnosis

Root cause: System.InvalidOperationException: Bitmap region is already locked.

The call stack is:

NLEditForm_Resize → ResetLevelImage → CombineLayers → CreateLevelImageFromLayers → BmpModify.DrawOn → Bitmap.LockBits
When the monitor is turned off via DisplayPort, Windows triggers a resolution/display change, which causes the WinForms window to receive a WM_WINDOWPOSCHANGED message. This fires OnResizeNLEditForm_Resize. The problem is that the renderer was already in the middle of a rendering operation (with a bitmap locked via LockBits) when this resize event fired — either from a concurrent render or from a prior render that didn't properly call UnlockBits before the resize interrupted it.

This is a re-entrancy / double-lock bug: Bitmap.LockBits is called on a bitmap that still has an active lock, either because:
  • A previous render was interrupted mid-flight and UnlockBits was never called (e.g. due to an earlier exception), or
  • The resize event fires while a render is already running (re-entrant call).



Solution

There are two complementary fixes that should both be applied.

Fix 1 — Re-entrancy guard on ResetLevelImage

Prevent NLEditForm_Resize from triggering a render if one is already in progress:

// In SLXEditForm:
private bool _isRendering = false;

private void ResetLevelImage()
{
    if (_isRendering) return;  // Guard against re-entrant calls
    _isRendering = true;
    try
    {
        // ... existing ResetLevelImage body ...
    }
    finally
    {
        _isRendering = false;
    }
}

This is the most important fix. It prevents a resize event from launching a new render while one is already running.



Fix 2 — Ensure UnlockBits is always called in BmpModify.DrawOn

The existing DrawOn method almost certainly does LockBits without a try/finally guarantee on UnlockBits. If any exception occurs mid-render, the bitmap stays locked forever for the lifetime of the object. Fix the locking pattern:

// In BmpModify.DrawOn — wrap the LockBits/UnlockBits pair in try/finally:
BitmapData bmpData = null;
try
{
    bmpData = origBmp.LockBits(rect, ImageLockMode.ReadOnly, origBmp.PixelFormat);
    // ... pixel operations ...
}
finally
{
    if (bmpData != null)
        origBmp.UnlockBits(bmpData);
}

Do the same for newBmp if it is also locked in that method. This ensures that even if an exception fires partway through a render, the lock is always released and future renders won't see a pre-locked bitmap.



Fix 3 (optional hardening) — Debounce resize events

Resize events can fire dozens of times per second during a resolution change. Even with the re-entrancy guard, it is worth debouncing to avoid hammering the renderer immediately after wake:

private System.Windows.Forms.Timer _resizeDebounce;

private void NLEditForm_Resize(object sender, EventArgs e)
{
    if (_resizeDebounce == null)
    {
        _resizeDebounce = new System.Windows.Forms.Timer { Interval = 150 };
        _resizeDebounce.Tick += (s, _) =>
        {
            _resizeDebounce.Stop();
            ResetLevelImage();
        };
    }
    _resizeDebounce.Stop();
    _resizeDebounce.Start();
}

This collapses a burst of resize events into a single render call 150ms after the last one.



Summary

FixWhat it addresses
Re-entrancy guard (_isRendering)Stops a second render from starting while one is in progress
try/finally around LockBitsGuarantees unlock even if a render throws mid-way
Resize debounceReduces needless render thrash during resolution changes

Fix 1 alone would have prevented this specific crash. Fix 2 prevents the "permanently locked bitmap" failure mode that makes Fix 1 necessary in the first place. Fix 3 is polish.
#5
Hello again WillLem,

Sorry for bombarding the forum board lately, but I got a new bug report.
Below I am attaching the .NET Framework error pop-up. The log file doesn't have anything up to date.
This happened after I turned my monitor off for an hour (at least this is what I am suspecting of what caused it).
When I turned it back on these errors were popped up;

Instead of this dialog box, JIT debugging would be invoked
For more details, see the end of this message.

************** Exception Text **************
System.InvalidOperationException: Bitmap region is already locked.
at: System.Drawing.Bitmap.LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format, BitmapData bitmapData)
at: System.Drawing.Bitmap.LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format)
at: SLXEditor.BmpModify.DrawOn(Bitmap origBmp, Bitmap newBmp, Point pos, Func`3 doDrawThisPixel, Byte alpha)
at: SLXEditor.BmpModify.DrawOn(Bitmap origBmp, Bitmap newBmp)
at: SLXEditor.Renderer.CreateLevelImageFromLayers(String dragNewPieceKey)
at: SLXEditor.Renderer.CombineLayers(String dragNewPieceKey)
at: SLXEditor.SLXEditForm.ResetLevelImage()
at: SLXEditor.SLXEditForm.NLEditForm_Resize(Object sender, EventArgs e)
at: System.EventHandler.Invoke(Object sender, EventArgs e)
at: System.Windows.Forms.Control.OnResize(EventArgs e)
at: System.Windows.Forms.Form.OnResize(EventArgs e)
at: System.Windows.Forms.Control.OnSizeChanged(EventArgs e)
at: System.Windows.Forms.Control.UpdateBounds(Int32 x, Int32 y, Int32 width, Int32 height, Int32 clientWidth, Int32 clientHeight)
at: System.Windows.Forms.Control.UpdateBounds()
at: System.Windows.Forms.Control.WmWindowPosChanged(Message& m)
at: System.Windows.Forms.Control.WndProc(Message& m)
at: System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at: System.Windows.Forms.ContainerControl.WndProc(Message& m)
at: System.Windows.Forms.Form.WmWindowPosChanged(Message& m)
at: System.Windows.Forms.Form.WndProc(Message& m)
at: System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at: System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at: System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

************** Loaded Assemblies **************
mscorlib
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4515.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll

SLXEditor
Assembly Version: 3.0.3.0
Win32 Version: 3.0.3.0
CodeBase: file:///X:/YEKELEMELER/OYUN/Lemmings/NeoLemmix_V12.14.0/SuperLemmix%203.0.2/SLXEditor.exe

System.Windows.Forms
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4550.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll

System
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4536.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll

System.Drawing
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4390.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll

System.Core
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4590.0 built by: NET48REL1LAST_B
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll

System.Configuration
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4190.0 built by: NET48REL1LAST_B
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll

System.Xml
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4084.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll

Accessibility
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4084.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Accessibility/v4.0_4.0.0.0__b03f5f7f11d50a3a/Accessibility.dll

mscorlib.resources
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4084.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/mscorlib.resources/v4.0_4.0.0.0_tr_b77a5c561934e089/mscorlib.resources.dll

System.Drawing.resources
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4084.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Drawing.resources/v4.0_4.0.0.0_tr_b03f5f7f11d50a3a/System.Drawing.resources.dll

System.Windows.Forms.resources
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4084.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms.resources/v4.0_4.0.0.0_tr_b77a5c561934e089/System.Windows.Forms.resources.dll

************** JIT Debugging **************
To enable JIT debugging, the jitDebugging value must be set in the
system.windows.forms section of the application's or machine's (machine.config)
.config file. The application must also be compiled with debugging
enabled.

For example:
<configuration> <system.windows.forms jitDebugging="true" /> </configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than being handled in this dialog box.

Luckily the editor DID allow me to save the map before exiting.
The reason I'm suspecting the monitor is due to the fact that I am using displayport for connection and I believe this connection causes resolution change during turn off and wake up.
#6
Quote from: WillLem on April 03, 2026, 11:07:24 PMAdded menu item and customisable hotkey (Ctrl + F2 by default) for Show/Hide Steel.
Implemented in SLXEditor commit 9ea1149.
Great news, can't wait for the full release!
Quote from: WillLem on April 03, 2026, 11:07:24 PMI've also fixed a bug with this: the hotkey would only work if there was no currently-selected piece under the cursor. This has now been fixed, so the hotkey will always cause the selection to re-trigger.
Fixed in SLXEditor commit 83d622d.
So that's why it was inconsistent! Great catch and awesome news!
Quote from: WillLem on April 03, 2026, 11:07:24 PMA hotkey to rotate through the pile is all that's needed, then. This has also been added: holding Shift whilst clicking LMB cycles selection through all pieces within 16px of the cursor (from lowest-highest).
Implemented in SLXEditor commit 8a1ce87
This is gonna be so useful
Quote from: WillLem on April 03, 2026, 11:07:24 PMAh, OK! In that case I've added this one to the to-do list. This one will likely take a bit longer, I'll post progress updates into this topic.
Thank you so much for getting into this, everyone will benefit from this.
Quote from: WillLem on April 03, 2026, 11:07:24 PMSelecting the piece from within the proposed asset list should be sufficient here. Showing each individual piece as its own "layer" could be done, but let's see if we need it first. That might be a good next step once the asset list (which I'll probably call the 'Pieces List' to keep it consistent with existing UI) is complete and working.
You're the owner/designer/coder, I'm sure whichever path you choose to take from here will be the most suiting one.
Quote from: WillLem on April 03, 2026, 11:07:24 PMThat's good to know, thanks for reporting back on this! :)
My pleasure!  :)  :thumbsup:
#7
Quote from: WillLem on April 03, 2026, 11:07:24 PMThe "select pieces below" hotkey (Alt + LMB by default) does work some of the time, but becomes difficult or impossible to use properly when there are multiple overlaying pieces.
I must admit I may have mixed ALT with CTRL, so I may have not fully utilized this properly but as you mentioned, when multiple pieces collide on top of each other this option unfortunately is not enough to solve it.

Quote from: WillLem on April 03, 2026, 11:07:24 PMGood shout. I'll add Show/Hide Steel in the next update for sure.
Such a relief to hear this is possible. Thank you.

Quote from: WillLem on April 03, 2026, 11:07:24 PM...not trivial to implement by any means, and still doesn't always guarantee selectability...
As you point out, it is of small importance and doesn't solve every selection problem. But an outline of the exact piece could be a great helper.
I don't think bypassing the alpha  would render the rectangle redundant though; you can still see it total boundaries while being able to select something visible behind.

Quote from: WillLem on April 03, 2026, 11:07:24 PM'Grab lowest' and 'grab highest' could also be done.
"Grab lowest" toggle would certainly be useful I think.

Quote from: WillLem on April 03, 2026, 11:07:24 PM...It just about works for image editing...
...
...Conversely, the "asset list" you've hinted at is an interesting idea that could work perfectly alongside what's already there. We could have a pop-up list (which can be closed or opened at any time) which simply lists every piece active in the level, in index order and with details such as location, render layer, whether it's an eraser piece, etc. Clicking a piece on the list could then select it in the level arranger (and vice versa). This could work, for sure, and would be much simpler to implement and maintain than a layers system. "Move Up", "Move Down" and "Delete" buttons could also be added for convenience.
An "asset list" was exactly what I was trying to describe. Yes I was thinking of image editor UI's but I haven't even thought about changing the rendering frame work etc.
I believe a simple "asset list" is all what it takes. If move up/down could also be implemented; that is exactly the thing I was suggesting. At this point I'm not sure if show/hide option next to the layer counts as changing the layer system, but if that can also work, that would be a perfect UI in my humble opinion.   

Furthermore, if an asset list were to be added, all of the above and other mentioned things become extra and/or secondary priority; because you'd be able to select what ever you want anyways.

Quote from: WillLem on April 03, 2026, 11:07:24 PMNot so. Missing pieces can be deleted by simply opening a level that contains missing pieces; the Editor will identify them, and they can then be deleted by choosing "Delete Missing Pieces" from the status bar menu. If you're not seeing the status bar message when you open a level with missing pieces, then this could be a bug.

Rest assured, the message bar pops up as intended, I haven't tried the buttons so I can't speak for sure for it's functions, but don't worry the bar and the message is there.
The moment I saw it the first time, I just re-added the recently deleted piece.
While researching the "depricated" flag I assumed that it was still a thing with the engine and the editor,
without realizing the editor could already clean them properly, that's my bad, sorry.

Quote from: WillLem on April 03, 2026, 11:07:24 PMAbsolutely, and it's something that I too struggle with now and again. You've given me a nudge to finally do something about it!
I am so glad that we are on the same page. Sometimes it takes a second person to point out the issues we delay in things.
I truly believe it would be a well worth investment of time for the editor, because afterwards it permenantly makes the life much easier for everyone.
And perhaps even trigger people's creativity even further.
Thanks again for everything.
#8
Quote from: WillLem on April 02, 2026, 05:50:51 AMHaha! Apologies, it's just easier to keep track of these things when they have separate topics.
Of course! No need to apologize.

Quote from: WillLem on April 02, 2026, 05:50:51 AMThanks for posting the full Error logs, some of those will no doubt be from before the previous "ToUpperInvariant" fix...
...
...But, let's completely exhaust the existing system first.
But I do need to apologize myself; because I have not been able to regenerate the error since the last time.
I can't remember if the last one I received  was from your RC version or v3.0.2, but I am beginning to suspect that it was also related to the "İ" problem.
If it ever comes back, I will make sure to report and let you know under this topic.

Thanks for taking such an interest in fixing and making your releases better which each version.
Greatly appreciated,
Cheers!
#9
When there are multiple objects, terrain etc on top of each other, with similar sizes and irregular shapes, it becomes impossible to select the desired asset.

For example on the design I am currently working on; I have a terrain piece on top of a very large piece of steel and an exit object on top of all.
I had to move the terrain back in order to align and position my exit but now I am stuck with not being able to select it because of the steel which blocking the way.

For my particular problem; an option to Show/Hide Steel (like any other layer) would solve it immediately.
Steel is the only asset type that hasn't got an option to hide/show.
I know steel is also technically a terrain, but I am referring to the distinction between steel and not steel.
Because in my example, I need to select the "not steel" terrain which is below the steel.
I fear it may not be possible to implement since the editor sees them all as terrain
but am hoping using it's flag etc would allow it.


An option in the settings or a modifier key press; that simply allow bypassing the alpha channel when selecting, would also save me right now.
I believe CTRL+Click and/or holding down the left mouse button 'sometimes' help with selecting an object which is behind of another,
but because of it's inconsistency I'm not so sure if this feature actually exists or not.

What would be a QoL update is; an actual toggle button to let the cursor prioritize and select the layer at the back/behind.

What would be an even better addition; is the layer system implementation;
Currently there is no way to tell how many layers are there or which and what layers are currently on the map.
This also makes it impossible to clean/delete an asset that has been removed/changed from the style folder,
because there is no way to select it once the editor is restarted, the level is reloaded or simply the styles has been refreshed.


If there was a file list or a layer system, that would allow;
- Eliminating the need to use the "depricated" feature. Since the assets can be selected and deleted from there,
- The ability to select/move, show/hide layers and objects individually,
- The ability to see/find assets at a glance, since it is outlined as it's selected,
- The ability to see/find how many and which assets are currently placed on a level,
  (assuming the filename is used for layer name instead of effect type)
- Make grouping and organizing much easier,
- Possibly allow to Show/Hide asset groups or groups of layers.


I hope I was able to explain the situation that I am struggling with.
Please let me know if I am missing something and if there's an already implemented way of working or selecting 'the object behind'.
Because even the marquee doesn't always help.

#10
To be totally frank, I was trying to build a realistic passageway to increase the immersiveness in the level. Giving a feeling of "3D" in Z axis. But then the idea of "hiding" the lemmings struck me and I tried to remember any level where I couldn't see my lemmings... I couldn't (obviously). Then I thought how exciting and perhaps nerve-racking it would be during the passage: "Will they fall somewhere? Is there a trap? Are they lost? Did they die? Is this a bug?" and then "OMG THEY WALKED BEHIND!"

While trying to figure out how to implement this, I actually wanted the player to still be able to see their lemmings walk in all fairness to the player. That's why I initially aimed for ~90% opacity. So yes, I was never really going for full concealment, more of a "veil" effect (Like the hanging moss).

Your concern about hiding lemmings from the player is completely fair, and I think opacity itself might be the natural answer to it. If the foreground decoration is drawn to rlEffects but respects the alpha of the source PNG, the level designer controls visibility directly: a 90% opacity tunnel still lets the player track their lemmings, a 100% opaque one is a deliberate and obvious artistic choice rather than a hidden 'gotcha'. The community's concern tends to be with *deceptive* hiding (concealed traps, invisible steel). A visually prominent arch that lemmings clearly walk behind feels categorically different.

On your concern about existing lemming effects (countdowns, balloon pop, etc.) potentially rendering beneath the foreground object: for this use case that's actually acceptable or even preferable. A timebomb countdown visible through a tunnel arch would look fine and is arguably better than it being hidden.

So the implementation I'd humbly suggest, if I may and if you do wish to pursue this:

- Allow DOM_DECORATION gadgets with a FOREGROUND flag to draw to rlEffects (exactly as you outlined; no new layer needed, the existing layer does the job).
- Honour the source PNG's alpha channel as-is during that draw, rather than forcing full opacity. This keeps the designer in control of how "veiled" the effect feels.
- Additionally, when a lemming's position is covered by a FOREGROUND-flagged decoration, you can have the engine draw a simple outline or silhouette of that lemming to rlEffects as well, ater the decoration is composited. Since both would write to the same layer and decorations are drawn before lemmings in the pipeline, the outline would naturally sit on top of the foreground asset. I believe the infrastructure for this already exists in the codebase as the CombineFixedColor is already used for similar fixed-color overlay passes and the lemming's bounding rect is readily available at draw time.

This approach sidesteps the "hidden lemmings" concern entirely without needing a cursor-hover mechanic. The outline guarantees the player always knows where their lemmings are, regardless of how opaque the foreground asset is. It also means no special documentation warnings like "Designer beware" are needed as the game handles visibility automatically...

The cursor-hover silhouette you mentioned could still be a nice additional polish if it's not too costly, but I think the outline alone would be sufficient.

THANK YOU for taking the time to look into this and for the detailed breakdown of the layer stack. That alone was incredibly helpful for understanding why my earlier attempts weren't working.
And sincerely thank you for keeping "The" nostalgia alive and keep improving it up to this day. I was stunned with disbelief when I discovered your fork (and NeoLemmix to be totally frank).
I wish you a great day!
#11
I took a while for me to realize that you moved this under a separate topic, I thought I hallucinated reporting it  :) . Sorry about that.

My ErrorLog.txt file is above 10MBs ... Repeating multiple same errors "multiple" times. So I used Notepad++'s "remove duplicate lines feature. Here are the original unique lines from that file;

System.ArgumentException: Parametre geçerli değil.
   konum: System.Drawing.Bitmap..ctor(String filename)
   konum: SLXEditor.Utility.CreateBitmapFromFile(String filePath)
   konum: SLXEditor.LoadStylesFromFile.Image(String imageKey)
System.Exception: 'System.Exception' türünde özel durum oluşturuldu.
   konum: SLXEditor.LoadStylesFromFile.CreateNewTerrainInfo(String filePath)
   konum: SLXEditor.LoadStylesFromFile.ImageInfo(String imageName)
   konum: SLXEditor.ImageLibrary.AddNewImage(String imageKey)
System.NullReferenceException: Nesne başvurusu bir nesnenin örneğine ayarlanmadı.
   konum: SLXEditor.SLXEditForm.ReadLevelInfoFromForm(Boolean allowWriteBack)
   konum: SLXEditor.SLXEditForm.textbox_Leave(Object sender, EventArgs e)
   konum: SLXEditor.SLXEditForm.chk_Lvl_AutoStart_Leave(Object sender, EventArgs e)
   konum: System.Windows.Forms.CheckBox.OnCheckedChanged(EventArgs e)
   konum: System.Windows.Forms.CheckBox.set_CheckState(CheckState value)
   konum: System.Windows.Forms.CheckBox.set_Checked(Boolean value)
   konum: SLXEditor.Settings.ReadSettingsFromFile()
   konum: SLXEditor.LoadStylesFromFile.CreateCompositeImage(String filePath, List`1 anims, LoadStyleAnimData primaryAnim, Int32& marginLeft, Int32& marginTop, Int32& marginRight, Int32& marginBottom, Boolean forceOriginalSize)
   konum: SLXEditor.LoadStylesFromFile.CreateNewObjectInfo(String filePath)
   konum: SLXEditor.SLXEditForm.CommitLevelChanges()
   konum: System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
   konum: System.Drawing.Bitmap..ctor(Int32 width, Int32 height)
System.DivideByZeroException: Sıfırla bölme girişiminde bulunuldu.

And here's the translated version;

System.ArgumentException: Parameter is not valid.
   at System.Drawing.Bitmap..ctor(String filename)
   at SLXEditor.Utility.CreateBitmapFromFile(String filePath)
   at SLXEditor.LoadStylesFromFile.Image(String imageKey)
System.Exception: Exception of type 'System.Exception' was thrown.
   at SLXEditor.LoadStylesFromFile.CreateNewTerrainInfo(String filePath)
   at SLXEditor.LoadStylesFromFile.ImageInfo(String imageName)
   at SLXEditor.ImageLibrary.AddNewImage(String imageKey)
System.NullReferenceException: Object reference not set to an instance of an object.
   at SLXEditor.SLXEditForm.ReadLevelInfoFromForm(Boolean allowWriteBack)
   at SLXEditor.SLXEditForm.textbox_Leave(Object sender, EventArgs e)
   at SLXEditor.SLXEditForm.chk_Lvl_AutoStart_Leave(Object sender, EventArgs e)
   at System.Windows.Forms.CheckBox.OnCheckedChanged(EventArgs e)
   at System.Windows.Forms.CheckBox.set_CheckState(CheckState value)
   at System.Windows.Forms.CheckBox.set_Checked(Boolean value)
   at SLXEditor.Settings.ReadSettingsFromFile()
   at SLXEditor.LoadStylesFromFile.CreateCompositeImage(String filePath, List`1 anims, LoadStyleAnimData primaryAnim, Int32& marginLeft, Int32& marginTop, Int32& marginRight, Int32& marginBottom, Boolean forceOriginalSize)
   at SLXEditor.LoadStylesFromFile.CreateNewObjectInfo(String filePath)
   at SLXEditor.SLXEditForm.CommitLevelChanges()
   at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
   at System.Drawing.Bitmap..ctor(Int32 width, Int32 height)
System.DivideByZeroException: Attempted to divide by zero.

I'm not sure why is it throwing too many errors and produced 184146 lines of errors between 20260330140005 - 20260402061859 but I'm deleting the file now to see what new errors it'll fill up with.

#12
Quote from: David on November 18, 2020, 08:57:49 PM"NO_EFFECT" images may be in the foreground or background while "BACKGROUND" images are always in the background (sometimes, I like to quibble ! :evil: ;P)

How do I force foreground for and object or terrain so that lemmings walk behind it?
#13
I am trying to create sort of a tunnel with %90 opacity so you can barely see the lemmings walk behind. I want it to physically be pass-through but visually on top of everything.

OR think of a scenario of a dungeon where some of the moss textures appear in front of the lemmings which is also something I like to achieve.
I tried decoration and one way flags as effect but I can't seem to achieve this. "No overwrite" nor "Draw Last" options don't help.  I even edited the level file giving the $gadget "foreground" flag but that also didn't work.

I've been searching the internet, these forums and old documentations for reference but so far no luck.

How does one go about creating a foreground terrain/object/decoration which is occluding but pass-through?
#14
Quote from: WillLem on April 01, 2026, 01:38:24 AMGlad to hear it worked, thanks for reporting back quickly! I'll get a hotfix release out soon :)

Great news. Since you're still polishing it, I like to report another thing you may wanna look at;

I get the "Warning: Could not read editor options from SLXEditorSettings.ini. Editor uses the default settings."

This happens even though the folders and files are NOT read-only and the exe runs as administrator. I am not sure if it's related to my locale again, but I keep having to customize my settings each time.
This is what my updated ini file looks like;
# SLXEditor settings
 EditorMode          Auto
 DefaultAuthorName      E
 DefaultTemplate       
 ValidateWhenSaving     True
 Autosave               2
 AutosaveLimit          5
 PieceBrowserMode       ShowData
 AutoPinOGStyles        True
 PreferObjectName       False
 InfiniteScrolling      False
 ShowRandomButton       False
 UseAutostart           True
 GridSize               1
 GridColor              MidnightBlue
 TriggerAreaColor       Pink
 CustomMove             64
 Button_Tooltip         3

 Form_Maximized         True
 Form_Width             872
 Form_Height            469

 ShowAboutAtStartup     True
 ShowControlHints       True
 AllTabsExpanded        False
 HighlightGroups        False
 HighlightErasers       False

 LevelArrangerOpen      False
 LevelArrangerMaximized False
 LevelArrangerLocation  301,71
 LevelArrangerSize      2126,1089

 PieceBrowserOpen       False
 PieceBrowserMaximized  False
 PieceBrowserLocation   643,381
 PieceBrowserSize       1425,148

 Display                Triggers
 Display                Rulers
 Display                ScreenStart
 Display                Background
#15
Quote from: WillLem on March 31, 2026, 02:08:08 AMThanks for reporting this. I've prepared a test version with the suggested fix (see attached), although it uses "ToUpperInvariant()" and "ToLowerInvariant()" instead, as this is shorthand for the same thing.

Can you confirm that this indeed fixes the issue?



NOTE TO ALL: Please do not use the attached Editor for anything important as stability cannot be guaranteed. Thanks.



Dear WillLem,

Thank you so much for your rapid response and quick fix. I tried the exe and the fix indeed works as intended.   :lem-mindblown: :thumbsup:
To test it, I first opened a level with swimmers and used Save As. The saved copy did in fact carry the skillset forward and the spelling is now correct.
Then I edited the file, set the hatch object piece to spawn swimmers re-saved and that file is also saved correctly and both levels open correctly in the player.
You can count the infamous "Turkish I problem" as 'solved' for your release candidate.

I also set the level to spawn ten lemmings and added a lemmings object, setting it's skill to swimmer. As mentioned earlier even with the hatch being set to spawn swimmers and manually added a lemming, the Globals tab still shows "11 Normal" under the Lemmings spawn/release rate and save options. I am not sure if I am doing something wrong or if it's a bug I wanted to let you know about this as well.

Once again, I thank you so much on behalf of all the players who suffered from the "İ" problem, for fixing it.