1717 * <li>Lazy block entity initialization - defers creation until needed</li>
1818 * <li>Lazy block tick discovery - defers ticking block detection</li>
1919 * <li>Lazy fluid pre-processing - defers fluid simulation during chunk load</li>
20+ * <li>Entity view distance - configurable entity sync distance multiplier</li>
21+ * <li>Chunk rate - configurable chunks per tick</li>
22+ * <li>Pathfinding limits - configurable A* pathfinding parameters</li>
2023 * </ul>
2124 *
2225 * @author CriticalRange
@@ -25,6 +28,7 @@ public class Catalyst extends JavaPlugin {
2528
2629 private static Catalyst instance ;
2730 private CatalystTransformerManager transformerManager ;
31+ private CatalystConfigFile configFile ;
2832
2933 public Catalyst (@ Nonnull JavaPluginInit init ) {
3034 super (init );
@@ -50,6 +54,13 @@ public String getVersion() {
5054
5155 @ Override
5256 protected void setup () {
57+ // Load configuration from file
58+ configFile = new CatalystConfigFile (getDataDirectory ());
59+ configFile .load ();
60+
61+ // Sync config values to injected fields in transformed classes
62+ syncConfigToInjectedFields ();
63+
5364 transformerManager = new CatalystTransformerManager ();
5465
5566 try {
@@ -70,6 +81,12 @@ protected void start() {
7081 @ Override
7182 protected void shutdown () {
7283 log ("Catalyst shutting down..." );
84+
85+ // Save configuration to file
86+ if (configFile != null ) {
87+ configFile .save ();
88+ }
89+
7390 log ("\n " + CatalystMetrics .generateReport ());
7491 if (transformerManager != null ) {
7592 transformerManager .logMetrics ();
@@ -83,6 +100,16 @@ private void logConfig() {
83100 log (" - Block Entities: " + s (CatalystConfig .LAZY_BLOCK_ENTITIES_ENABLED ));
84101 log (" - Block Tick: " + s (CatalystConfig .LAZY_BLOCK_TICK_ENABLED ));
85102 log (" - Fluid: " + s (CatalystConfig .LAZY_FLUID_ENABLED ));
103+ log (" Runtime Optimizations:" );
104+ log (" - Entity Distance: " + s (CatalystConfig .ENTITY_DISTANCE_ENABLED ) +
105+ " (multiplier: " + CatalystConfig .ENTITY_VIEW_MULTIPLIER + ")" );
106+ log (" - Chunk Rate: " + s (CatalystConfig .CHUNK_RATE_ENABLED ) +
107+ " (chunks/tick: " + CatalystConfig .CHUNKS_PER_TICK + ")" );
108+ log (" Pathfinding:" );
109+ log (" - Custom Limits: " + s (CatalystConfig .PATHFINDING_ENABLED ));
110+ log (" - Max Path Length: " + CatalystConfig .MAX_PATH_LENGTH );
111+ log (" - Open Nodes: " + CatalystConfig .OPEN_NODES_LIMIT );
112+ log (" - Total Nodes: " + CatalystConfig .TOTAL_NODES_LIMIT );
86113 }
87114
88115 private String s (boolean enabled ) {
@@ -93,7 +120,97 @@ private void log(String message) {
93120 System .out .println ("[Catalyst] " + message );
94121 }
95122
123+ /**
124+ * Syncs CatalystConfig values to the injected fields in transformed Hytale classes.
125+ * This must be called after loading config but before the server starts using these values.
126+ */
127+ private void syncConfigToInjectedFields () {
128+ // Lazy loading fields
129+ setStaticField ("com.hypixel.hytale.server.core.modules.block.BlockModule" ,
130+ "$catalystLazyBlockEntities" , CatalystConfig .LAZY_BLOCK_ENTITIES_ENABLED );
131+ setStaticField ("com.hypixel.hytale.builtin.blocktick.BlockTickPlugin" ,
132+ "$catalystLazyBlockTick" , CatalystConfig .LAZY_BLOCK_TICK_ENABLED );
133+ setStaticField ("com.hypixel.hytale.builtin.fluid.FluidPlugin" ,
134+ "$catalystLazyFluid" , CatalystConfig .LAZY_FLUID_ENABLED );
135+
136+ // Entity distance fields
137+ setStaticField ("com.hypixel.hytale.server.core.universe.Universe" ,
138+ "$catalystEntityDistEnabled" , CatalystConfig .ENTITY_DISTANCE_ENABLED );
139+ setStaticField ("com.hypixel.hytale.server.core.universe.Universe" ,
140+ "$catalystEntityViewMultiplier" , CatalystConfig .ENTITY_VIEW_MULTIPLIER );
141+
142+ // Chunk rate fields
143+ setStaticField ("com.hypixel.hytale.server.core.modules.entity.player.ChunkTracker" ,
144+ "$catalystChunkRateEnabled" , CatalystConfig .CHUNK_RATE_ENABLED );
145+ setStaticField ("com.hypixel.hytale.server.core.modules.entity.player.ChunkTracker" ,
146+ "$catalystChunksPerTick" , CatalystConfig .CHUNKS_PER_TICK );
147+
148+ // Pathfinding fields
149+ setStaticField ("com.hypixel.hytale.server.npc.navigation.AStarBase" ,
150+ "$catalystPathfindingEnabled" , CatalystConfig .PATHFINDING_ENABLED );
151+ setStaticField ("com.hypixel.hytale.server.npc.navigation.AStarBase" ,
152+ "$catalystMaxPathLength" , CatalystConfig .MAX_PATH_LENGTH );
153+ setStaticField ("com.hypixel.hytale.server.npc.navigation.AStarBase" ,
154+ "$catalystOpenNodesLimit" , CatalystConfig .OPEN_NODES_LIMIT );
155+ setStaticField ("com.hypixel.hytale.server.npc.navigation.AStarBase" ,
156+ "$catalystTotalNodesLimit" , CatalystConfig .TOTAL_NODES_LIMIT );
157+ }
158+
159+ private void setStaticField (String className , String fieldName , boolean value ) {
160+ try {
161+ Class <?> clazz = Class .forName (className );
162+ java .lang .reflect .Field field = clazz .getField (fieldName );
163+ field .setBoolean (null , value );
164+ } catch (ClassNotFoundException e ) {
165+ // Class not loaded yet - this is fine, field will use default
166+ log (" [Sync] " + className .substring (className .lastIndexOf ('.' ) + 1 ) + " not loaded yet" );
167+ } catch (NoSuchFieldException e ) {
168+ // Field doesn't exist - transformer may not have run
169+ log (" [Sync] Field " + fieldName + " not found in " + className );
170+ } catch (Exception e ) {
171+ log (" [Sync] Failed to set " + fieldName + ": " + e .getMessage ());
172+ }
173+ }
174+
175+ private void setStaticField (String className , String fieldName , int value ) {
176+ try {
177+ Class <?> clazz = Class .forName (className );
178+ java .lang .reflect .Field field = clazz .getField (fieldName );
179+ field .setInt (null , value );
180+ } catch (ClassNotFoundException e ) {
181+ // Class not loaded yet - this is fine, field will use default
182+ log (" [Sync] " + className .substring (className .lastIndexOf ('.' ) + 1 ) + " not loaded yet" );
183+ } catch (NoSuchFieldException e ) {
184+ // Field doesn't exist - transformer may not have run
185+ log (" [Sync] Field " + fieldName + " not found in " + className );
186+ } catch (Exception e ) {
187+ log (" [Sync] Failed to set " + fieldName + ": " + e .getMessage ());
188+ }
189+ }
190+
96191 public CatalystTransformerManager getTransformerManager () {
97192 return transformerManager ;
98193 }
194+
195+ /**
196+ * Saves the current configuration to the config file.
197+ * Call this after making changes to {@link CatalystConfig} to persist them.
198+ */
199+ public void saveConfig () {
200+ if (configFile != null ) {
201+ configFile .save ();
202+ }
203+ }
204+
205+ /**
206+ * Reloads configuration from the config file.
207+ *
208+ * @return true if config was reloaded successfully
209+ */
210+ public boolean reloadConfig () {
211+ if (configFile != null ) {
212+ return configFile .load ();
213+ }
214+ return false ;
215+ }
99216}
0 commit comments