The Level Objects of one Level are all stored one after another in memory.
Levels have different Object Sets, like Plains, Hilly or Fortress.
The NES can only hold some parts of the ROM in memory at a time.
When playing a Level, the part of the ROM where this level resides needs to be loaded into memory.
This leads to Levels with same or similar Object Sets being all stored in the same part (PRG Bank) of the ROM.
There is no code or other data anywhere between the Levels inside a PRG Bank.
The end of the area Level data can be in is the end of the PRG Bank.
The beginning of the area the Level data can be in is not defined and not stored in the ROM.
The beginning can only be asserted after finding every accessible Level and declaring the earliest found per PRG Bank as being the beginning. There can be more unused space before it.
There can be space in between Levels, that is either unused or houses Levels not accessible from within the game (from the overworld or jumps inside other levels).
Problems
Existing Workflows and raw addresses
From what I've seen, some people just replace the vanilla levels in their hacks, keeping within the original level sizes, meaning they don't move or expand Levels at all.
I would presume more experienced hackers would do some reordering of levels themselves, by saving levels at specific level addresses, which they probably keep track of outside of the editor. Which would allow them to go beyond the level bounds in a controlled manner and only overwrite data they no longer need.
And then there might be super pros, that just start from scratch, not even caring about the original Levels, who knows.
So it seems, that for anything but the most basic "replace stuff" ROM hacking, access to the "raw level addresses" was necessary. Taking them away or invalidating them in any other way, would only be an option if the solution that makes this necessary works perfectly and does not take away functionality (in general I wouldn't want to hide too much ROM information).
Finding Level Data Limits
To find the areas in the ROM, that can hold Level Data, without running the risk of overwriting code, we basically have to find and parse every Level in the ROM and assume, that the space those take up (from the first level in a bank to the end of the bank) is all we can get.
We have to parse Levels at least up to the header, because, if we want to change the position of a level in the ROM, we have to also change every place in the ROM that points to that level, be it level headers or level pointers on overworlds. That means, we cannot have any damaged Levels caused by overwriting them halfway. Because if we follow a level header to a broken level, we read garbage for a while.
That seems to imply, that we have to take full control, not allowing any manual saving levels to where ever, because that would almost inevitably lead to such problems, taking away access to "raw level addresses".
But a solution will need to be found, since there could always be existing ROMs with level headers pointing to broken levels.
Level Accessibility
Since we cannot just take a PRG Bank and magically figure out where Levels are, we have to find them the way the Game finds them. By going into a level from the world map and then through the level header again and again, until all "accessible" levels have been found (plus the coinship and other special levels).
Putting aside any broken levels we might encounter, this is already in the code base. The problem with that, however, is that any data between the first level of a bank and the end of the bank, that is not part of a level we found with the method above, will be deemed "empty". That includes any levels users might have build beforehand, but which they have not yet assigned to a level pointer, or chose a level to jump from.
That means the level is not accessible and the first time the ROM is loaded and the user would activate the "level management feature" or whatever it would be called, this level would effectively be deleted.
This is not great and also not easily communicated to the user. Without a lengthy explanation (in the vain of this issue here) it might not be clear why that level was deleted, although you might also argue that any user who writes down level addresses is advanced enough to get it.
As it is now in the nightly version, the Level Viewer takes about 40sec to go through the whole ROM and find all the vanilla levels. This information could then be used to fill a level list similar to how the Vanilla levels are shown in the current Level Selector. this would help the visibility of Bonus Levels, since atm, you can either select a Vanilla Level or a Level accessible through the world map, anything else - bonus, generic exit, coinship etc. - is not immediately accessible or not at all, even though we have the information.
It is not quite clear to me, how we could make Bonus Levels more visible.
So it seems that the feature of dynamic level sizes is entwined with taking the control of Level Addresses away from the user and necessitates a better LevelSelector to make world specific levels and bonus levels more accessible, so that it becomes clear, that they must be saved in order to survive.
This is a massive undertaking in terms of UX/UI and I would need some feedback, since I don't have enough user experience with the editor myself.
Some background info
Problems
Existing Workflows and raw addresses
From what I've seen, some people just replace the vanilla levels in their hacks, keeping within the original level sizes, meaning they don't move or expand Levels at all.
I would presume more experienced hackers would do some reordering of levels themselves, by saving levels at specific level addresses, which they probably keep track of outside of the editor. Which would allow them to go beyond the level bounds in a controlled manner and only overwrite data they no longer need.
And then there might be super pros, that just start from scratch, not even caring about the original Levels, who knows.
So it seems, that for anything but the most basic "replace stuff" ROM hacking, access to the "raw level addresses" was necessary. Taking them away or invalidating them in any other way, would only be an option if the solution that makes this necessary works perfectly and does not take away functionality (in general I wouldn't want to hide too much ROM information).
Finding Level Data Limits
To find the areas in the ROM, that can hold Level Data, without running the risk of overwriting code, we basically have to find and parse every Level in the ROM and assume, that the space those take up (from the first level in a bank to the end of the bank) is all we can get.
We have to parse Levels at least up to the header, because, if we want to change the position of a level in the ROM, we have to also change every place in the ROM that points to that level, be it level headers or level pointers on overworlds. That means, we cannot have any damaged Levels caused by overwriting them halfway. Because if we follow a level header to a broken level, we read garbage for a while.
That seems to imply, that we have to take full control, not allowing any manual saving levels to where ever, because that would almost inevitably lead to such problems, taking away access to "raw level addresses".
But a solution will need to be found, since there could always be existing ROMs with level headers pointing to broken levels.
Level Accessibility
Since we cannot just take a PRG Bank and magically figure out where Levels are, we have to find them the way the Game finds them. By going into a level from the world map and then through the level header again and again, until all "accessible" levels have been found (plus the coinship and other special levels).
Putting aside any broken levels we might encounter, this is already in the code base. The problem with that, however, is that any data between the first level of a bank and the end of the bank, that is not part of a level we found with the method above, will be deemed "empty". That includes any levels users might have build beforehand, but which they have not yet assigned to a level pointer, or chose a level to jump from.
That means the level is not accessible and the first time the ROM is loaded and the user would activate the "level management feature" or whatever it would be called, this level would effectively be deleted.
This is not great and also not easily communicated to the user. Without a lengthy explanation (in the vain of this issue here) it might not be clear why that level was deleted, although you might also argue that any user who writes down level addresses is advanced enough to get it.
As it is now in the nightly version, the Level Viewer takes about 40sec to go through the whole ROM and find all the vanilla levels. This information could then be used to fill a level list similar to how the Vanilla levels are shown in the current Level Selector. this would help the visibility of Bonus Levels, since atm, you can either select a Vanilla Level or a Level accessible through the world map, anything else - bonus, generic exit, coinship etc. - is not immediately accessible or not at all, even though we have the information.
It is not quite clear to me, how we could make Bonus Levels more visible.
So it seems that the feature of dynamic level sizes is entwined with taking the control of Level Addresses away from the user and necessitates a better LevelSelector to make world specific levels and bonus levels more accessible, so that it becomes clear, that they must be saved in order to survive.
This is a massive undertaking in terms of UX/UI and I would need some feedback, since I don't have enough user experience with the editor myself.