Updating Lem3Edit {v2.1 - 05/05/2018}

Started by kieranmillar, November 10, 2017, 10:01:32 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

kieranmillar

I want to jot down my thoughts about level file management for Lemmings 3 and a potential solution for lem3edit to eventually take. Somebody might be interested, so I'll explain it here.

When editing Lemmings 2, I only had to deal with a single level file. I could name the file anything I wanted to, test them individually in the editor, then when it came to release the pack, copy over any files that changed and rename them appropriately into LEVEL###.DAT according to its tribe and position. Not the quickest process when it comes to releasing an update, but it was easy to organise.

In Lemmings 3 there is not one file, but three. LEVEL###.DAT, PERM###.OBS and TEMP###.OBS. The DAT file is tiny and contains basic level properties, like its size, which Tribe it is, time limit, that sort of thing, while the two OBS files contain the positions and types of all of the objects and terrain pieces that the level uses. Straight away we can see a huge problem, making a release or changing the order of the levels involves triple the work, as all 3 files need renaming. Doing this manually will be a huge pain, but its doable. And if you want to rename the levels while working on them to something easier to remember so you know which level is which, ideally you want all 3 files to have a similar naming convention. So a huge pain in the butt, still doable manually but very tedious.

But wait! Lemmings 3 has one more really annoying trick up its sleeve! This isn't actually how it works at all! You see, when the game wants to load Classic 1, it loads up LEVEL001.DAT as you'd expect, but inside LEVEL001.DAT two numbers are saved, one for the number in the PERM filename, and one for the number in the OBJ filename. So renaming those latter two files is technically unnecessary, and PERM001.OBS doesn't even necessarily get read by LEVEL001.DAT.

This leaves two choices if someone is making a level pack and wants to reorder two levels manually:
1) Just rename the DAT file, leaving the OBS files with the same name and let the folder descend into a chaotically numbered mess, which is terrible for latter reorganisation and runs an easy risk of accidentally overwriting some other level's OBS file or deleting the wrong level's data.
2) Try to keep file numbers strictly correct, by first resaving level A to a different number, then open and save level B to A's old position, then go back to level A and save it yet again to B's old position. This is not really user friendly at all, but at least it keeps things in order.

Clearly, doing things manually will be awful no matter which way you cut it, so this leaves the program begging for another option, automating this mess with a proper level pack management system.

There's a couple of ways this can be done. My current thought is as follows:

  • The editor can load and save individual levels in the default format, but you can also create a level pack. When using a level pack, a folder is created to store level files in, and the level pack itself is just a simple text file that stores all of the organisational data.
  • Users are given an interface of 3 columns, one for each Tribe, with up to 30 slots, and players can load in individual levels or create new ones by clicking on an empty slot. You can assign each level done this way with an internal name to remember it by, and the level files themselves are stored using this name, they can all be tested from within the editor using an L2Suite-style temporary file moving and renaming so for now this is just for organisational purposes internally.
  • Levels can be easily reordered by swapping them in the interface within a tribe, or saved down under the traditional file names for individual release/archiving and/or deleted.
  • Finally, there's a publish button, which creates a folder with all of the level files in the proper named format so that they can be zipped up and distributed for others to play.

I feel like something like this is necessary for users to not go insane trying to make a level pack in the event anybody wants to. It sounds like a lot of work, but once the groundwork is done for handling an ini file for file paths for testing, and a way to test from the editor, you've already got the hard stuff out of the way.

Simon

#16
Scary design problem. :lix-scared: I love it.

I'd keep the data tree pristine, with the DAT always pointing to same-numbered OBS files as the DAT's filename suggests. Reason: The data is public, it has some documentation flying around on the net, and will be read by programs other than our own. It's okay if the user interface is nasty to deal with this.

Since the format is concocted, it sounds wise to view the entire level tree as one thing, and offer swap in the interface.

If you save levels with names in the filename, not numbers in the filename, this makes the tree incompatible with L3, therefore it's almost like defining your own format. If your level filenames contain level names, not numbers, how will you handle the (number fields that choose an OBS file) in the DAT? Leave arbitrary values in there until export?

But for loose levels, saving with name-in-filenames (not number in filenames) is probably required anyway. Will look forward to your result.

-- Simon

kieranmillar

Time for another small release before I work on some more substantial features that will take a bit of work. You can now edit the in-game camera's starting position. Press space to bring up a camera box and drag it to where you want the camera to begin.

v0.8 changelog:

  • Starting camera position can now be set.
  • Fixed bug introduced in v0.7 where tools and creatures moved when you resized the level.

kieranmillar

Here's an important milestone release, version 1.0!

Why is this release a milestone? This version marks the first time all relevant level features can be edited via the level editor. No more need for hex editors! Of course there's still more to do to make things even easier, but now you can fully edit the official levels with no need for any other tools.

The main addition for this release is a dialog with which to edit miscellaneous level properties, such as the release rate and time limit.

v1.0 changelog:

  • New menu available through which release rate, initial spawn delay, and time limit can be edited. The maximum time limit is 7 mins constrained by the game, but the editor will allow inputs up to 7:59, although will change this to 7:00 internally. Hotkey: p
  • More buttons at the bottom of the screen to rely less on hotkeys. The one gap remaining is reserved for a future test level feature.
  • Tooltips display when hovering over a button to explain what they do.
  • The numpad can now be used for number inputs and changing layers.
  • For developers only: New external library used: SDL_ttf.

kieranmillar

Version 1.1 now attached to the opening post.

This version adds area select. Clicking and dragging over an empty area draws a box, all pieces within that box when the mouse is released are selected. Modifiable with Ctrl to add pieces to the existing selection. Holding down Alt will force drawing a box over any other left-click action.

v1.1 changelog:

  • New area select feature to easily select multiple pieces at once.
  • Fixed bug on some systems where resizing the window caused all textures to be lost. - Thanks to Nessy for reporting and testing.
  • Developers only - CMake support added for easier setup. - Thanks to Simon for this.

kieranmillar

Version 1.2 now attached to the opening post!

There are substantial changes made to the way Lem3edit reads files in this release. Most importantly, Lem3edit no longer needs to be situated in the same location as the game data. You are highly encouraged to move the program out of the game data location and into its own location.

Loading levels via command line arguments also no longer works. You now directly browse to and open the level you need.

In reality these features are just to pave the way for the level pack organisation tool and easy testing, but there's been a lot of work in the backend made to get the program this far.

v1.2 changelog:

  • Lem3edit now asks for and stores the location of the game data upon first run (or first after upgrading to this version or newer).
  • Levels now loaded directly by browsing to them via a typical file browsing dialog. Command line arguments no longer work.
  • Improved readability of tooltips.

Simon

Doesn't build here (Linux, Arch, 64-bit) anymore despite passsing CMake configuration. It looks like the CMake files need to check for the newer dependencies.

#include <filesystem> is not found on Linux; the wise internet suggests #include <experimental/filesystem> and that works here. Nonetheless, I haven't researched further how standard this is, and what the standard way to write platform-independent code here would be.

Build instructions should explain the GUI library and the CMake files should check for that. Maybe ship the GUI library with the project source, but I'm not sure if that would be good style.

-- Simon

kieranmillar

Thanks for trying to compile Simon. I should have asked someone earlier to give it a try. I'll look closer at these tonight when I get home.

I don't believe the experimental filesystem include is right anymore as its no longer experimental and now an official part of the C++ spec, maybe your compiler is out of date? I followed the latest Visual Studio instructions to include the filesystem in a crods-platform manner but I'll look into it further.

The dependencies have not changed. Only nw inclusion is TinyFileDialogs and that is designed to drop right into the project as a .c and .h file pair so as far as I understood nothing more is needed? I'll double-check.

607

I've skimmed through these changelogs: very cool!

kieranmillar

#24
Version 1.3 now attached to the opening post!

Lem3edit now has a main menu. Instead of automatically trying to load a level, you will be presented with a menu from which you can create, load, copy, renumber or delete a level! Due to the nature of Lemmings 3's level format, it can potentially be non-obvious what files to delete or change, so now lem3edit can handle this for you.

On the main menu you will find some options struck-through. These are still to be implemented in a future update!

The new additional features on the main menu aren't really meant to be used that much, the upcoming level pack feature is intended to make organising your level pack much easier.

v1.3 changelog:

  • Implemented main menu (Note: unimplemented features are on the menu, struck-through and unselectable)
  • Closing a level now returns to the main menu instead of quitting the program.
  • Can now create new levels from scratch.
  • Can now copy or renumber levels.
  • Can now delete levels.
  • Can now save and load levels with arbitrary names for the .DAT file. The .OBS file names are still enforced per the level file specification.
  • When inputting numbers you can now use the Delete key instead of just backspace to remove digits.
  • Proper checking of L3's data files on program start and after first-time setup instead of just accepting that you pointed to some exe file and hoping it's the right one

kieranmillar

Simon, when you have a spare moment I would appreciate it if you could try re-building this and see if it still works.

I haven't had a chance to look at CMake yet so it might have to be manual. I did look at other projects though that didn't have CMake and they all seem to expect you to store the SDL files separately then link them, so I think include SDL with the project isn't a good idea. It's a pretty common library. Perhaps CMake is overkill for this project? Not sure.

kieranmillar

I figured out last night why the build instructions don't work any more. Tinyfiledialogs adds files with the extensions .c and .h while every other file has .cpp and .hpp.

Simon

Sorry for not catching your questions earlier. >_>

Now the build aborts in with
Spoiler
In file included from /home/simon/c/notown/lem3edit/src/Main Menu/mainmenu.cpp:25:0:
/home/simon/c/notown/lem3edit/src/Main Menu/mainmenu.hpp:96:7: error: extra qualification 'Mainmenu::' on member 'typedNumber' [-fpermissive]
  void Mainmenu::typedNumber(const unsigned int value);
       ^~~~~~~~

Commit f31adab. This sort of dumb warning differences can happen across compilers. No time now but maybe later today.

-- Simon

ccexplore

#28
We need a spoiler for that? :o ??? :P

In file included from /home/simon/c/notown/lem3edit/src/Main Menu/mainmenu.cpp:25:0:
/home/simon/c/notown/lem3edit/src/Main Menu/mainmenu.hpp:96:7: error: extra qualification 'Mainmenu::' on member 'typedNumber' [-fpermissive]
  void Mainmenu::typedNumber(const unsigned int value);
       ^~~~~~~~


This seems legit from what I can remember about C++.  You can do this ("A"):

// this is typically in a header file
class Mainmenu {
    void typedNumber(const unsigned int value); // just declare the method inside the class definition, no implementation
};


Or this ("B"):

// typically in a .cpp file, outside of the class definition
void Mainmenu::typedNumber(const unsigned int value) { /* implementation code */ }


But you can't mix B's syntax (specifically qualifying the method name with the class name) in A's.  At the very least it's almost never done, if not outright disallowed by the grammar of the language.  Removing the extraneous "Mainmenu::" on the line in the header file pointed out by the error should fix that error.

kieranmillar

Haha whoops what a dumb mistake. Visual Studio accepted that so I didnt even realise Id done it. Thats 'll be because I wrote the function in the cpp file first instead of initially doing the header first, so a copy paste fail. I didnt even reslise it'd be accepted as valid syntax.