Repository navigation
Contributing
A summary of CONTRIBUTING.md: where code goes, the rules, tests, and commits. Read Architecture first. Each rule exists because breaking it once hid a real bug.
See Building and running: Xcode 26.3+, scheme OpenWallpaperEngine, Debug and Release sign with Apple Development (don't commit your own team), no tools to install, no WE assets in the repo.
| You are adding… | Put it in… |
|---|---|
| A new WE file format or field |
Scene/Format/: plain Decodable models, no side effects |
| Anything that reads a value that can be user-, script- or animation-bound | Resolve it through Scene/Values; never read the raw JSON |
| Shader translation, reflection, caching | Scene/Shaders/ |
| Metal drawing, render passes, render targets | Scene/Rendering/ |
| A SceneScript API member |
Scene/Scripting/ (JS in a bundled .js resource, not a Swift string) |
| A settings control or Scene Editor (Live) UI |
Settings/ or Scene/UI/; the view model next to its view |
| Anything used by several features (logging, settings, asset paths) | Core/ |
One type per file unless the types are tiny and private. A file over about 600 lines, or a function over about 80, needs a reason; split along a real seam.
-
Implement WE's behaviour, not a look-alike. No native approximations of WE effects, invented parameter names or remapped ranges. No special cases keyed on a layer, effect, file or property name (
"cloud","clock","snow"…). If a wallpaper renders wrong, find the missing general feature. See WE-fidelity principles. -
Fail loudly. No
try?on file IO, decoding, shader translation or pipeline creation:do/catchand log once, with the wallpaper, layer, effect and reason.try?is fine for genuinely optional lookups, with a comment. Decode collections element by element. -
No new global state. No new
static let shared, noAppDelegate.sharedfrom engine code, noUserDefaults.standard. UseUserDefaults.appandAppStorageLocation.current. Pass dependencies in; state belongs to a wallpaper instance. -
Typed keys. No new
"_owe_…"string keys. -
Logging through
OWELog:.debugper frame,.infolifecycle,.errorfailures. Noprintor rawNSLog; nothing every frame at.infoor above. -
Caches are versioned. Keyed on inputs and a revision constant bumped when the producing code changes:
ShaderVariantTranslator.revision(ShaderVariantCacheTestsenforces it). -
Concurrency. UI types are
@MainActor. Shared mutable state has an owner (an actor, or one documented lock). Nononisolated(unsafe)without a comment saying why it's safe. - Keep dead code out. Delete it; don't comment it out or keep an unused alternate path.
-
UI text goes through
Localizable.xcstrings, translated into all 15 languages with the glossary's terms. See UI, localization and settings storage.
- Tests go in
OpenWallpaperEngineTests; fixtures inTests/Fixtures/. Every fix or feature comes with a test. Known gaps use strictXCTExpectFailure. - Tests never touch the user's state or assets (
OWE_ASSETSonly). -
Launch dev copies isolated with
OWE_ISOLATED_STATE. -
Before merging, a PR passes
Scripts/ci-local.sh(the local gate), run withOWE_ASSETSandOWE_SLOW_TESTS=1.
Details: Testing.
-
Conventional Commits:
fix:,feat:,perf:,refactor:,build:,docs:,test:(with a scope, e.g.fix(particles): …). - Small, single-purpose commits. File moves and renames go in their own commit with no logic changes and must build, so review and
git log --followstay useful. Asset or vendor drops never share a commit with code. - The PR description says what changed, why, and how it was verified.
- The project uses folder-synced groups, so putting a new file in the right folder is enough.
-
Never add Wallpaper Engine files to the repository, the app or
Tests/Fixtures.
User guide: Legal and credits
Open Wallpaper Engine · GPL-3.0 · Released by Deepratna Awale · Based on Open Wallpaper Engine by Haren Chen and MrWindDog · Not affiliated with Wallpaper Engine or Valve · Home · User Guide · Developer Guide