Skip to content

UDMF context drift fixes

toaster requested to merge conversion-context-drift into next

[This merge request consists of and expands upon work done for Dr. Robotnik's Ring Racers.]

Previously, many concatenated texture field strings were turned to text, then had that string run through get_number, then had it converted back into a string to become a stringarg.

Now, the concatenated string is copied directly to the relevant stringarg, with no intermediary steps.

This fixes an issue where a map with object or state properties would have "context drift" - breaking when the object or state list changed, due to differently ordered freeslots, or new hardcoded objects.

Affected types:

  • doomednum 1110/Action 9 (Custom Mace/Chain)
  • doomednum 700 and those immediately following (Ambient Sound)
  • Action 4 and 414 (dash pad, play sound effect)
  • Action 14 (bustable block parameters)
  • Action 434 (Award Power)
  • doomednum 757/Action 15 (fan particle generator)
  • doomednum 1202 (bumpable hazard rock/apple spawner)
    • This one has undefined behaviour in the binary map format which was not previously forbidden. This undefined behaviour is EXTREMELY vulnerable to context drift, and so it's simply not worth creating a system to write numerical values into object types - we write an explicit name only for the intended range, and otherwise report the threat of context drift when converting.

In addition, to reduce duplicated zone memory, (sidedef_t).text and (linedef_t).text have been removed from all but the Lua API. In Lua, in binary maps, they point to the host line's stringargs - the line's text and a frontside's text will return stringargs[0], while a backside's text will return stringargs[1]. I've done my best to match the previous API as closely possible, to the point of reporting false nils if the line didn't previously have text available.

However, there are four linedef Actions for which the sidedef text will be different between builds containing and not containing this commit - 331, 332, 333 (the Character-specific linedef executors), and 443 (Call Lua Script), and only if the text is long enough to go over two lines. Given that both halves would be incomplete nonsense in this case, I'm willing to wager this minor point of discrepancy is not a breaking issue.

In addition, never dereference an invalid pointer when P_GetNodeType can't get a valid set of nodes, just I_Error immediately.

Merge request reports