Repository navigation
Conversation
Fixes the vanilla crash-to-desktop when the personal letters list shows a scripted letter whose town byte is not a town index, most prominently the escort/patrol mission's "Patrol destination" letters. The letter-creation script command (0x4ed4a0) stores the low byte of a script variable as the message's town unvalidated, and the list's town column looks it up in the 40-slot town-name bank without a bounds check (0x47d928), passing the result to ddraw_Dll's unguarded text draw. The fix detours the lookup: out-of-range town bytes draw an empty string, matching what the unpatched game shows whenever the wild read happens to survive. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The crash is one wrong byte in one file. The missions are script blobs in p2arch0_eng.cpr rather than code, and command 37 of missions_addon/patrouille.p2m - the "Patrol destination" letter - names variable 131 as the letter's town in a script that declares 25 variables. The variable array is malloc(count * 4), so the create-letter command reads 424 bytes past a 100-byte block and stores whatever heap data follows it as the town byte the letters list then indexes the name bank with. Ship the corrected script alongside the DLL: variable 0 is the town the letter is about, which the route command writes, the letter body prints twice, the deadline and the arrival check both use, and every other letter in the script already passes. The game prefers a loose file over the archive, and no command changes length, so savegames keep working. The DLL is still what makes an existing save openable - a letter's town byte is written at creation and saved with the game, so letters that already exist keep their garbage byte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
There's an old bug where the game generates a message with invalid pointer for the town name. When it doesn't lead to crash, that manifests as an empty town name:

https://patrician3.fandom.com/wiki/Forum:Recieving_letter_glitch
https://steamcommunity.com/app/33570/discussions/0/1474222595298102350/
Got a reproducible save and nailed it. It is fixed the same way in the 1.1b exe, but we are based on 1.1.
The patrol letter crash
Every letter in the game carries a town byte, which the letters list uses to look up a town name and print it in the town column. The list trusts that byte: it uses it as an index into a 40-entry table of town names with no range check.
Patrol missions send a "Patrol destination" letter whose town byte is garbage. The mission is a little script, and the script tells the letter to take its town from variable 131 — but the script only has 25 variables. The game reads variable 131 anyway, which lands about 400 bytes past the end of the variable array, so the town byte ends up being whatever unrelated data happens to sit there.
That is why the bug looks random. If the stray value is under 40 the row prints a wrong town name; if it is larger, the lookup reads past the name table and hands the text renderer something that isn't a string, and the game crashes the moment the list is drawn. Which of the two happens depends on what is in memory at the time, so it varies by save, resolution and session.
Only the list is affected — the letter's own text is built through a bounded lookup, so opening the letter is always safe.
The fix bounds the lookup: town bytes under 40 behave exactly as before, anything else draws an empty town column — the same blank cell the unpatched game shows whenever the stray read happens not to crash.
Also included is missions_addon/patrouille.p2m, the mission script with that one byte corrected so the letter reads its town from variable 0 — the town it is actually about. Copy it next to Patrician3.exe and the game prefers it over the archived copy. It only helps letters created from then on: a town byte is written when the letter is created and saved with the game, so letters already in a mailbox keep their garbage byte, which is what the DLL is still for.