diff --git a/Data/RenderConfig.cs b/Data/RenderConfig.cs
index 5241e14..99f2731 100644
--- a/Data/RenderConfig.cs
+++ b/Data/RenderConfig.cs
@@ -1,272 +1,272 @@
-using System.Diagnostics.CodeAnalysis;
-using Newtonsoft.Json;
-using UnityEngine;
-
-namespace ADOFAIRenderer.Data;
-
-///
-/// Settings of one render: resolution, frame rates, encoding and advanced options. Serialized to JSON in the preset
-/// files (PresetManager). renders with a copy ().
-///
-[SuppressMessage("ReSharper", "RedundantDefaultMemberInitializer")]
-public class RenderConfig
-{
- ///
- /// Game frames simulated per second of render time (the game clock advances 1 / RenderFPS seconds per frame).
- /// Values above render extra frames between video frames, which are not captured
- /// (the game state then advances in smaller time steps).
- ///
- public double RenderFPS { get; set; }
-
- ///
- /// Frame rate of the output video. The effective rate is min(VideoFPS, RenderFPS).
- ///
- public double VideoFPS { get; set; }
-
- /// Width of the rendered frames and the output video in pixels (also reported by the Screen.width patch).
- public int RenderWidth { get; set; }
-
- /// Height of the rendered frames and the output video in pixels (also reported by the Screen.height patch).
- public int RenderHeight { get; set; }
-
- /// Video encoder settings.
- public VideoEncodingConfig VideoConfig { get; set; } = new();
-
- /// Audio rendering and encoder settings.
- public AudioEncodingConfig AudioConfig { get; set; } = new();
-
- /// Advanced options (random seed, spectrum processing, tile hiding, container, planet colors).
- public AdvancedConfig AdvancedConfig { get; set; } = new();
-
- /// Seconds of render time recorded after the end condition first holds (default 15).
- public double DelayAfterEnd { get; set; } = 15;
-
- /// Whether the judgement texts (hit accuracy texts) are shown during the render (scrHitTextManagerPatch). Default false.
- public bool ShowJudgementText { get; set; } = false;
-
- ///
- /// Copies every value of into this object; the nested configs are copied value by value
- /// into the existing nested objects. Does nothing when is null.
- ///
- public void CopyFrom(RenderConfig? source)
- {
- if (source == null) return;
- RenderFPS = source.RenderFPS;
- VideoFPS = source.VideoFPS;
- RenderWidth = source.RenderWidth;
- RenderHeight = source.RenderHeight;
- DelayAfterEnd = source.DelayAfterEnd;
- ShowJudgementText = source.ShowJudgementText;
-
- VideoConfig.CopyFrom(source.VideoConfig);
- AudioConfig.CopyFrom(source.AudioConfig);
- AdvancedConfig.CopyFrom(source.AdvancedConfig);
- }
-
- /// Returns a deep copy (nested configs are new objects).
- public RenderConfig Clone()
- {
- var clone = new RenderConfig();
- clone.CopyFrom(this);
- return clone;
- }
-}
-
-/// Advanced render options.
-[SuppressMessage("ReSharper", "RedundantDefaultMemberInitializer")]
-public class AdvancedConfig
-{
- ///
- /// Seed for UnityEngine.Random set before the game scene loads, so random visual effects repeat between renders;
- /// null leaves the random state unchanged.
- ///
- public int? RandomSeed { get; set; } = null;
-
- ///
- /// When true, AudioSource.GetSpectrumData is answered from the offline song audio at the render time
- /// (AudioSpectrumGenerator), so audio-reactive visuals follow the rendered audio. Default true.
- ///
- public bool ProcessAudio { get; set; } = true;
-
- ///
- /// When true, the level's floor tiles (including hold meshes and the portal particles of the level's floors) and the
- /// planets are hidden during the render, so only the background and decorations remain (scnGamePatch, scrFloorPatch,
- /// RenderManager.OnLastUpdate). Default false.
- ///
- public bool NonTile { get; set; } = false;
-
- ///
- /// When true, the game's bloom (VideoBloom) computes its blur size as if the frame were 720 pixels high, so the
- /// blur passes on the 198-pixel-high bloom buffer are the same as in a 720p frame at any render height
- /// (VideoBloomPatch). Default false.
- ///
- public bool HighResBloomCorrection { get; set; } = false;
-
- ///
- /// When true, fixes in-game and render bugs during SetFramerate events (where objects disappear on the first frame
- /// or parallax/tiles lag behind) by deferring manual camera rendering to the end of the frame after all LateUpdates.
- /// Default true.
- ///
- public bool FixCustomFrameRate { get; set; } = true;
-
- ///
- /// When true, prevents floor tiles from being disabled when outside the camera frustum (scrFloor.OnBecameInvisible),
- /// eliminating the 1-frame update lag/glitch when tiles enter the screen. Default true.
- ///
- public bool DisableTileCulling { get; set; } = true;
-
- ///
- /// When true, hides placeholder decorations (default tree-in-circle sprite) that failed to load or are empty.
- /// Default false.
- ///
- public bool HideFailedDecorations { get; set; } = false;
-
- /// File extension of the default output file name, without the dot (e.g. "mkv", "mp4"); selects the container.
- public string FileExtension { get; set; } = "mkv";
-
- /// Color of the fire (red) planet during the render; null keeps the user's setting. Serialized as "#RRGGBBAA".
- [JsonConverter(typeof(ColorJsonConverter))]
- public Color? firePlanetColor = null;
-
- /// Color of the ice (blue) planet during the render; null keeps the user's setting. Serialized as "#RRGGBBAA".
- [JsonConverter(typeof(ColorJsonConverter))]
- public Color? icePlanetColor = null;
-
- ///
- /// Color of the third (wind, planetGreen) planet during the render (PlanetarySystemPatch); null keeps the game's color.
- /// Serialized as "#RRGGBBAA".
- ///
- [JsonConverter(typeof(ColorJsonConverter))]
- public Color? windPlanetColor = null;
-
- /// Copies every value of ; does nothing when it is null.
- public void CopyFrom(AdvancedConfig? source)
- {
- if (source == null) return;
- RandomSeed = source.RandomSeed;
- ProcessAudio = source.ProcessAudio;
- NonTile = source.NonTile;
- HighResBloomCorrection = source.HighResBloomCorrection;
- FixCustomFrameRate = source.FixCustomFrameRate;
- DisableTileCulling = source.DisableTileCulling;
- HideFailedDecorations = source.HideFailedDecorations;
- FileExtension = source.FileExtension;
- firePlanetColor = source.firePlanetColor;
- icePlanetColor = source.icePlanetColor;
- windPlanetColor = source.windPlanetColor;
- }
-
- /// Returns a copy of this object.
- public AdvancedConfig Clone()
- {
- var clone = new AdvancedConfig();
- clone.CopyFrom(this);
- return clone;
- }
-}
-
-/// Video encoder settings (passed to FFmpegNativeEncoder.EncoderSettings).
-public class VideoEncodingConfig
-{
- /// Video codec (default H.264). Also selects the audio codec (CodecUtil.AudioCodecMatch).
- public Codec Codec { get; set; } = Codec.H264;
-
- /// Bitrate control mode (default CBR).
- public RateControlMode RateControlMode { get; set; } = RateControlMode.CBR;
-
- /// Target video bitrate in kbps for CBR and VBR (default 30000 = 30 Mbps).
- public int Bitrate { get; set; } = 30000;
-
- /// Peak video bitrate in kbps for VBR, used when larger than Bitrate (otherwise 1.5 × Bitrate). Default 50000.
- public int MaxBitrate { get; set; } = 50000;
-
- ///
- /// Quality value for CQP: lower is higher quality. Clamped to the range of the selected encoder; a negative value
- /// selects 18. Default 18.
- ///
- // ReSharper disable once InconsistentNaming
- public int QP { get; set; } = 18;
-
- /// Keyframe interval in seconds (GOP length = round(effective video FPS × interval) frames, at least 1). Default 2.
- public double KeyframeInterval { get; set; } = 2.0;
-
- /// When true, only software (CPU) encoders are tried; hardware encoders are skipped.
- public bool ForceSoftwareEncoder { get; set; }
-
- /// Copies every value of ; does nothing when it is null.
- public void CopyFrom(VideoEncodingConfig? source)
- {
- if (source == null) return;
- Codec = source.Codec;
- RateControlMode = source.RateControlMode;
- Bitrate = source.Bitrate;
- MaxBitrate = source.MaxBitrate;
- QP = source.QP;
- KeyframeInterval = source.KeyframeInterval;
- ForceSoftwareEncoder = source.ForceSoftwareEncoder;
- }
-
- /// Returns a copy of this object.
- public VideoEncodingConfig Clone()
- {
- var clone = new VideoEncodingConfig();
- clone.CopyFrom(this);
- return clone;
- }
-}
-
-///
-/// Audio rendering and encoder settings. Non-positive values of the numeric settings read back as their defaults
-/// (48000 Hz, 2 channels, 256000 bps).
-///
-public class AudioEncodingConfig
-{
- private int _audioSampleRate = 48000;
- private int _audioChannels = 2;
- private int _audioBitrate = 256000;
-
- /// When true, the song and sound effects are mixed offline and encoded as an audio stream. Default true.
- public bool RenderAudio { get; set; } = true;
-
- ///
- /// Output sample rate in Hz (default 48000). A rate the audio codec does not support in the mod
- /// (CodecUtil.AvailableSampleRate) is replaced with 48000 when the render starts.
- ///
- public int AudioSampleRate
- {
- get => _audioSampleRate <= 0 ? 48000 : _audioSampleRate;
- set => _audioSampleRate = value <= 0 ? 48000 : value;
- }
-
- /// Number of output audio channels (default 2).
- public int AudioChannels
- {
- get => _audioChannels <= 0 ? 2 : _audioChannels;
- set => _audioChannels = value <= 0 ? 2 : value;
- }
-
- /// Audio bitrate in bits per second (default 256000 = 256 kbps). Unit differs from the video bitrate (kbps).
- public int AudioBitrate
- {
- get => _audioBitrate <= 0 ? 256000 : _audioBitrate;
- set => _audioBitrate = value <= 0 ? 256000 : value;
- }
-
- /// Copies every value of ; does nothing when it is null.
- public void CopyFrom(AudioEncodingConfig? source)
- {
- if (source == null) return;
- RenderAudio = source.RenderAudio;
- AudioSampleRate = source.AudioSampleRate;
- AudioChannels = source.AudioChannels;
- AudioBitrate = source.AudioBitrate;
- }
-
- /// Returns a copy of this object.
- public AudioEncodingConfig Clone()
- {
- var clone = new AudioEncodingConfig();
- clone.CopyFrom(this);
- return clone;
- }
-}
\ No newline at end of file
+using System.Diagnostics.CodeAnalysis;
+using Newtonsoft.Json;
+using UnityEngine;
+
+namespace ADOFAIRenderer.Data;
+
+///
+/// Settings of one render: resolution, frame rates, encoding and advanced options. Serialized to JSON in the preset
+/// files (PresetManager). renders with a copy ().
+///
+[SuppressMessage("ReSharper", "RedundantDefaultMemberInitializer")]
+public class RenderConfig
+{
+ ///
+ /// Game frames simulated per second of render time (the game clock advances 1 / RenderFPS seconds per frame).
+ /// Values above render extra frames between video frames, which are not captured
+ /// (the game state then advances in smaller time steps).
+ ///
+ public double RenderFPS { get; set; }
+
+ ///
+ /// Frame rate of the output video. The effective rate is min(VideoFPS, RenderFPS).
+ ///
+ public double VideoFPS { get; set; }
+
+ /// Width of the rendered frames and the output video in pixels (also reported by the Screen.width patch).
+ public int RenderWidth { get; set; }
+
+ /// Height of the rendered frames and the output video in pixels (also reported by the Screen.height patch).
+ public int RenderHeight { get; set; }
+
+ /// Video encoder settings.
+ public VideoEncodingConfig VideoConfig { get; set; } = new();
+
+ /// Audio rendering and encoder settings.
+ public AudioEncodingConfig AudioConfig { get; set; } = new();
+
+ /// Advanced options (random seed, spectrum processing, tile hiding, container, planet colors).
+ public AdvancedConfig AdvancedConfig { get; set; } = new();
+
+ /// Seconds of render time recorded after the end condition first holds (default 15).
+ public double DelayAfterEnd { get; set; } = 15;
+
+ /// Whether the judgement texts (hit accuracy texts) are shown during the render (scrHitTextManagerPatch). Default false.
+ public bool ShowJudgementText { get; set; } = false;
+
+ ///
+ /// Copies every value of into this object; the nested configs are copied value by value
+ /// into the existing nested objects. Does nothing when is null.
+ ///
+ public void CopyFrom(RenderConfig? source)
+ {
+ if (source == null) return;
+ RenderFPS = source.RenderFPS;
+ VideoFPS = source.VideoFPS;
+ RenderWidth = source.RenderWidth;
+ RenderHeight = source.RenderHeight;
+ DelayAfterEnd = source.DelayAfterEnd;
+ ShowJudgementText = source.ShowJudgementText;
+
+ VideoConfig.CopyFrom(source.VideoConfig);
+ AudioConfig.CopyFrom(source.AudioConfig);
+ AdvancedConfig.CopyFrom(source.AdvancedConfig);
+ }
+
+ /// Returns a deep copy (nested configs are new objects).
+ public RenderConfig Clone()
+ {
+ var clone = new RenderConfig();
+ clone.CopyFrom(this);
+ return clone;
+ }
+}
+
+/// Advanced render options.
+[SuppressMessage("ReSharper", "RedundantDefaultMemberInitializer")]
+public class AdvancedConfig
+{
+ ///
+ /// Seed for UnityEngine.Random set before the game scene loads, so random visual effects repeat between renders;
+ /// null leaves the random state unchanged.
+ ///
+ public int? RandomSeed { get; set; } = null;
+
+ ///
+ /// When true, AudioSource.GetSpectrumData is answered from the offline song audio at the render time
+ /// (AudioSpectrumGenerator), so audio-reactive visuals follow the rendered audio. Default true.
+ ///
+ public bool ProcessAudio { get; set; } = true;
+
+ ///
+ /// When true, the level's floor tiles (including hold meshes and the portal particles of the level's floors) and the
+ /// planets are hidden during the render, so only the background and decorations remain (scnGamePatch, scrFloorPatch,
+ /// RenderManager.OnLastUpdate). Default false.
+ ///
+ public bool NonTile { get; set; } = false;
+
+ ///
+ /// When true, the game's bloom (VideoBloom) computes its blur size as if the frame were 720 pixels high, so the
+ /// blur passes on the 198-pixel-high bloom buffer are the same as in a 720p frame at any render height
+ /// (VideoBloomPatch). Default false.
+ ///
+ public bool HighResBloomCorrection { get; set; } = false;
+
+ ///
+ /// When true, fixes in-game and render bugs during SetFramerate events (where objects disappear on the first frame
+ /// or parallax/tiles lag behind) by deferring manual camera rendering to the end of the frame after all LateUpdates.
+ /// Default true.
+ ///
+ public bool FixCustomFrameRate { get; set; } = true;
+
+ ///
+ /// When true, prevents floor tiles from being disabled when outside the camera frustum (scrFloor.OnBecameInvisible),
+ /// eliminating the 1-frame update lag/glitch when tiles enter the screen. Default false.
+ ///
+ public bool DisableTileCulling { get; set; } = false;
+
+ ///
+ /// When true, hides placeholder decorations (default tree-in-circle sprite) that failed to load or are empty.
+ /// Default false.
+ ///
+ public bool HideFailedDecorations { get; set; } = false;
+
+ /// File extension of the default output file name, without the dot (e.g. "mkv", "mp4"); selects the container.
+ public string FileExtension { get; set; } = "mkv";
+
+ /// Color of the fire (red) planet during the render; null keeps the user's setting. Serialized as "#RRGGBBAA".
+ [JsonConverter(typeof(ColorJsonConverter))]
+ public Color? firePlanetColor = null;
+
+ /// Color of the ice (blue) planet during the render; null keeps the user's setting. Serialized as "#RRGGBBAA".
+ [JsonConverter(typeof(ColorJsonConverter))]
+ public Color? icePlanetColor = null;
+
+ ///
+ /// Color of the third (wind, planetGreen) planet during the render (PlanetarySystemPatch); null keeps the game's color.
+ /// Serialized as "#RRGGBBAA".
+ ///
+ [JsonConverter(typeof(ColorJsonConverter))]
+ public Color? windPlanetColor = null;
+
+ /// Copies every value of ; does nothing when it is null.
+ public void CopyFrom(AdvancedConfig? source)
+ {
+ if (source == null) return;
+ RandomSeed = source.RandomSeed;
+ ProcessAudio = source.ProcessAudio;
+ NonTile = source.NonTile;
+ HighResBloomCorrection = source.HighResBloomCorrection;
+ FixCustomFrameRate = source.FixCustomFrameRate;
+ DisableTileCulling = source.DisableTileCulling;
+ HideFailedDecorations = source.HideFailedDecorations;
+ FileExtension = source.FileExtension;
+ firePlanetColor = source.firePlanetColor;
+ icePlanetColor = source.icePlanetColor;
+ windPlanetColor = source.windPlanetColor;
+ }
+
+ /// Returns a copy of this object.
+ public AdvancedConfig Clone()
+ {
+ var clone = new AdvancedConfig();
+ clone.CopyFrom(this);
+ return clone;
+ }
+}
+
+/// Video encoder settings (passed to FFmpegNativeEncoder.EncoderSettings).
+public class VideoEncodingConfig
+{
+ /// Video codec (default H.264). Also selects the audio codec (CodecUtil.AudioCodecMatch).
+ public Codec Codec { get; set; } = Codec.H264;
+
+ /// Bitrate control mode (default CBR).
+ public RateControlMode RateControlMode { get; set; } = RateControlMode.CBR;
+
+ /// Target video bitrate in kbps for CBR and VBR (default 30000 = 30 Mbps).
+ public int Bitrate { get; set; } = 30000;
+
+ /// Peak video bitrate in kbps for VBR, used when larger than Bitrate (otherwise 1.5 × Bitrate). Default 50000.
+ public int MaxBitrate { get; set; } = 50000;
+
+ ///
+ /// Quality value for CQP: lower is higher quality. Clamped to the range of the selected encoder; a negative value
+ /// selects 18. Default 18.
+ ///
+ // ReSharper disable once InconsistentNaming
+ public int QP { get; set; } = 18;
+
+ /// Keyframe interval in seconds (GOP length = round(effective video FPS × interval) frames, at least 1). Default 2.
+ public double KeyframeInterval { get; set; } = 2.0;
+
+ /// When true, only software (CPU) encoders are tried; hardware encoders are skipped.
+ public bool ForceSoftwareEncoder { get; set; }
+
+ /// Copies every value of ; does nothing when it is null.
+ public void CopyFrom(VideoEncodingConfig? source)
+ {
+ if (source == null) return;
+ Codec = source.Codec;
+ RateControlMode = source.RateControlMode;
+ Bitrate = source.Bitrate;
+ MaxBitrate = source.MaxBitrate;
+ QP = source.QP;
+ KeyframeInterval = source.KeyframeInterval;
+ ForceSoftwareEncoder = source.ForceSoftwareEncoder;
+ }
+
+ /// Returns a copy of this object.
+ public VideoEncodingConfig Clone()
+ {
+ var clone = new VideoEncodingConfig();
+ clone.CopyFrom(this);
+ return clone;
+ }
+}
+
+///
+/// Audio rendering and encoder settings. Non-positive values of the numeric settings read back as their defaults
+/// (48000 Hz, 2 channels, 256000 bps).
+///
+public class AudioEncodingConfig
+{
+ private int _audioSampleRate = 48000;
+ private int _audioChannels = 2;
+ private int _audioBitrate = 256000;
+
+ /// When true, the song and sound effects are mixed offline and encoded as an audio stream. Default true.
+ public bool RenderAudio { get; set; } = true;
+
+ ///
+ /// Output sample rate in Hz (default 48000). A rate the audio codec does not support in the mod
+ /// (CodecUtil.AvailableSampleRate) is replaced with 48000 when the render starts.
+ ///
+ public int AudioSampleRate
+ {
+ get => _audioSampleRate <= 0 ? 48000 : _audioSampleRate;
+ set => _audioSampleRate = value <= 0 ? 48000 : value;
+ }
+
+ /// Number of output audio channels (default 2).
+ public int AudioChannels
+ {
+ get => _audioChannels <= 0 ? 2 : _audioChannels;
+ set => _audioChannels = value <= 0 ? 2 : value;
+ }
+
+ /// Audio bitrate in bits per second (default 256000 = 256 kbps). Unit differs from the video bitrate (kbps).
+ public int AudioBitrate
+ {
+ get => _audioBitrate <= 0 ? 256000 : _audioBitrate;
+ set => _audioBitrate = value <= 0 ? 256000 : value;
+ }
+
+ /// Copies every value of ; does nothing when it is null.
+ public void CopyFrom(AudioEncodingConfig? source)
+ {
+ if (source == null) return;
+ RenderAudio = source.RenderAudio;
+ AudioSampleRate = source.AudioSampleRate;
+ AudioChannels = source.AudioChannels;
+ AudioBitrate = source.AudioBitrate;
+ }
+
+ /// Returns a copy of this object.
+ public AudioEncodingConfig Clone()
+ {
+ var clone = new AudioEncodingConfig();
+ clone.CopyFrom(this);
+ return clone;
+ }
+}
diff --git a/UI/Window/RenderConfigWindow.cs b/UI/Window/RenderConfigWindow.cs
index b305fcc..9b0d3e9 100644
--- a/UI/Window/RenderConfigWindow.cs
+++ b/UI/Window/RenderConfigWindow.cs
@@ -807,7 +807,7 @@ internal static class RenderConfigWindow
_disableTileCullingToggle = CreateToggleField(
ctx, CreateFieldSlot(advLeft),
labelKey: "",
- defaultValue: true,
+ defaultValue: false,
value: config.AdvancedConfig.DisableTileCulling,
toggleTextKey: "ui.render_config.disable_tile_culling",
id: "toggle_disable_tile_culling",