Skip to content

Conversation

@memo33
Copy link
Collaborator

@memo33 memo33 commented Jan 18, 2026

  • adds a GH action script that scans RUL0 for the most common type of sinkhole bugs (mismatches between CellLayout and ConsLayout)
  • fixes various potential sinkholes identified by the script

Example output:

===> Controller/RUL0/5000_RHW/5F00_FARHW/5F20_FARHW_Curves.txt
Potential sinkhole bug in ConsLayout at cells (0, 1):
  538: CellLayout =............
  539: CellLayout =...abbbb+..<
  540: CellLayout =.....bbbb...
  541: CellLayout =....^.......
  ---
  548: ConsLayout =............
  549: ConsLayout =...-----...<
  550: ConsLayout =....----....
  551: ConsLayout =....^.......

This might not catch every sinkhole out there. If any others are found, the criteria in the script can be extended. (It might become necessary to parse the CheckTypes then.)

@UlisseWolf
Copy link
Contributor

I have no problem with implementing this script to avoid the sinkhole bug.

One possible suggestion to avoid further problems is to create an instruction page on CellLayout and ConsLayout.

@memo33
Copy link
Collaborator Author

memo33 commented Jan 18, 2026

The Wiki is a good source of information: https://www.wiki.sc4devotion.com/index.php?title=RUL0#ConsLayout

@caspervg
Copy link
Contributor

caspervg commented Jan 18, 2026

Haven't gone over the script
code and changes entirely just yet, but did want to throw in that in DBPFKit I set up a full RUL0 parser in CPP that could be useful for other kinds of validation or as inspiration for the Scala script: https://github.com/caspervg/DBPFKit/blob/main/src/RUL0.h
https://github.com/caspervg/DBPFKit/blob/main/src/RUL0.cpp

It didn't yet do actual validation of the Cell/ConsLayout agreeing, so that's a nice feature I'll add there :)

if bad_cells:
cell_layout_str = "".join(f" {line_no}: {line}" for line_no, line in cell_lines)
cons_layout_str = "".join(f" {line_no}: {line}" for line_no, line in cons_lines)
raise Exception(f"Potential sinkhole bug in ConsLayout at cells {" ".join(map(str, bad_cells))}:\n{cell_layout_str} ---\n{cons_layout_str}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f-string quote handling seems a bit off here. I would use single quotes for ' '.join here within the bigger string. It might work as is but looks a bit confusing at first glance

elif grouped and not grouped[-1][0]:
yield "Found no matching ConsLayout for last CellLayout in file"
else:
for ((_, cell_lines), (_, cons_lines)) in itertools.batched(grouped, 2):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since itertools.batched() is fairly new (Py 3.12+) it might be good to document this somewhere in case people want to run this script locally before committing new RUL0 code

# create mapping of (x,y)-cell to char
def parse_layout(lines):
layout = [line[(line.index("=")+1):].strip() for line in drop_comments(lines)]
origin_x = ([l.index("^") for l in layout if "^" in l] or [0])[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the origin x/y are missing, does the game also just default to 0? If not this might be an easy extra check to build in (even if maybe not relevant specifically for the sinkhole bug)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure. You're right though – regardless of what the game does in case the markers are missing, we'd always want them to be present, as it's unlikely to be intentional, so I'll add an extra check.

@memo33
Copy link
Collaborator Author

memo33 commented Jan 18, 2026

in DBPFKit I set up a full RUL0 parser in CPP that could be useful for other kinds of validation or as inspiration

Thanks for the link. I hadn't seen your code yet, but knew you had been working on a RUL0 parser. For the purpose of a linter, C++ is a bit too cumbersome to work with for me though. As you can see, I took the quick and dirty approach, not trying to 100% validate the entire syntax.

I'll set this PR back to draft to make the suggested changes. I might also try to add a check for the following criterion, as it's a good indicator for sinkholes: Static cells (i.e. not tagged optional or check) in the cell layout should not use . in the constraint layout.

@memo33 memo33 marked this pull request as draft January 18, 2026 19:44
@caspervg
Copy link
Contributor

in DBPFKit I set up a full RUL0 parser in CPP that could be useful for other kinds of validation or as inspiration

Thanks for the link. I hadn't seen your code yet, but knew you had been working on a RUL0 parser. For the purpose of a linter, C++ is a bit too cumbersome to work with for me though. As you can see, I took the quick and dirty approach, not trying to 100% validate the entire syntax.

Yeah for sure, for linting this code makes a lot more sense 😅 The setup to get the DBPFKit parser running in the Github Action container would be very overkill. Just thought I'd link it in case it offers ideas for other linting options

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants