Custom desktop pets show scaling artifacts from forced sprite resampling

Open 💬 4 comments Opened May 2, 2026 by kalanihelekunihi

Custom Codex desktop pets can show jagged/aliased edges even when the installed spritesheet is clean and correctly sized.

I tracked this to the desktop avatar renderer, not the source image. Custom pet spritesheets use the same fixed atlas contract as bundled pets: 8 x 9 cells, 192x208 per cell, 1536x1872 total. The renderer then draws each cell into a smaller 7.04rem CSS element with background-size: 800% 900% and forces image-rendering: pixelated.

That means a clean 192x208 sprite is resampled to roughly 113x122 CSS pixels at a default 16px root font size. On high-DPI displays that can also map to fractional physical pixels. The forced pixelated resampling is fine for bundled pixel-art pets, but it introduces artifacts for smooth/high-resolution custom pets.

The fix should make avatar image-rendering configurable:

  • Keep bundled pets rendering as pixelated.
  • Default custom pets to auto.
  • Optionally add custom-pet metadata later so pet authors can choose auto or pixelated explicitly.

I have a patch proposal that changes the avatar root CSS to use a custom property:

image-rendering: var(--codex-avatar-image-rendering, auto);

Then the avatar component can set that custom property to pixelated for bundled assets and auto for custom spritesheets.

The public openai/codex checkout does not appear to include the desktop webview avatar renderer source, so I could not submit a source-level code PR against the public tree. The packaged desktop app evidence maps to webview/assets/codex-avatar-D82knaKt.css, webview/assets/codex-avatar-BpKnWN_W.js, and webview/assets/avatar-overlay-page-Dj9Zinq_.js in the app bundle.

View original on GitHub ↗

4 Comments

kalanihelekunihi · 3 months ago
diff --git a/webview/src/components/codex-avatar/codex-avatar.css b/webview/src/components/codex-avatar/codex-avatar.css
index 0000000..0000000 100644
--- a/webview/src/components/codex-avatar/codex-avatar.css
+++ b/webview/src/components/codex-avatar/codex-avatar.css
@@ -1,7 +1,7 @@
 .codex-avatar-root {
   aspect-ratio: 192 / 208;
   width: 7.04rem;
-  image-rendering: pixelated;
+  image-rendering: var(--codex-avatar-image-rendering, auto);
   background-repeat: no-repeat;
   background-size: 800% 900%;
 }
diff --git a/webview/src/components/codex-avatar/codex-avatar.tsx b/webview/src/components/codex-avatar/codex-avatar.tsx
index 0000000..0000000 100644
--- a/webview/src/components/codex-avatar/codex-avatar.tsx
+++ b/webview/src/components/codex-avatar/codex-avatar.tsx
@@ -1,3 +1,9 @@
+type AvatarStyle = React.CSSProperties & {
+  "--codex-avatar-image-rendering"?: "auto" | "pixelated";
+};
+
 export function CodexAvatar({
   assetRef,
   className,
@@ -10,8 +16,15 @@ export function CodexAvatar({
   const resolvedAssetRef = isBundledAvatarAssetRef(assetRef) ? assetRef : "codex";
   const avatarRef = useRef<HTMLDivElement>(null);
 
+  const isCustomAvatar = spritesheetUrl != null;
+  const imageRendering = isCustomAvatar ? "auto" : "pixelated";
   const backgroundImage = `url(${spritesheetUrl ?? BUILT_IN_AVATAR_SPRITESHEETS[resolvedAssetRef]})`;
-  const style = { backgroundImage };
+  const style: AvatarStyle = {
+    "--codex-avatar-image-rendering": imageRendering,
+    backgroundImage,
+  };
 
   useAvatarAnimation({
     avatarRef,
@@ -25,6 +38,7 @@ export function CodexAvatar({
       data-avatar-asset-ref={resolvedAssetRef}
       data-avatar-state={state}
       data-testid="codex-avatar"
+      data-avatar-rendering={imageRendering}
       style={style}
       aria-hidden="true"
     />
jazzyalex · 3 months ago

I am seeing a similar rendering/scaling issue, but it is not limited to custom pets. It reproduces for all built-in mascots I tried.

Environment:

  • Platform: macOS
  • Codex Desktop: current build installed via the desktop app updater
  • Pets tested: built-in mascots, including Seedy

Observed:

  • The mascot appears, but it renders very tiny and visibly pixelated/rough.
  • It looks like the sprite is being resampled or drawn at the wrong scale.
  • The issue is visible in the normal Codex Desktop chat/pet overlay surface, not only in a custom imported pet.

Expected:

  • Built-in mascots should render crisply at the intended overlay size.
  • If scaling is needed, it should preserve sprite quality and use the correct display scale.

Screenshot:
/Users/alexm/Downloads/Screenshot 2026-05-02 at 1.15.23 PM.png

kalanihelekunihi · 3 months ago

Yep, confirmed that it also affects the official ones.
Wasn't immediately clear as "maybe they were intended to look like that", but comparing the actual sprite sheets vs the rendered output it's apparent that it affects them all.

jazzyalex · 3 months ago

I ran into this with a custom Desktop pet and put together a temporary workaround others can try while the renderer bug is still open:

https://gist.github.com/jazzyalex/6128e1127c3df27194bb23055363af9d

The gist includes:

  • install-boba-small.py: installs a ready-to-use sample custom pet named Boba Small.
  • make-crop-safe-pet.py: code to rebuild an existing custom pet as a crop-safe atlas.
  • README with install/adaptation steps.

What it does: keeps the Codex Desktop spritesheet dimensions at 1536 x 1872 and the built-in 8 x 9 atlas layout, but scales each 192 x 208 frame down inside its cell. This does not fix the product bug; it just works around the current forced scaling/clipping behavior by giving each frame more transparent margin.

Install test:

python3 install-boba-small.py --select

Then restart Codex Desktop and select Boba Small in Settings if it is not already selected.