Skip to content

Conversation

@millennIumAMbiguity
Copy link

@millennIumAMbiguity millennIumAMbiguity commented Jan 11, 2026

Send DynamicMoldUnits, CastToolDurabilityPenalty, and DurabilityPenaltyPerRepair to clients from the server so that tooltips and descriptions work as intended when the config has been modified.

Summary by CodeRabbit

  • Refactor
    • Restructured configuration lifecycle management for improved server-client synchronization.
    • Added configuration validation to detect and warn about potential misconfigurations.

✏️ Tip: You can customize this high-level summary in your review settings.

Send `DynamicMoldUnits`, `CastToolDurabilityPenalty`, and `DurabilityPenaltyPerRepair` so that tooltips and descriptions work as intended when the config has been modified
@coderabbitai
Copy link

coderabbitai bot commented Jan 11, 2026

📝 Walkthrough

Walkthrough

The ConfigLoader is refactored to implement a multi-stage lifecycle pattern, replacing the single Start method with StartPre, StartServerSide, and StartClientSide hooks. Server config loading is extracted into a dedicated method, and config synchronization between server and client is implemented via new public methods.

Changes

Cohort / File(s) Summary
Config Lifecycle Refactoring
SmithingPlus/Config/ConfigLoader.cs
Replaces single Start(ICoreAPI api) with three lifecycle methods: StartPre (loads server config), StartServerSide (sends config to client), StartClientSide (reads config from server). Extracts config loading into private LoadServerConfig method. Adds public SendConfigToClient and ReadConfigFromServer for config synchronization. Introduces private VerifyConfig method for validation and sanity checks. Lines changed: +38/-4

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Hop, skip, and a sync!
Config flows from server's seat,
Client hops to rhythm beat,
Verification checks complete—
Configs now move graceful and sweet! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: fixing config synchronization from server to clients, which is the core objective of this PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @SmithingPlus/Config/ConfigLoader.cs:
- Around line 68-73: ReadConfigFromServer currently reads only three of the five
values that SendConfigToClient writes; update ReadConfigFromServer to also read
and assign Config.CanRepairForlornHopeEstoc and Config.WorkableBits from
api.World.Config (use the same keys used in SendConfigToClient, e.g.,
"SmithingPlus_CanRepairForlornHopeEstoc" and "SmithingPlus_WorkableBits") so the
static Config stays in sync with the server; if WorkableBits is intended to be
computed on demand instead, then compute it where needed and still read
CanRepairForlornHopeEstoc here to preserve consistency.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef40e45 and d1f4b34.

📒 Files selected for processing (1)
  • SmithingPlus/Config/ConfigLoader.cs
🧰 Additional context used
🧬 Code graph analysis (1)
SmithingPlus/Config/ConfigLoader.cs (1)
SmithingPlus/Config/ServerConfig.cs (1)
  • ServerConfig (7-53)
🔇 Additional comments (8)
SmithingPlus/Config/ConfigLoader.cs (8)

3-3: LGTM! Required imports for side-specific lifecycle methods.

The new imports support the ICoreClientAPI and ICoreServerAPI parameters used in the lifecycle methods.

Also applies to: 5-5


20-23: LGTM! Proper server-side initialization.

The StartServerSide override correctly calls SendConfigToClient to synchronize config values to connected clients via world config.


30-33: LGTM! Proper early initialization.

The StartPre override correctly calls LoadServerConfig to load configuration before side-specific initialization occurs.


35-56: Good refactoring with config verification.

The extraction of LoadServerConfig properly separates config loading logic, and the addition of VerifyConfig() (line 47) ensures config validation before persistence.

Minor note: The method name LoadServerConfig is slightly misleading since it runs on both client and server via StartPre, but it's acceptable since it loads the ServerConfig type.


62-65: PR objective successfully implemented.

The three config values specified in the PR objectives (DynamicMoldUnits, CastToolDurabilityPenalty, DurabilityPenaltyPerRepair) are now correctly transmitted to clients via world config synchronization.


58-66: Config values correctly written to world config.

The method properly sets config values in api.World.Config, which will be synchronized to connected clients by the game engine.

Note: Five values are sent but only three are read back in ReadConfigFromServer. See comment on lines 68-73 for details.


75-87: LGTM! Proper config validation.

The VerifyConfig method appropriately validates config values, warns about potential issues, and clamps VoxelsPerBit to the valid range [2, 3].


25-28: No timing concern here. Vintage Story's engine automatically synchronizes World.Config from server to client before StartClientSide is called. Your implementation correctly reads the synchronized values without needing custom network channels or delayed callbacks.

Comment on lines +68 to +73
public void ReadConfigFromServer(ICoreAPI api)
{
Config.DynamicMoldUnits = api.World.Config.GetBool("SmithingPlus_DynamicMoldUnits");
Config.CastToolDurabilityPenalty = api.World.Config.GetFloat("SmithingPlus_CastToolDurabilityPenalty");
Config.DurabilityPenaltyPerRepair = api.World.Config.GetFloat("SmithingPlus_DurabilityPenaltyPerRepair");
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the ConfigLoader.cs file to see SendConfigToClient method and get full context
find . -name "ConfigLoader.cs" -type f

Repository: jayugg/SmithingPlus

Length of output: 100


🏁 Script executed:

# Look for the file and get its size
fd ConfigLoader.cs

Repository: jayugg/SmithingPlus

Length of output: 98


🏁 Script executed:

# Examine the ConfigLoader.cs file
cat -n SmithingPlus/Config/ConfigLoader.cs | head -100

Repository: jayugg/SmithingPlus

Length of output: 3865


🏁 Script executed:

# Search for SendConfigToClient method to see what values are sent
rg -n "SendConfigToClient" --type=cs -A 10 SmithingPlus/Config/ConfigLoader.cs

Repository: jayugg/SmithingPlus

Length of output: 1035


🏁 Script executed:

# Search for usage of ConfigLoader.Config properties on client side
rg -n "ConfigLoader\.Config\." --type=cs

Repository: jayugg/SmithingPlus

Length of output: 45


🏁 Script executed:

# Also search for direct Config property access patterns
rg -n "Config\.(CanRepairForlornHopeEstoc|SmithWithBits|EnableToolRecovery|DynamicMoldUnits|CastToolDurabilityPenalty|DurabilityPenaltyPerRepair|WorkableBits)" --type=cs

Repository: jayugg/SmithingPlus

Length of output: 2363


🏁 Script executed:

# Check if CanRepairForlornHopeEstoc is used anywhere on client side
rg -n "CanRepairForlornHopeEstoc" --type=cs

Repository: jayugg/SmithingPlus

Length of output: 314


🏁 Script executed:

# Search for how WorkableBits is used
rg -n "WorkableBits" --type=cs -B 2 -A 2

Repository: jayugg/SmithingPlus

Length of output: 588


Incomplete synchronization: read back all sent config values for consistency.

SendConfigToClient sends 5 values to world config (lines 60-65), but ReadConfigFromServer only reads back 3 of them:

  • ✅ Read back: DynamicMoldUnits, CastToolDurabilityPenalty, DurabilityPenaltyPerRepair
  • ❌ Not read back: CanRepairForlornHopeEstoc (line 60), WorkableBits (line 61)

While CanRepairForlornHopeEstoc and WorkableBits are not currently used on the client side, the missing synchronization creates inconsistency and violates the pattern established by the other config values. Since the server explicitly sends these values to the world config, they should be read back on the client to ensure the static Config object stays in sync with the server.

Add the missing properties to ReadConfigFromServer:

Suggested fix
 public void ReadConfigFromServer(ICoreAPI api)
 {
+    Config.CanRepairForlornHopeEstoc = api.World.Config.GetBool("SmithingPlus_CanRepairForlornHopeEstoc");
     Config.DynamicMoldUnits = api.World.Config.GetBool("SmithingPlus_DynamicMoldUnits");
     Config.CastToolDurabilityPenalty = api.World.Config.GetFloat("SmithingPlus_CastToolDurabilityPenalty");
     Config.DurabilityPenaltyPerRepair = api.World.Config.GetFloat("SmithingPlus_DurabilityPenaltyPerRepair");
 }

Note: WorkableBits is a computed value derived from SmithWithBits or EnableToolRecovery and does not need to be stored as a config property; it can be computed on demand when needed.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void ReadConfigFromServer(ICoreAPI api)
{
Config.DynamicMoldUnits = api.World.Config.GetBool("SmithingPlus_DynamicMoldUnits");
Config.CastToolDurabilityPenalty = api.World.Config.GetFloat("SmithingPlus_CastToolDurabilityPenalty");
Config.DurabilityPenaltyPerRepair = api.World.Config.GetFloat("SmithingPlus_DurabilityPenaltyPerRepair");
}
public void ReadConfigFromServer(ICoreAPI api)
{
Config.CanRepairForlornHopeEstoc = api.World.Config.GetBool("SmithingPlus_CanRepairForlornHopeEstoc");
Config.DynamicMoldUnits = api.World.Config.GetBool("SmithingPlus_DynamicMoldUnits");
Config.CastToolDurabilityPenalty = api.World.Config.GetFloat("SmithingPlus_CastToolDurabilityPenalty");
Config.DurabilityPenaltyPerRepair = api.World.Config.GetFloat("SmithingPlus_DurabilityPenaltyPerRepair");
}
🤖 Prompt for AI Agents
In @SmithingPlus/Config/ConfigLoader.cs around lines 68 - 73,
ReadConfigFromServer currently reads only three of the five values that
SendConfigToClient writes; update ReadConfigFromServer to also read and assign
Config.CanRepairForlornHopeEstoc and Config.WorkableBits from api.World.Config
(use the same keys used in SendConfigToClient, e.g.,
"SmithingPlus_CanRepairForlornHopeEstoc" and "SmithingPlus_WorkableBits") so the
static Config stays in sync with the server; if WorkableBits is intended to be
computed on demand instead, then compute it where needed and still read
CanRepairForlornHopeEstoc here to preserve consistency.

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.

1 participant