Vielleicht kann ich das "Geheimnis" ein wenig lüften, ich muss aber ein wenig länger ausholen. Ich versuche es mal auf eine weniger technische Art zu erklären.
Die einfache Erklärung
Ein Computerprogramm (genauer: ein Prozess) hat immer einen bestimmten definierten Speicher, der ihm zugestanden wird. Das Betriebssystem weist dem jeweiligen Prozess einen gewissen Speicherbereich zu, in diesem Speicherbereich kann das Computerprogramm alle nötigen Daten ablegen.
Nehmen wir als Beispiel ein sehr einfaches Programm, was eine Liste verwaltet, in etwa so: [ 1, 53, 7, 8, ]. Im Speicher sieht das dann so aus:
Platz im Speicher ... 195 196 197 198 ...
Inhalt 1 53 7 8
Diese Liste hat vier Plätze, die in den Speicherzellen 195-198 liegen. Das Betriebssystem (bzw das Programm) weiß das und weiß auch, dass das Programm genau 4 Speicherplätze belegt. Alle anderen Speicherzellen sind von anderen Programmen oder dem Betriebssystem selbst belegt.
Ein Programm ist immer eine gewisse Abfolge von Maschinenanweisungen. Im Hintergrund werden stumpf Befehle abgearbeitet und Anweisungen ausgewertet. Wir können nun z.B. folgenden Befehl ausführen: "Gib mir das zweite Element der Liste zurück". Wenn man das äquivalent in eine Programmier-/Maschinensprache umsetzt, wird folgendes dabei herauskommen: "Gib mir die Zahl in der Speicherzelle 196 zurück".
Was aber, wenn wir folgenden Befehl haben: "Gib mir das fünfte Element der Liste zurück". Das Programm weiß, wo die Liste anfängt und teilt dem Betriebssystem nun mit: "Gib mir die Zahl in der Speicherzelle 199 zurück". Da das Betriebssystem clever ist und auch als eine Art "Wächter" für den Speicher fungiert, merkt es recht schnell, dass da etwas faul ist. "Moooment, Speicherzelle 199 gehört ja gar nicht zu dem Prozess, der gerade anfragt." Dann holt das Betriebssystem die Zugriffsverletzungskeule raus und lässt das Programm abstürzen. Das ist dann die sogenannte Zugriffsverletzung: Ein Prozess will auf einen Speicherbereich zugreifen, der ihm gar nicht gehört.
In der Regel befindet sich ein (klassisches) Computerprogramm immer in einem wohldefinierten Zustand und man weiß ganz genau, was folgt. Das nennt man "deterministisch": Man weiß stets, an welcher Stelle das Programm gerade ist, welche Parameter gegeben sind, was als nächstes folgt usw. Fehlerzustände kann ein Programm nicht automatisch behandeln, außer der Entwickler kümmert sich aktiv darum. Ergo stürzt es im Fehlerfall einfach ab.
Es ist komplizierter ...
In Wirklichkeit gibt es nicht nur das Programm und das Betriebssystem, sondern viele verschiedene Ebenen dazwischengeschaltet (oder eben auch nicht). Das ist auch immer abhängig von der Programmiersprache:
- C: Hier ist ein Programm nahezu direkt mit dem Controller des Speichersverbunden. Wenn ich jetzt sage "Gib mir das fünfte Element der Liste zurück", merkt niemand den Fehler und du bekommst den Inhalt der Speicherzelle 199 zurück. Das ist übrigens der Grund, wieso C-Entwickler immer höllisch aufpassen müssen und stets auf der Hut vor Speicherfehlern sein müssen: Es fällt einfach nicht auf. Da im Speicher nicht nur Variablen drinstehen, sondern auch Anweisungen kann es leicht passieren, dass man Anweisungen ausführt, die gar nicht mehr zum Programm gehören. An dieser Stelle kann sich dann auch Schadsoftware befinden, die so ausgeführt wird ... Die klassischste Form von Sicherheitslücken durch Code Execution.
- Java/C#: Hier ist man nahezu immun gegen Speicherfehler. Die Programmiersprache (bzw. die Umgebung, in der die Programme laufen - eine Art "virtueller PC" - in Java die JVM (Java Virtual Machine)) wacht von Haus aus über Speicherfehler (und andere Fehler). Wenn man in Java z.B. auf das nicht-existierende fünfte Element der Liste zugreifen würde, erhielte man eine IndexOutOfBoundsException - Exceptions sind eine Art "Nachrichten", die Fehlerzustände signalisieren.
Der Programmierer muss sich darum aktiv kümmern, dass solche Exceptions nicht auftreten, dazu hat er folgende Möglichkeiten (s.u.). Tut er dies nicht, wird die Exception weiter "geworfen" und das Programm stürzt ab. In C# ist das dann die sog. "Unbehandelte Ausnahme" (vielleicht kennt der ein oder andere diesen Dialog).
- Überprüfen vorher: Vor dem Zugriff wird überprüft, ob die Liste tatsächlich so lang ist. Falls nicht, wird entweder eine Fehlermeldung ausgegeben (z.B. in einer Log-Datei) oder einfach irgendein anderer Wert (z.B. -1) zurückgegeben.
- Exception abfangen: Wir prüfen vorher nicht, sondern tun so als wäre nichts passiert und behandeln die Exception-Nachricht im Nachhinein. Dann können wir z.B. in die Log-Datei eine Fehlermeldung schreiben und den Zugriff irgendwie anders behandeln.
Natürlich gibt es noch gaaanz viele andere Typen von Exceptions (bspw. eine Datei soll geschrieben werden, die aber schreibgeschützt ist, die 750. Zeile einer Textdatei wird geladen, die aber nur 740 Zeilen hat, eine Variable soll quadriert werden, ist aber eine Zeichenkette und keine Zahl, ...), aber die meisten solcher Art lassen sich technisch auf Speicherfehler zurückführen weil entweder auf eine Speicherstelle zugegriffen wird, die einem nicht gehört oder eine Instruktion ausgeführt wird, die gar nicht mehr zum Programm gehört.
Was hat das mit OMSI zu tun?
Delphi/Pascal ist die Programmierumgebung, in der OMSI geschrieben wurde. Nach einigem Googeln stellt sich heraus, dass Meldungen wie "Zugriffsverletzung bei Adresse X in Modul Y" und "Fehler bei Bereichsprüfung" keinesfalls nur in der OMSI-Welt auftauchen, sondern typische Pascal-Fehlermeldungen sind. Ich vermute(!), dass überall dort, wo ein Fehlerzustand eintritt (s.o. - ein Programm weiß nicht, was es im Fehlerfall machen soll. Es stürzt ab - vergleichbar mit den Exceptions oben), der nicht behandelt wurde, eine der zwei Meldungen geworfen wird. Das kann ganz viele Gründe haben:
- Syntaxfehler in einer Konfigurationsdatei oder in einem Script => OMSI kann nicht wissen, was der Erbauer damit gemeint hat.
- Eine verwendete Variable ist nicht vorhanden => OMSI weiß nicht, welchen Wert die Variable hat und kann sie somit auch nicht verwenden
- In der global.cfg fehlt irgendwo ein Kacheleintrag => OMSI weiß nicht, was mit dieser Kachel ist. Ist die gelöscht? Ist die vorhanden? Ist die fehlerhaft? Wurde die vergessen?
- => Irgendwer hat irgendwas beim Bauen falsch gemacht
Es ist noch viiiiiieeeeeeel komplizierter ...
Wem die Erklärung immer noch nicht zu technisch war, dem sei auf folgende Seiten verwiesen:
Bitte noch mehr!
Informatik ist an vielen Universitäten zulassungsfrei. 
Zusammengefasst
Wann immer OMSI nicht mehr weiter weiß, weil ein Fehlerzustand eingetreten ist, wird eine der beiden Meldungen geworfen und OMSI stürzt ab weil es nicht weiß, wie es den Fehlerzustand "ausbügeln" kann.
Dementsprechend ist es sehr schwierig, den genauen Ursachen auf den Grund zu gehen. Alle Fehler eines Entwicklers (im Sinne von unsachgemäß geschriebenen Dateien oder Benutzung des Editors) können eine solche Meldung nach sich ziehen. Im Prinzip alles, was OMSI-seitig nicht vorgesehen und auch nicht abgefangen wird.