Re: Linux port of reconstruction, now in C/C++
Posted: Wed Apr 21, 2021 8:24 pm
My own recommendation is that any out of bounds elements should be considered undefined behaviour, and should not be used in any world file (except for testing purposes) (you may emulate this if you wish, although in my own opinion, I consider it unnecessary and probably undesirable). If you require elements with specific attributes (visible in dark, pushable, etc) and/or behaviour, consider using the FreeZZT format, which allows these things to be customized. Larger buffer sizes should probably be implemented regardless of the world format, since that does not affect compatibility with world files that do not rely on undefined behaviour. If you do not require the features of FreeZZT or other variants, then you should use the standard ZZT format without any extensions. (If you wish to emulate WeaveZZT or other variants, then you will need some way to identify it as a WeaveZZT world file, and as far as I know it doesn't include such a thing (one possibility is to use a command-line argument, or perhaps a file with a .VAR extension to denote the variant to emulate). If you wish to emulate FreeZZT and/or SuperZZT, then it can be easily detected by the contents of the world file (and, in the case of SuperZZT, also the file name), so no other mechanism is needed.) Maybe it is difficult sometimes to determine which behaviour is "undefined behaviour". My own opinion is, anything that depends on accessing memory that is not part of the correct part of memory in order to make decisions (not simply display) is "undefined", although other parts of the same structure or array are not considered to be "not part of the same part of memory" (even if the index is unexpected), so they are still considered to be defined. Since the current number of gems and keys are part of the same structure (TWorldInfo), this is not considered to be undefined behaviour (it is defined), and it must be emulated. Use of elements beyond MAX_ELEMENT is undefined behaviour since it involves access to memory outside of the array that it is trying to access (ElementDefs) in order to make decisions. (Executing any native code that isn't one of the procedures in the game engine (including the run time library as part of the game engine for this purpose), or trying to use arbitrary data (including data that comes from outside of the game engine) as a subroutine address or memory address, is also undefined behaviour.) Runtime errors (other than I/O errors) may also be considered as undefined behaviour (for example, this includes division by zero).