Some quick background: It's no secret that old content tends to become unplayable on the next major release that comes around, and I have some interest in seeing old levels made playable in the current engine, if only to make it easier to appreciate the past works of previous level artists in our current environment. As a community, we place strong value in the autonomy and creative rights of the original content creators, and to modify and republish an author's work without consent -- even if strictly for conservation/compatibility purposes -- is considered a breach of those rights unless the work is expressedly marked as common use.
I believe there may be an alternative solution which is more in line with our ethics, and this would be to create ingame level "translators", which read level data and automatically convert its properties to match the right format. This might be unfeasible to maintain at the hard code level as it would mean setting up translation tables for every type of SRB2 level format created in the past; however, with lua hooks, all of the heavy lifting could potentially be left up to the community, and this would have the benefit of improving backwards compatibility while also having the potential to sharply reduce the prevalence of bootleg ports.
What's changed between versions
How lua could resolve these discrepancies
Current restrictions preventing this
Potential solutions
Other limitations
Potential Advantages
I'm mostly curious if there are any technical limitations I might be overlooking here. But maybe this is also a good window to discuss creative rights as we've currently defined them; this idea mostly came into fruition due to some internal conversation I had with others on the team in regards to what can be done with the intellectual property of someone's wad file. If an external file renders an older addon playable without actually modifying the file itself, then it may work to the benefit of multiple parties.
I believe there may be an alternative solution which is more in line with our ethics, and this would be to create ingame level "translators", which read level data and automatically convert its properties to match the right format. This might be unfeasible to maintain at the hard code level as it would mean setting up translation tables for every type of SRB2 level format created in the past; however, with lua hooks, all of the heavy lifting could potentially be left up to the community, and this would have the benefit of improving backwards compatibility while also having the potential to sharply reduce the prevalence of bootleg ports.
What's changed between versions
- Some level header information has become outdated. MusicSlot has been replaced with Music, and many skies and music track names have been internally restructured.
- Thing type numbers have been reorganized. Additional flags have been added, and this descrepancy causes mapthing options and height values to be misread.
- Sector and linedef specials have been reorganized.
- Flats and textures have been reorganized.
How lua could resolve these discrepancies
- Headers could be read as the level is loading, and use the presence of outdated header items such as "MusicSlot" to automatically identify if a level needs to be converted. Alternatively, a console command or lua function/variable can be used to define which levels need to be converted.
- Header-defined skies and bgm entries can be modified on level load using lua-defined lookup tables.
- Thing type numbers can be redefined on level load using lua-defined look-up tables. Flags and height values can be automatically adjusted to reflect discrepancies between 1.x and 2.x.
Current restrictions preventing this
- The only hooks present for handling items on level load are MapLoad and MapThingSpawn. Both of these hooks are executed after mapthings have spawned their mobjs and linedef/sector specials have been activated.
- There is no lua hook available for reading level header data prior to execution
- Linedef specials are read-only variables in lua due to stability issues that would arise from editing them during level runtime.
- Mapheader data is set to read-only, likely due to implications that would result from them being modified during runtime.
Potential solutions
- Create a MapRead hook which runs after map data has been read, but before mapthings have had their objects spawned or their sector/linedef specials executed. This may also be a point where mapheader data can be allowed a writable state from within lua.
- Conditionally allow linedef specials and mapheader data to be read+writable, but only from within the MapRead hook.
Other limitations
- Certain outdated addons may contain assets (e.g. music, skies) that are placed in previous vanilla asset locations; unless explicit exceptions are made (perhaps via a console variable?) a translation script for these asset types will result in the intended custom assets being incorrectly translated.
- Textures, flats, and sprites contained in the old file will still suffer from discolorations due to palette differences between current and previous SRB2 versions. I don't know of any solution that wouldn't involve somehow reading which graphical assets have been replaced by X file and flipping its colors using X algorithm mapped to X custom palette.
Potential Advantages
- A level translator system with customizable lookup tables could allow a large number of levels (particularly OLDC map packs) to become accessible without tampering with the integrity of the original files.
- This system could extend beyond the translation of SRB2 maps; for example, what would happen if a scripter created lookup tables designed to translate levels made for the original Doom?
- While it's already possible to change some sector properties in lua, the creation of a MapRead hook and the ability to read+write header and linedef properties before level load has powerful implications on the extent to which innovative game mechanics would be possible through lua; for example, it would be easier to emulate Sonic CD's time travel system by modifying skies, linedef specials, and thing spawns without the help of any explicit scripting / execution instructions from the level itself.
I'm mostly curious if there are any technical limitations I might be overlooking here. But maybe this is also a good window to discuss creative rights as we've currently defined them; this idea mostly came into fruition due to some internal conversation I had with others on the team in regards to what can be done with the intellectual property of someone's wad file. If an external file renders an older addon playable without actually modifying the file itself, then it may work to the benefit of multiple parties.