Looking for suggestions on how to approach debugging in 6M62

Hi all!

I’m the lead dev of a very large project started in 2011 in 6G60, I won’t go into specific details here as it’s extremely NSFW and don’t want to break any rules or ruffle any feathers.

Anyway we recently started having huge problems with 6G60 where the compiler was halting in ‘abject failure’ due to how large and complex the code was (we know it was this because we got to several points where deleting any single function would allow the code to compile, and adding any single empty function would cause it to fail).

So we’ve been trying to upgrade to 6M62 in the hopes that this complexity limit is different, or at the very least we can make a bug report to the main website explaining our issue. Thanks to the work of many people including Dannii Willis, there are now enough extensions compatible with 6M62 that this seemed realistic.

So, I began migrating one of the simplest versions of the code over - the ‘no graphics’ version which doesn’t have any of the complex code for rendering graphics with Glimmr and Flexible Windows and which definitely compiled with ease on 6G60. But already we’ve hit a roadblock - after fixing all the issues that the new 6M62 compiler wasn’t happy with, it’s now just halting in failure with a code 11 and a complicated stack trace.

Since this is a huge codebase with over a million words being migrated from 6G60, it’s not possible to just ‘revert the last change’ and be aware of what is causing the problem. Instead we need to somehow hunt down whatever the thing is that’s causing the compiler to break (or more likely, things) and the only way I can think of to do this is to break down the source code bit by bit until the compiler stops breaking and then build it back up bit by bit afterwards. However this will take weeks if not months and during this time we’re going to lose a lot of income which will significantly affect a number of people’s livelihoods if we can’t manage to find the solution faster.

So I’ve come here to ask: does anyone have a better suggestion of how to go about hunting this issue down? Any wild ideas about what sort of thing we should be looking for? Any clever methods to go about cutting spaghetti code into smaller chunks that can still compile? Currently I’m thinking of trying to write a script that will take every variable and object definition, and take every procedure and function definition and just return ‘nothing’, and lose everything else. And then slowly build it back up from there. I think it will take forever though.

For anyone that’s interested enough to listen, here are the other details I can think of that might be relevant:

I’ve noticed that there’s one sort of issue causing a code 11 that’s already known: inform7.com/mantis/view.php?id=1837 but I think if we suffered from a similar mistake, then it wouldn’t have successfully compiled in 6G60.

The compiler creates a Problems.html file that grows to nearly 250MB before it finally halts. Opening that index file in a browser shows a seemingly infinite repeating nesting of reports:

i.imgur.com/t9gUTM1.png

When using 6G60, we had to use some very large limit overrides, for example

Use MAX_NUM_STATIC_STRINGS of 300000.

Removing these from the source code for 6M62 doesn’t change anything about this compiler error. So I guess that suggests that it’s crashing and burning before any checks are being made against these limits.

Stack Trace:

[spoiler]Process failed, stack backtrace:
Exception code 0xc00000fd at PC=0x76897c97
msvcrt!_unlock()
msvcrt!_write()
msvcrt!_flsbuf()
msvcrt!putc()
ni!Streams__putc() at inform7\Chapter 2\Streams.w line 558
ni!Streams__putc() at inform7\Chapter 2\Streams.w line 599
ni!Streams__printf() at inform7\Chapter 2\Streams.w line 445
ni!Problems__Issue__issue_problems_banner() at inform7\Chapter 6\Problems, Level 3.w line 827
ni!HTML__html_outcome_image() at inform7\Chapter 4\HTML Files.w line 229
ni!Problems__show_problem_location() at inform7\Chapter 6\Problems, Level 2.w line 83
ni!Problems__issue_problem_begin() at inform7\Chapter 6\Problems, Level 2.w line 315
ni!Problems__Issue__internal_error_fn() at inform7\Chapter 6\Problems, Level 3.w line 57
ni!Memory__allocate_another_block() at inform7\Chapter 2\Memory.w line 388
ni!Memory__allocate() at inform7\Chapter 2\Memory.w line 540
ni!allocate_parse_node_annotation_array() at inform7\Chapter 2\Memory.w line 835
ni!allocate_parse_node_annotation() at inform7\Chapter 2\Memory.w line 835
ni!ParseTree__pna_new() at inform7\Chapter 13\Parse Tree.w line 760
ni!ParseTree__pn_annotate_pointer() at inform7\Chapter 13\Parse Tree.w line 843
ni!ParseTree__set_problem_falls_under() at inform7\Chapter 13\Parse Tree.w line 912
ni!Problems__visit_for_headings() at inform7\Chapter 6\Problems, Level 2.w line 51
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1555
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1551
ni!Problems__find_headings_at() at inform7\Chapter 6\Problems, Level 2.w line 35
ni!Problems__show_problem_location() at inform7\Chapter 6\Problems, Level 2.w line 90
ni!Problems__issue_problem_begin() at inform7\Chapter 6\Problems, Level 2.w line 315
ni!Problems__Issue__internal_error_fn() at inform7\Chapter 6\Problems, Level 3.w line 57
ni!Memory__allocate_another_block() at inform7\Chapter 2\Memory.w line 388
ni!Memory__allocate() at inform7\Chapter 2\Memory.w line 540
ni!allocate_parse_node_annotation_array() at inform7\Chapter 2\Memory.w line 835
ni!allocate_parse_node_annotation() at inform7\Chapter 2\Memory.w line 835
ni!ParseTree__pna_new() at inform7\Chapter 13\Parse Tree.w line 760
ni!ParseTree__pn_annotate_pointer() at inform7\Chapter 13\Parse Tree.w line 843
ni!ParseTree__set_problem_falls_under() at inform7\Chapter 13\Parse Tree.w line 912
ni!Problems__visit_for_headings() at inform7\Chapter 6\Problems, Level 2.w line 51
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1555
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1551
ni!Problems__find_headings_at() at inform7\Chapter 6\Problems, Level 2.w line 35
ni!Problems__show_problem_location() at inform7\Chapter 6\Problems, Level 2.w line 90
ni!Problems__issue_problem_begin() at inform7\Chapter 6\Problems, Level 2.w line 315
ni!Problems__Issue__internal_error_fn() at inform7\Chapter 6\Problems, Level 3.w line 57
ni!Memory__allocate_another_block() at inform7\Chapter 2\Memory.w line 388
ni!Memory__allocate() at inform7\Chapter 2\Memory.w line 540
ni!allocate_parse_node_annotation_array() at inform7\Chapter 2\Memory.w line 835
ni!allocate_parse_node_annotation() at inform7\Chapter 2\Memory.w line 835
ni!ParseTree__pna_new() at inform7\Chapter 13\Parse Tree.w line 760
ni!ParseTree__pn_annotate_pointer() at inform7\Chapter 13\Parse Tree.w line 843
ni!ParseTree__set_problem_falls_under() at inform7\Chapter 13\Parse Tree.w line 912
ni!Problems__visit_for_headings() at inform7\Chapter 6\Problems, Level 2.w line 51
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1555
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1551
ni!Problems__find_headings_at() at inform7\Chapter 6\Problems, Level 2.w line 35
ni!Problems__show_problem_location() at inform7\Chapter 6\Problems, Level 2.w line 90
ni!Problems__issue_problem_begin() at inform7\Chapter 6\Problems, Level 2.w line 315
ni!Problems__Issue__internal_error_fn() at inform7\Chapter 6\Problems, Level 3.w line 57
ni!Memory__allocate_another_block() at inform7\Chapter 2\Memory.w line 388
ni!Memory__allocate() at inform7\Chapter 2\Memory.w line 540
ni!allocate_parse_node_annotation_array() at inform7\Chapter 2\Memory.w line 835

SNIP - THE ABOVE 18 LINES REPEAT ABOUT 1000 TIMES

ni!ParseTree__pna_new() at inform7\Chapter 13\Parse Tree.w line 760
ni!ParseTree__pn_annotate_pointer() at inform7\Chapter 13\Parse Tree.w line 843
ni!ParseTree__set_problem_falls_under() at inform7\Chapter 13\Parse Tree.w line 912
ni!Problems__visit_for_headings() at inform7\Chapter 6\Problems, Level 2.w line 51
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1555
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1551
ni!Problems__find_headings_at() at inform7\Chapter 6\Problems, Level 2.w line 35
ni!Problems__show_problem_location() at inform7\Chapter 6\Problems, Level 2.w line 90
ni!Problems__issue_problem_begin() at inform7\Chapter 6\Problems, Level 2.w line 315
ni!Problems__Issue__internal_error_fn() at inform7\Chapter 6\Problems, Level 3.w line 57
ni!Memory__allocate_another_block() at inform7\Chapter 2\Memory.w line 388
ni!Memory__allocate() at inform7\Chapter 2\Memory.w line 540
ni!allocate_parse_node() at inform7\Chapter 2\Memory.w line 767
ni!ParseTree__new() at inform7\Chapter 13\Parse Tree.w line 667
ni!Invocations__new() at inform7\Chapter 31\Invocations.w line 146
ni!Phrases__Parser__parse_against() at inform7\Chapter 31\Parse Invocations.w line 253
ni!SParser__add_ilist() at inform7\Chapter 16\Conditions and Phrases.w line 323
ni!s_text_substitution_NTMR() at inform7\Chapter 16\Conditions and Phrases.w line 253
ni!Preform__parse_nt_against_word_range() at inform7\Chapter 7\Preform.w line 1738
ni!Preform__parse_nt_against_word_range() at inform7\Chapter 7\Preform.w line 2103
ni!Preform__parse_nt_against_word_range() at inform7\Chapter 7\Preform.w line 2103
ni!SParser__parse_phrase_inner() at inform7\Chapter 16\Architecture of the S-Parser.w line 304
ni!SParser__parse_say_term() at inform7\Chapter 16\Architecture of the S-Parser.w line 297
ni!Routines__Compile__code_line() at inform7\Chapter 31\Compile Phrases.w line 199
ni!Routines__Compile__code_block() at inform7\Chapter 31\Compile Phrases.w line 154
ni!Routines__Compile__code_line() at inform7\Chapter 31\Compile Phrases.w line 367
ni!Routines__Compile__code_block() at inform7\Chapter 31\Compile Phrases.w line 154
ni!Routines__Compile__routine() at inform7\Chapter 31\Compile Phrases.w line 99
ni!Phrases__compile() at inform7\Chapter 28\Phrases.w line 378
ni!Routines__ToPhrases__compilation_coroutine() at inform7\Chapter 28\To Phrases.w line 263
ni!Phrases__Manager__compile_as_needed() at inform7\Chapter 28\Construction Sequence.w line 503
ni!TemplateFiles__interpret() at inform7\Chapter 38\I6 Template Interpreter.w line 789
ni!TemplateFiles__interpret() at inform7\Chapter 38\I6 Template Interpreter.w line 460
ni!Main__core_inform_main() at inform7\Chapter 38\Main Routine.w line 43
ni!main() at inform7\Chapter 38\Main Routine.w line 15
ni!__tmainCRTStartup() at \usr\src\debug\mingw64-i686-runtime-4.0.6-1\crt\crtexe.c line 334
KERNEL32!BaseThreadInitThunk()
ntdll!RtlValidSecurityDescriptor()
ntdll!RtlValidSecurityDescriptor()

Compiler finished with code 11[/spoiler]

Bug 1837 was not in 6G60. So this is still something to watch out for.

However, this doesn’t look like 1837. It looks a lot like inform7.com/mantis/view.php?id=1973 (and maybe it’s the same game?)

Similarity: The stack trace shows Memory__allocate_another_block, followed by Problems__Issue__internal_error_fn, followed by a crash when trying to display the error message.

If it’s the same root cause, then you’re running into a hard limit in the I7 compiler, as you were in 6G60. There is nothing you can do about this; it just can’t compile a game of this size.

Which means you may just have to go the Zork to Zork I II III route (when it was migrated from mainframes to micros). Break the game up at reasonable points into several games.

It’s really a bummer when this happens. The method I’ve used to narrow down a bug that causes an Inform [SHRUG?] error is to comment out sections of code and try running it to see if it works or gives the same error. Try commenting out half of your code (surround the ENTIRE section with [ ]) and try to run and see if the errors change or at least make reasonable sense without giving you the abject failure error. (Here is where it helps a lot to have your source organized into headers.) If running without half the code still gives you the big error, that narrows down where it is. Divide and conquer the remaining code with the error in half again and repeat to see if you can whittle down where it’s happening.

Theoretically, it’s really hard to make a game big enough to choke the compiler on modern computers. I’m sure it happens in weird circumstances though - using up all the memory and such.

Huh, I thought this problem in Inform had been fixed, but apparently not?

Basically there’s an internal constant called MAX_BLOCKS_ALLOWED which defaults to 10,000. When Inform tries to allocate more memory blocks than this, a watchdog steps in to stop it, and report an error. (And that error report then ends up trying to allocate more memory, which causes the same error, and so on and so on until it actually crashes. This is what causes the nonsensical nested Problems.html file.)

This constant is currently hardcoded and cannot be changed. But there’s an open issue to make it settable, like the other compiler limits.

So at the moment, the only way to get past this limitation is to get one of the few people with the compiler’s source code (Graham or DavidK) to release a modified version of the compiler with this limit raised. This issue was first raised back in 2016 and hasn’t been touched in nearly two years now, so unfortunately it’s unlikely that they’ll do this.

Thanks guys. I’ve just spoken with the creator of that bug report and he was given a version of ni.exe which uses 64 bits and apparently that was a big enough difference to solve his problem, at least for the last 2 years. However, it has not worked for me. It just gives me the same error with a slightly different stack trace:

[spoiler]Process failed, stack backtrace:
Exception code 0xc00000fd at PC=0x76897c97
msvcrt!_unlock()
msvcrt!_write()
msvcrt!_flsbuf()
msvcrt!putc()
ni!Streams__putc() at inform7\Chapter 2\Streams.w line 558
ni!Streams__putc() at inform7\Chapter 2\Streams.w line 599
ni!Streams__printf() at inform7\Chapter 2\Streams.w line 445
ni!Problems__Issue__issue_problems_banner() at inform7\Chapter 6\Problems, Level 3.w line 827
ni!HTML__html_outcome_image() at inform7\Chapter 4\HTML Files.w line 229
ni!Problems__show_problem_location() at inform7\Chapter 6\Problems, Level 2.w line 83
ni!Problems__issue_problem_begin() at inform7\Chapter 6\Problems, Level 2.w line 315
ni!Problems__Issue__internal_error_fn() at inform7\Chapter 6\Problems, Level 3.w line 57
ni!Memory__allocate_another_block() at inform7\Chapter 2\Memory.w line 388
ni!Memory__allocate() at inform7\Chapter 2\Memory.w line 540
ni!allocate_parse_node_annotation_array() at inform7\Chapter 2\Memory.w line 835
ni!allocate_parse_node_annotation() at inform7\Chapter 2\Memory.w line 835
ni!ParseTree__pna_new() at inform7\Chapter 13\Parse Tree.w line 760
ni!ParseTree__pn_annotate_pointer() at inform7\Chapter 13\Parse Tree.w line 843
ni!ParseTree__set_problem_falls_under() at inform7\Chapter 13\Parse Tree.w line 912
ni!Problems__visit_for_headings() at inform7\Chapter 6\Problems, Level 2.w line 51
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1555
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1551
ni!Problems__find_headings_at() at inform7\Chapter 6\Problems, Level 2.w line 35
ni!Problems__show_problem_location() at inform7\Chapter 6\Problems, Level 2.w line 90
ni!Problems__issue_problem_begin() at inform7\Chapter 6\Problems, Level 2.w line 315
ni!Problems__Issue__internal_error_fn() at inform7\Chapter 6\Problems, Level 3.w line 57
ni!Memory__allocate_another_block() at inform7\Chapter 2\Memory.w line 388
ni!Memory__allocate() at inform7\Chapter 2\Memory.w line 540
ni!allocate_parse_node_annotation_array() at inform7\Chapter 2\Memory.w line 835
ni!allocate_parse_node_annotation() at inform7\Chapter 2\Memory.w line 835
ni!ParseTree__pna_new() at inform7\Chapter 13\Parse Tree.w line 760
ni!ParseTree__pn_annotate_pointer() at inform7\Chapter 13\Parse Tree.w line 843
ni!ParseTree__set_problem_falls_under() at inform7\Chapter 13\Parse Tree.w line 912
ni!Problems__visit_for_headings() at inform7\Chapter 6\Problems, Level 2.w line 51

LOOPS 1000 TIMES

ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1555
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_from_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1558
ni!ParseTree__traverse_ppn_nocs() at inform7\Chapter 13\Parse Tree.w line 1551
ni!Problems__find_headings_at() at inform7\Chapter 6\Problems, Level 2.w line 35
ni!Problems__show_problem_location() at inform7\Chapter 6\Problems, Level 2.w line 90
ni!Problems__issue_problem_begin() at inform7\Chapter 6\Problems, Level 2.w line 315
ni!Problems__Issue__internal_error_fn() at inform7\Chapter 6\Problems, Level 3.w line 57
ni!Memory__allocate_another_block() at inform7\Chapter 2\Memory.w line 388
ni!Memory__allocate() at inform7\Chapter 2\Memory.w line 540
ni!allocate_parse_node_annotation_array() at inform7\Chapter 2\Memory.w line 835
ni!allocate_parse_node_annotation() at inform7\Chapter 2\Memory.w line 835
ni!ParseTree__pna_new() at inform7\Chapter 13\Parse Tree.w line 760
ni!ParseTree__annotate_int() at inform7\Chapter 13\Parse Tree.w line 824
ni!Dash__clear_flags() at inform7\Chapter 20\Dash.w line 3432
ni!Dash__typecheck_recursive_inner() at inform7\Chapter 20\Dash.w line 858
ni!Dash__typecheck_recursive() at inform7\Chapter 20\Dash.w line 253
ni!Dash__typecheck_recursive_inner() at inform7\Chapter 20\Dash.w line 818
ni!Dash__typecheck_recursive() at inform7\Chapter 20\Dash.w line 253
ni!Dash__funnel_to_level_2() at inform7\Chapter 20\Dash.w line 216
ni!Dash__check_invl() at inform7\Chapter 20\Dash.w line 206
ni!Routines__Compile__line() at inform7\Chapter 31\Compile Phrases.w line 550
ni!Routines__Compile__code_line() at inform7\Chapter 31\Compile Phrases.w line 231
ni!Routines__Compile__code_block() at inform7\Chapter 31\Compile Phrases.w line 154
ni!Routines__Compile__code_line() at inform7\Chapter 31\Compile Phrases.w line 483
ni!Routines__Compile__code_block() at inform7\Chapter 31\Compile Phrases.w line 154
ni!Routines__Compile__code_line() at inform7\Chapter 31\Compile Phrases.w line 367
ni!Routines__Compile__code_block() at inform7\Chapter 31\Compile Phrases.w line 154
ni!Routines__Compile__code_line() at inform7\Chapter 31\Compile Phrases.w line 367
ni!Routines__Compile__code_block() at inform7\Chapter 31\Compile Phrases.w line 154
ni!Routines__Compile__routine() at inform7\Chapter 31\Compile Phrases.w line 99
ni!Phrases__compile() at inform7\Chapter 28\Phrases.w line 378
ni!Routines__ToPhrases__compilation_coroutine() at inform7\Chapter 28\To Phrases.w line 263
ni!Phrases__Manager__compile_as_needed() at inform7\Chapter 28\Construction Sequence.w line 503
ni!TemplateFiles__interpret() at inform7\Chapter 38\I6 Template Interpreter.w line 789
ni!TemplateFiles__interpret() at inform7\Chapter 38\I6 Template Interpreter.w line 460
ni!Main__core_inform_main() at inform7\Chapter 38\Main Routine.w line 43
ni!main() at inform7\Chapter 38\Main Routine.w line 15
ni!__tmainCRTStartup() at \usr\src\debug\mingw64-i686-runtime-4.0.6-1\crt\crtexe.c line 334
KERNEL32!BaseThreadInitThunk()
ntdll!RtlValidSecurityDescriptor()
ntdll!RtlValidSecurityDescriptor()

Compiler finished with code 11[/spoiler]

I am beginning to suspect that my game is even bigger than nuku’s and I’ve only survived this long because 6G60 was actually better at handling complexity without spilling over the limit than 6M62.

Assuming there is a culprit that can be found and fixed, as opposed to the complexity limit being the issue, this is what I need to do but I can’t just comment out half my code, it’s way more complicated than that. Commenting out half my code just gives me 10000 errors where it’s confused about variables, objects and rules that no longer exist.

What I was trying to say is that in 6G60, Bug 1837 would result in a failed compile with a sensible error message, rather than a successful compile.

There’s nothing special about that test build of “ni.exe” I did for them: the “ni.exe” in the latest builds of Windows Inform 7 at inform7.com (and ifarchive.org) have those changes. There are two points to this:

  1. A setting in the Inform 7 source needed to be raised, but perhaps it needed to be raised a bit further.
  2. Currently “ni.exe” is built as a 32-bit executable, but with a special flag set in its header. This means that on a 32-bit Windows OS it gets 2 gigabytes of address space, but on a 64-bit Windows OS it gets 3 gigabytes. So you definitely need to be using 64-bit Windows, but these days nearly everyone does that.

Going forward we’ll move to a fully 64-bit tool chain. But for the moment if you put the source for your game somewhere where I can get at it I will have a look and see if the internal limit is being hit, and if it can be just raised a bit.

Oh thank you so much for having a look. I’ll PM you the link to the repo. I’m concerned that it is quite possibly an issue somewhere in the code, and we are all barking up the wrong tree, but I am grateful for your advice in any case.