fix: Project Zomboid runs on G1 and the C1 JIT instead of ZGC (#2016)

This commit is contained in:
Kurt Himebauch authored and maxjivi05 committed 2026-11-03 13:25:08 -05:00
1 parent 6588185e96
commit d1707dc1b7
2 files changed
+99

No files matched your search

@@ -243,6 +243,59 @@ def ubisoft_overlay_off(env):
print("droiddeck-game-env: Ubisoft Connect overlay left as is (%s)" % error, file=sys.stderr)
PZ_JVM_FLAGS = ("-XX:+UseG1GC", "-XX:TieredStopAtLevel=1")
def zomboid_vm_args(args):
updated = [arg for arg in args if not re.fullmatch(r"-XX:\+Use\w*GC", arg) or arg == "-XX:+UseG1GC"]
for flag in PZ_JVM_FLAGS:
if flag not in updated:
updated.append(flag)
return updated
def zomboid_rewrite(node):
changed = False
if isinstance(node, dict):
for key, value in node.items():
if key == "vmArgs" and isinstance(value, list) and all(isinstance(arg, str) for arg in value):
updated = zomboid_vm_args(value)
if updated != value:
node[key] = updated
changed = True
elif isinstance(value, dict):
changed |= zomboid_rewrite(value)
return changed
def project_zomboid_jvm(command):
if len(command) <= 2:
return
exe = Path(command[2])
if not exe.stem.lower().startswith("projectzomboid"):
return
settings = exe.with_suffix(".json")
try:
with settings.open(encoding="utf-8-sig") as source:
data = json.load(source)
if not zomboid_rewrite(data):
return
handle, staged = tempfile.mkstemp(prefix=".droiddeck-", dir=settings.parent)
try:
with os.fdopen(handle, "w", encoding="utf-8") as target:
json.dump(data, target, indent=4)
target.write("\n")
os.chmod(staged, settings.stat().st_mode & 0o7777)
os.replace(staged, settings)
except BaseException:
os.unlink(staged)
raise
print("droiddeck-game-env: Project Zomboid: G1 garbage collector and C1 JIT only (ZGC overheats and stalls here)",
file=sys.stderr)
except (OSError, ValueError, AttributeError) as error:
print("droiddeck-game-env: Project Zomboid JVM settings left as is (%s)" % error, file=sys.stderr)
def offline_without_anticheat(command, env):
if (env.get("DROIDDECK_ANTICHEAT_OFFLINE") != "1" or len(command) <= 2
or command[1] != "waitforexitandrun"
@@ -931,6 +984,7 @@ def main():
if waiting:
command = skip_red_launcher(command)
ubisoft_overlay_off(env)
project_zomboid_jvm(command)
fixes, extra, notes = engine_fixes(command[2], command[3:]) if len(command) > 2 else ({}, [], [])
if not gl_default:
fixes.pop("vblank_mode", None)
+45
View File
@@ -2026,6 +2026,51 @@ class DirectAudioPrefixTest(unittest.TestCase):
self.assertIsNone(self.link("system32"))
class ProjectZomboidJvmTest(unittest.TestCase):
ARGS = ["-Djava.awt.headless=true", "-Xmx3072m", "-XX:+UseZGC", "-XX:-CreateCoredumpOnCrash"]
def launch(self, tmp, args=None, stem="ProjectZomboid64"):
settings = Path(tmp) / (stem + ".json")
settings.write_text(json.dumps({"mainClass": "zombie/gameStates/MainScreenState", "vmArgs": args or self.ARGS}))
command = ["proton", "waitforexitandrun", str(Path(tmp) / (stem + ".exe"))]
return settings, command
def test_zgc_becomes_g1_and_the_c1_jit_flag_is_added_once(self):
with tempfile.TemporaryDirectory() as tmp:
settings, command = self.launch(tmp)
MODULE["project_zomboid_jvm"](command)
data = json.loads(settings.read_text())
self.assertEqual(data["vmArgs"], ["-Djava.awt.headless=true", "-Xmx3072m", "-XX:-CreateCoredumpOnCrash",
"-XX:+UseG1GC", "-XX:TieredStopAtLevel=1"])
self.assertEqual(data["mainClass"], "zombie/gameStates/MainScreenState")
before = settings.read_text()
MODULE["project_zomboid_jvm"](command)
self.assertEqual(settings.read_text(), before)
def test_other_collectors_and_windows_specific_lists_are_rewritten(self):
with tempfile.TemporaryDirectory() as tmp:
settings, command = self.launch(tmp)
settings.write_text(json.dumps({"vmArgs": ["-XX:+UseParallelGC", "-Xmx1g"],
"windows": {"10.0.17134": {"vmArgs": ["-XX:+UseZGC", "-XX:+UseG1GC"]}}}))
MODULE["project_zomboid_jvm"](command)
data = json.loads(settings.read_text())
flags = ["-XX:+UseG1GC", "-XX:TieredStopAtLevel=1"]
self.assertEqual(data["vmArgs"], ["-Xmx1g"] + flags)
self.assertEqual(data["windows"]["10.0.17134"]["vmArgs"], flags)
def test_other_games_and_unreadable_files_are_left_alone(self):
with tempfile.TemporaryDirectory() as tmp:
settings, command = self.launch(tmp, stem="Other")
before = settings.read_text()
MODULE["project_zomboid_jvm"](command)
self.assertEqual(settings.read_text(), before)
settings.write_text("{")
MODULE["project_zomboid_jvm"](command[:2] + [str(Path(tmp) / "Other.exe")])
(Path(tmp) / "ProjectZomboid64.json").write_text("{")
MODULE["project_zomboid_jvm"](command[:2] + [str(Path(tmp) / "ProjectZomboid64.exe")])
self.assertEqual((Path(tmp) / "ProjectZomboid64.json").read_text(), "{")
class UbisoftOverlayTest(unittest.TestCase):
SETTINGS = (
"language:\n code: en-US\n"