Skip to content

Code Conventions

Taiizor edited this page Jun 5, 2026 · 2 revisions

Code Conventions

Sucrose enforces a tight, consistent code style across its many projects, and one convention in particular — the namespace-alias acronym rule — is so pervasive that code which ignores it will look wrong immediately. This page documents that aliasing rule, the directory conventions inside shared projects, the .editorconfig style rules (which are build errors, not suggestions, because EnforceCodeStyleInBuild=true), and the project-wide language settings. Follow these exactly when contributing.

Contents

Namespace alias convention (critical)

Every Sucrose (and Skylark) namespace import is aliased to a short uppercase acronym formed from the first letter of each namespace segment. Never use fully-qualified names, and never use a bare using for a Sucrose namespace. Real examples:

using SHC = Skylark.Helper.Culture;                       // S-H-C
using SMMCG = Sucrose.Memory.Manage.Constant.General;     // S-M-M-C-G
using SMMI = Sucrose.Manager.Manage.Internal;             // S-M-M-I
using SMMRG = Sucrose.Memory.Manage.Readonly.General;     // S-M-M-R-G
using SSDECT = Sucrose.Shared.Dependency.Enum.CompatibilityType;
using SSSHP = Sucrose.Shared.Space.Helper.Processor;
using SPVPLP = Sucrose.Portal.Views.Pages.LibraryPage;

Rules:

  • The alias is the first letter of each namespace segment, uppercased.
  • Collisions are disambiguated by appending more letters from the final segment. For example, SSDECT is used for Sucrose.Shared.Dependency.Enum.CompatibilityType, distinguishing it from Sucrose.Shared.Dependency.Enum.CommandType (which would otherwise also acronym to SSDEC).
  • using directives go outside the namespace.

When you write new code, derive aliases the same way and reuse the existing alias for a namespace if the file already imports it elsewhere in the codebase.

Directory conventions

Files inside shared projects are organized by role (see Shared Item Projects for the full list of projects):

Folder Contents
Enum/ Enum types
Helper/ Static helper/utility classes
Manage/ Configuration/state management
Manage/Manager/ Settings-manager classes
Manage/Readonly/ Read-only constants
Struct/ Struct types
Extension/ Extension methods
Services/ Pipe/signal service classes (in .Pipe, .Signal)
Event/, View/ Used in engine shared projects (XAML views and event handlers)

Style rules (.editorconfig)

EnforceCodeStyleInBuild=true is set in Directory.Build.props, so .editorconfig violations fail the build locally. The key rules:

Rule Setting
Indentation 4 spaces (indent_style = space, tab_width = 4)
Line endings CRLF (end_of_line = crlf)
XML files indent 2 spaces ([*.xml] indent_size = 2)
Namespaces block-scoped (csharp_style_namespace_declarations = block_scoped)
Type/method/property/event naming PascalCase
Field naming camelCase
Interfaces prefixed I (dotnet_naming_style.begins_with_i.required_prefix = I)
using placement outside the namespace (csharp_using_directive_placement = outside_namespace)
Types explicit types, not var (csharp_style_var_* = false)
Expression-bodied members Yes for accessors/properties/indexers/lambdas; No for methods/constructors/operators/local functions
Operator wrapping operator_placement_when_wrapping = beginning_of_line
Preferred patterns pattern matching, switch expressions, null propagation/coalescing, compound assignment, simplified interpolation
Suggested (not enforced) primary constructors, readonly structs, UTF-8 string literals (all :suggestion)

Two notes about .editorconfig:

  • It contains a full duplicate [*.vb] naming block (Turkish-named rules). VB is not used in the app — it is legacy/IDE-generated and can be ignored.
  • Because CI only compiles 7 Library projects (see Building From Source), CI will not catch a style violation in an engine, the Portal, or a shared project — but your local build will, since enforcement is on.

Project-wide language settings

From Directory.Build.props:

  • Nullable is disabled project-wide.
  • ImplicitUsings is enabled.
  • LangVersion is preview (C# preview language features are available).
  • Optimize=false is set globally (even for Release).
  • CS8632, WFO0003, SYSLIB0014 are suppressed.

The settings pattern

Settings are the most common thing contributors add, and they follow a strict pattern. Settings live in the Sucrose.Manager class library (src/Library/Sucrose.Manager/Manage/*.cs), grouped by area: General, System, Personal (Private), Library, Portal, Engine, Backgroundog, Aurora, Cycling, Donate, Hook, Update, Warehouse, Internal. Each setting is a static property that reads/writes through a SettingManager with a constant key and an inline default:

public static string Culture => SMMI.GeneralSettingManager.GetSetting(SMMCG.Culture, SHC.CurrentUITwoLetterISOLanguageName);
public static int RunStartup => SHS.Clamp(SMMI.GeneralSettingManager.GetSettingStable(SMMCG.RunStartup, 0), 0, 10);
public static bool TelemetryData => SMMI.GeneralSettingManager.GetSetting(SMMCG.TelemetryData, true);
  • Setting keys are constants in Sucrose.Memory.Manage.Constant.* (aliased SMMCG, etc.).
  • The manager instance comes from Sucrose.Manager.Manage.Internal (SMMI).
  • Use GetSettingStable plus SHS.Clamp for bounded integers.
  • Defaults are passed inline to GetSetting/GetSettingStable.

See the full recipe for adding a setting in Extending Sucrose, and how the JSON is persisted in Settings Persistence.

Example file header

A representative file header obeying the aliasing rule and using-outside-namespace convention:

using SHC = Skylark.Helper.Culture;
using SMMCG = Sucrose.Memory.Manage.Constant.General;
using SMMI = Sucrose.Manager.Manage.Internal;

namespace Sucrose.Manager.Manage
{
    public static class General
    {
        public static string Culture => SMMI.GeneralSettingManager.GetSetting(SMMCG.Culture, SHC.CurrentUITwoLetterISOLanguageName);
    }
}

See also

Home

Getting Started

Wallpaper Types

Using Sucrose

Settings Reference

Creating Wallpapers

Engine Reference

Automation & Command Line

Architecture & Internals

Data, Files & Diagnostics

Building & Contributing

Help & Support

Clone this wiki locally