Delve into the world of graphics and game development. Discuss creating stunning visuals, optimizing game mechanics, and share resources for game developers.

All subtopics
Posts under Graphics & Games topic

Post

Replies

Boosts

Views

Activity

Core Animation Background Thread CATransaction
Hey everyone 👋 I'm trying to initialize a part of a CALayer hierarchy on a background thread and then attach the root of that hierarchy to a CALayer that backs a UIView. The motivation is to keep the main thread responsive when constructing a complex layer hierarchy. This isn't a case where I'm creating two or three layers and then switching back to the main thread. The hierarchy can potentially contain a large number of layers, with animations being created/configured for those layers as well. My first approach was to create and configure the layers entirely on a background thread. While the output might be the expected one (not always), CoreAnimation emits an assertion along the lines of: "Modifications to the layer tree from a background thread may not be committed" (or something like this). This makes sense to me if implicit CATransaction is thread-local. In that case, the implicit transaction opened by the layer modification on the background thread would not be part of the transaction that is already open on the main thread. Therefore, committing the main-thread transaction would not commit the changes made on the background thread. My second approach was to explicitly create and commit a CATransaction on the background thread. This appears to be accepted by Core Animation's threading model, but I'm seeing unreliable results. Sometimes parts of the hierarchy are missing, and in other cases the hierarchy is present but the animations don't appear to run at all. I do understand that this is private behavior of the framework, but I wanted to know if what I am trying to achieve is possible and, if so, what the solution would be (obviously if you can share this information). Besides this, I would also like to know what behavior CATransactions have when they are created on different threads. What I mean by this is that the transactions work as a stack, and the changes are committed when the stack is empty. Does this behavior still apply when having transactions on different threads? Any weird behaviours that might appear between transactions operated on main vs background threads? Thank you! Vlad.
2
0
24
7m
Behaviour of a 0-value `accelerationStructureID`
When constructing a MTLIndirectAccelerationStructureInstanceDescriptor, one specifies an accelerationStructureID. In the equivalents in both Vulkan and DirectX12, one can set it to zero to be an "inactive" instance. However, on Metal, this field does not appear to have any documentation, and thus it is difficult to figure out if there is similar behavior (and no other Metal documentation seems to mention this). Does setting this field to 0 (i.e. null) disable the instance? If not, is there any other way to have an equivalent effect?
5
0
1.5k
4h
CGSetDisplayTransferByTable is broken on macOS Tahoe 26.4 RC (and 26.3.1) with MacBook M5 Pro, Max and Neo
The CGSetDisplayTransferByTable() is not working on the latest round of Mac hardware, namely the MacBook Neo (external display), MacBook M5 Pro (both built-in and external display) and possibly the M5 Max. All tested apps (BetterDisplay, MonitorControl, f.lux, Lunar) exhibit the very issue both in macOS Tahoe 26.3 and macOS Tahoe 26.4 RC. Tested on multiple Macs and installations on the MacBook Neo and MacBook M5 Pro. This issue breaks several display related macOS apps. Way to reproduce the issue using an affected app: Install the app BetterDisplay (https://betterdisplay.pro) Launch the app, open the app menu, choose Image Adjustments and try to adjust colors. Adjustments take no effect Way to reproduce the issue programmatically: Attempt to use the affected macOS API feature: https://developer.apple.com/documentation/coregraphics/cgsetdisplaytransferbytable(::::_:) Here are the FB numbers: FB22273730 (Filed this one as a developer on an unaffected MBP M3 Max) FB22273782 (Filed from an affected MBP M5 Pro running 26.4 RC, with debug info attached)
10
5
4.5k
2d
Stress-testing Metal compute pipelines using Autolykos workload characteristics
I have been using a small macOS research project to exercise Metal with a workload that differs from rendering and dense machine-learning kernels. Autolykos v2 is useful for this because it combines a large, height-dependent working set with pseudo-random reads, integer-heavy hashing, sustained execution, and periodic replacement of the dataset. The project happens to be a miner, but my question here is strictly about Metal compute behaviour. On the Apple M4 system used for these measurements, the full dataset contained 216,430,305 elements of 32 bytes each: 6.93 GB, or about 6.45 GiB, held in a .storageModePrivate buffer. For every nonce, the search kernel: computes an index seed, performs 32 pseudo-random 32-byte dataset reads, accumulates the eight 32-bit limbs into a 256-bit sum, and applies a final BLAKE2b compression and target comparison. The normal dispatch uses 128 threads per threadgroup. The wider pipeline also builds the next height's dataset in chunks on a separate command queue while search continues, and keeps two search command buffers in flight. I record command-buffer wall time, gpuStartTime/gpuEndTime, unions of overlapping intervals, and thermal state. To estimate the ceiling imposed by the random gathers, I added a non-consensus microbenchmark. It retains the normal seed calculation, index distribution, all 32 dataset reads, and the complete accumulation, but omits the final BLAKE2b compression. The accumulated result remains observable through a comparison, so the gather loop cannot simply disappear. I expected this stripped kernel to be at least slightly faster. Instead, an order-balanced campaign on an M4 produced: complete search kernel: 3.108 million nonces/s median active throughput gather-only kernel: 2.952 million nonces/s ratio: 105.3% All four same-round ratios were between 103.18% and 105.74%. Each measured run used the full dataset, a 30-second search interval, an excluded warm-up, and a start-temperature gate below 50 °C. Both compute pipeline states reported maxTotalThreadsPerThreadgroup == 1024. My conservative conclusion was not to pursue speculative register-pressure or manual memory-level-parallelism rewrites. The access pattern appears sufficiently dominant, while the supposedly simpler microbenchmark may have changed the compiled pipeline in a way that makes it a poor upper-bound model. My questions are: Can removing the trailing arithmetic legitimately make a memory-latency-heavy Metal kernel slower by changing register allocation, instruction scheduling, or the amount of useful latency hiding? Or would you first suspect a flaw in this kind of gather-only benchmark construction? Also, which Metal GPU counters are the most reliable way to distinguish memory-latency saturation from register-limited occupancy in a long-running compute kernel? I am looking at compute occupancy, buffer and ALU limiters, bandwidth, and cache behaviour, but maxTotalThreadsPerThreadgroup alone is clearly too coarse to explain the result. This is one hardware-specific observation rather than a general claim about Apple GPUs. If useful, I can reduce the workload to a smaller standalone reproducer. The source code, benchmark driver, and complete campaign report are available here: https://github.com/giffeler/ergometal The detailed measurements and validation procedure for this comparison are documented here: https://github.com/giffeler/ergometal/blob/main/Benchmarks/2026-08-15-search-gather-ceiling-ab.md
0
0
583
2d
Metal-cpp usability issue with MTL::Buffer and MTL::ResidencySet
I know this might be a peeve of mine, but looking into programming a simple Metal4 Compute Shader example, essentially updating the Performing Calculations on a GPU example code to work with CPP and Metal4. I found that MTL::Allocation and MTL::Buffer pointers can't be used interchangeably when you are trying to add allocations to a MTL::ResidencySet, this is forcing you to: Know by heart that they inherit from each other and that you can just cast them (this is a bit suspicious though, it did work for me). Forcefully either C-cast or reinterpret_cast the MTL::Buffer pointer to a MTL::Allocation pointer as the MTL::ResidencySet will only accept that type. I might as well just be plain wrong about how this is used, any tips on correct usage in that case? Is there any expectation to either provide a typecast operator or add inheritance to support the expected behaviour seen in Swift and ObjC, which is just passing the thing? Opened a report with # FB24534953 with some extra information. Bear in mind that the example code uses Premake5, but it can generate an Xcode solution easily.
0
0
591
3d
On-screen RealityView starves CADisplayLink to 30 Hz on ProMotion (Mac Catalyst)
FB24536235 On Mac Catalyst under macOS 27, a plain CADisplayLink asking for CAFrameRateRange(minimum: 60, maximum: 60, preferred: 60) gets serviced at 30 Hz for as long as a RealityView is on screen in the same window. The link does nothing per tick but count, so there's nothing of mine to blame it on. RealityKit's own statistics overlay reads 60.41 fps in the same frame. Click a segmented control that removes the RealityView and the same link goes straight back to 60. Nothing else changes. That's the whole reproducer, and I've attached it to the radar. It only happens while the display panel is in ProMotion mode. Set the built-in to a fixed 60 Hz and it's correct again. With an external 60 Hz display attached the roles swap: the built-in is fine and the external drops to somewhere between 18 and 30, and setting the built-in to 60 Hz fixes that one too without touching the external's own settings. A raw MTKView presenting continuously at 60, at 120, and on a 120 Hz link presenting every second callback are all fine, so it isn't continuous presentation and it isn't the requested rate. It's RealityKit specifically. Worth knowing if you're testing: RealityView on Catalyst is an ARView underneath, so both paths give you the same answer. This is VERY rough for anything that puts RealityKit next to a UI. In an editor that's the sidebar, the inspector, gizmos, drag handles, every display-link-driven or UIKit animation in the window running at half rate around a viewport that stays smooth. Likely Related to FB24091347, which is the same defect seen as SwiftUI scroll judder. If you can reproduce either, please file a duplicate. Attached two screenshots; first with promotion enabled, second with promotion off. PLEASE fix this, it drives me crazy and there seems to be no workaround. On release day of macOS 27 our app will likely be blamed for it by users and my hands are tied. Thank you!
0
0
144
3d
Xcode 27.0 b5, macOS 26.6.1, Metal build fails: symbols not found for air64_v28
I've just downloaded the Xcode 27.0 beta 5 on a macOS 26.6.1 machine and tried to build my app (which includes Metal CoreImage kernels). I'm met with a new (to me) error; /Users/…/Developer/…/air-lld:1:1 symbol(s) not found for target 'air64_v28-apple-macosx26.0.0' and from the build log; air-lld: warning: ignoring file '/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/CoreImage.framework/Versions/A/CoreImage.metallib', file AIR version (2.9) is bigger than the one of the target being linked (2.8) air-lld: error: symbol(s) not found for target 'air64_v28-apple-macosx26.0.0' metal: error: air-lld command failed with exit code 1 (use -v to see invocation) I have no MTL_LANGUAGE_REVISION in my build settings. If I add one, with value Metal41 the app builds fine, but crashes at runtime as Metal 4.1 isn't supported on macOS 26. I imagine this is a beta Xcode and or macOS SDK bug, is there a workaround?
1
0
1.1k
5d
Can Materials not assigned to entities be retrieved from a .reality file?
like: let mat = try await ShaderGraphMaterial(named: "matname", from: "reality") currently I use an USD file with materials like so and it works: try await ShaderGraphMaterial(named: "/Root/matname", from: "file.usda", in: appBundle) when i try it with .reality i get "NameNotFound". so is it possible or do i have to have a bunch of dummy entities with my materials assigned so i can find the entity>components>material? or what's the best way to author materials in RCP3 for quick access in realitykit?
3
0
1.8k
5d
Is there a working example for Fog post effect for non AR game?
i can read the depth and mix it with the rendered image and get a linear fog effect but I can't get a true radial fog. I've been going back and forth with gemini and chatgpt and neither can do it. gemini got me a radial gradient but it's jsut projected flat across all 3d objects. it's been all day trial after trial this is what gives me the flat radial gradient using namespace metal; struct DepthFogEffectConstants { float4 fogColor; float density; // We no longer need the inverse projection matrix here! }; kernel void depthFogKernel( texture2d<half, access::read> inColor [[texture(0)]], texture2d<float, access::read> inDepth [[texture(1)]], texture2d<half, access::write> outColor [[texture(2)]], constant DepthFogEffectConstants& uniforms [[buffer(0)]], uint2 gid [[thread_position_in_grid]]) { float w = outColor.get_width(); float h = outColor.get_height(); if (gid.x >= w || gid.y >= h) { return; } half4 originalColor = inColor.read(gid); float rawDepth = inDepth.read(gid).r; // 1. Guard check for empty backgrounds/skyboxes if (rawDepth <= 0.00001f || rawDepth >= 0.9999f) { outColor.write(originalColor, gid); return; } // 2. Map screen pixels from the center of the lens (-1.0 to 1.0) float2 screenPos = float2( ((float(gid.x) / w) * 2.0f) - 1.0f, 1.0f - ((float(gid.y) / h) * 2.0f) ); // 3. Since rawDepth is already acting as a view-space Z proxy, // we use it to calculate the true spherical ray distance from the lens center. // The hypotenuse of screen offset (X, Y) and depth (Z) gives the radial distance. float radialDistance = sqrt(screenPos.x * screenPos.x + screenPos.y * screenPos.y + rawDepth * rawDepth); // 4. Calculate exponential fog matching your visual test float fogFactor32 = exp(-radialDistance * uniforms.density); half fogFactor = half(clamp(fogFactor32, 0.0f, 1.0f)); half4 fogColor = half4(uniforms.fogColor); // Mix and write colors out cleanly half4 finalColor = mix(fogColor, originalColor, fogFactor); outColor.write(radialDistance, gid); } in this code i'm just outputing the radial distance to see that calculation and it's just wrong. i don't know what to do anymore
1
0
1.5k
1w
macOS 27 beta: ProMotion refresh cadence is unstable, causing constant scroll judder
FB24091347 On macOS 27.0 beta (26A5388g), MacBook Pro M4 Pro, the built-in ProMotion display never settles on a stable refresh cadence. Scrolling in SwiftUI judders constantly. The same app binary was smooth on macOS 26, and is smooth on a 120 Hz ProMotion iPad. I captured two 60-second Instruments traces — same app, same scene, same scrolling, no external display — changing only the display's refresh-rate setting. On ProMotion the vsync interval standard deviation is 4.093 ms across six different cadences, mostly flip-flopping between 120 Hz and 60 Hz. Forced to a fixed 60 Hz it drops to 0.391 ms with a single cadence. The app presented an identical 59 fps median in both runs — frame production is perfectly steady, the display just holds each frame for an unpredictable length of time. That's what makes this nasty: it's invisible to every frame-rate metric, so it looks like the app got slow when nothing about the app changed. I spent most of a day profiling my own code before realising the app was never the problem. Workaround: force the built-in display to 60 Hz. Worth noting, because it complicates the picture: attaching a 60 Hz Studio Display makes the built-in smooth, but the Studio itself then judders — despite its own vsync cadence measuring perfectly stable. So refresh rate alone isn't the whole story, and there may be a second mechanism. The clean, reproducible, single-variable result is the ProMotion vs forced-60 Hz comparison on the built-in panel. If you can reproduce this on an M-series MacBook Pro on 27 beta, please file a duplicate referencing FB24091347.
4
0
826
1w
D3DMetal: crash on Cmd+Tab out of a fullscreen D3D11 app — FindClosestMatchingMode reads modes[count-1] (FB24422691)
Filed as FB24422691. Posting here as well because the crash leaves no usable stack in the application's own crash handler, and searching for "0x1BFFFFFFE4" or "FindClosestMatchingMode" returns nothing anywhere, so this may save someone else the debugging. SYMPTOM A Direct3D 11 Windows application (Unity 2021.3) running fullscreen under Game Porting Toolkit dies when you Cmd+Tab out of it and back in. Exclusive and borderless fullscreen both crash; windowed never does. It is intermittent: on my machine it takes 5 to 9 switches. Always the same signature: EXCEPTION_ACCESS_VIOLATION (0xC0000005), reading address 0x1BFFFFFFE4, faulting RIP at D3DMetal+0xFA8F. Identical in all 16 crash reports I collected, which is what makes it a deterministic underflow rather than heap corruption. CAUSE D3DMetal's DXGIOutput::FindClosestMatchingMode calls GetDisplayModeList and then reads the last element of the list without checking the count or the buffer pointer: call DXGIOutput::GetDisplayModeList(...) ; count returned in [rsp+0x3c] mov eax, [rsp+0x3c] ; eax = count dec eax ; 0xFFFFFFFF when count == 0 lea rcx, [rax + 8rax] ; rcx = 28 * eax (28 = sizeof DXGI_MODE_DESC) lea rcx, [rcx + 2rcx] add rcx, rax mov rax, [r14 + rcx] ; reads modes[-1] 28 * 0xFFFFFFFF = 0x1BFFFFFFE4, and r14 (the mode buffer) is NULL on that path, so the read lands exactly on the address seen in the crash reports. WHY THE LIST IS EMPTY winemac.drv rebuilds the display device list on every application activation. With WINEDEBUG=+display, four Cmd+Tab activations produce exactly four full rebuilds (macdrv_UpdateDisplayDevices: GPU count, adapter, monitor). An application that queries the closest matching mode mid-rebuild gets zero modes back. Fullscreen makes that query on focus changes; windowed does not, which is exactly why windowed never crashes. The empty-list condition is not unique to this race: GetDisplayModeList has also been reported returning 0 modes for DXGI_FORMAT_R16G16B16A16_FLOAT on D3DMetal 2.1 (github.com/vec715/enfusion-dxgi-fix). DXVK and DXMT both return DXGI_ERROR_NOT_FOUND for an empty list instead of dereferencing it. MEASUREMENTS Alternating applications automatically and verifying every focus change: borderless fullscreen: crash after 5, 6, 6 and 8 switches (4 of 4 runs) exclusive fullscreen: crash after 9 switches windowed: 105+ switches, no crash As a control I patched a local copy of D3DMetal so the read is skipped when count == 0 or the buffer is NULL, keeping the requested mode. Same machine, same setup: 140 switches in fullscreen with no crash, and the unpatched binary crashed again after 8 switches immediately afterwards. VERSIONS The unchecked read is present in both D3DMetal builds I have: 2.0 (built for macOS 13.3) at 0x1453A, and 3.0 (built for macOS 15.4) at 0xFA82. Environment: macOS 26.5.2 (25F84), Apple M5, D3DMetal 3.0 inside Game Porting Toolkit, Wine 7.7, 64-bit prefix, fullscreen at 2560x1664 with winemac.drv Retina mode on. WORKAROUND UNTIL IT IS FIXED Run the application windowed, or interpose a dxgi proxy DLL that returns DXGI_ERROR_NOT_FOUND from FindClosestMatchingMode when the mode count is 0. Suggested fix: return DXGI_ERROR_NOT_FOUND from FindClosestMatchingMode / FindClosestMatchingMode1 when the count is 0 or the buffer is NULL, instead of indexing modes[count-1].
0
0
85
1w
Photogrammetry with Object masks hangs and terminates with masks of objects
[PhotogrammetrySample]) with objectMask set and traps on my ios26.5.2, see the attached screenshot on feedback FB24379913 , it gets to the function and hangs . Even the folder reconstruction with lazy sequence as recommended from your video sample also doesn;t complete as it can't find alignment and displays the CoreOC.PhotogrammetrySession.Error error 6 means alignment failed. What can be done or do you guys expose any functions that can be used to check or trace or handle these internally The ObjectMasks are actually segmentation masks from an segmentation algorithm I will appreciate a timely response and willing to provide more clarity and informations, thank you so much for your understanding
2
0
617
1w
MPS bf16 softmax produces NaN on M5 Max (regression from M4) — breaks all on-device diffusion inference
Metal Performance Shaders produces from bf16/fp16 softmax for large attention tensors on , forcing the entire local generative-AI ecosystem to fall back to fp32. This is a . Environment Minimal reproduction Decomposed softmax on MPS — diffs = x - maxes produces NaN even though every element is identical (result should be all zeros): Real-world impact Running ComfyUI (the dominant local generative-AI UI) on M5 Max: Root cause (per PyTorch MPS maintainers) PyTorch maintainers (@drisspg, @albanD) have traced this to in the MPS/MPSGraph fused kernels. The NaN originates in the x - maxes subtraction inside softmax, then propagates through the attention block and the entire network. PyTorch cannot fix this — it is in the Metal/MPS kernel layer. Not isolated The M4-era fix ("fixed on macOS 15.1") did not survive onto M5, indicating the MPS fused-kernel precision fix was either reverted or not ported to the M5 GPU architecture. Request
1
0
832
1w
PhotogrammetrySession(input: [PhotogrammetrySample]) Hangs or terminates
Xcode hangs when I call PhotogrammetrySession(input: [PhotogrammetrySample]) with objectMask set and traps on some devices, see the attached screenshot, it gets to the function and hangs. Even the folder reconstruction also doesn't complete as it can't find alignment and displays the CoreOC.PhotogrammetrySession.Error 6 and I understand to mean alignment failed. In this case it failed while object masking was ON, so RealityKit could not find enough consistent feature tracks inside the masked pixels across the image set. What can be done or do you guys expose any functions that can be used to aid, or handle these internally, can't find any internally. The ObjectMasks are actually segmentation masks from an ML algorithm . To replicate try calling PhotogrammetrySession(input: [PhotogrammetrySample]) with contentsOf as captured on your documentation, even with like 30 image set or is there something I'm missing. I will appreciate a timely response and willing to provide more clarity and informations, thank you so much for your understanding
4
0
2.6k
1w
Metal Shader Converter thread safety
Hello Apple! We've got offline shader compilation from HLSL -> Metallib using DXC -> SPIR-V -> metal.exe. This works okay for the most part, but it requires the creation of intermediate files to pass to/from the metal.exe process and we've had some issues with metal.exe sometimes not launching (probably our fault). Then we noticed Metal Shader Converter (MSC) exists and has a DLL - this looks way better since there's no need to launch processes or store intermediate files. However, upon trying to replace metal.exe with it I quickly ran into rampant heap corruption. I was surprised because the docs claim this: Each thread in your program needs to create its own instance of IRCompiler to avoid race conditions. But once I start calling IRCompilerAllocCompileAndLink in parallel all hell breaks loose, whether or not each thread has its own IRCompiler. I figured I must be doing something wrong, so I removed my attempt and compiled DXC locally with the MSC integration and encountered the exact same heap corruption. So I'm inclined to think the library isn't actually thread safe, but I'm wondering if there's something I'm missing? I tried all 3 versions of MSC just in case it was a problem with 3.0, but I got the same result each time. The only way to make it work was to surround compilation with a mutex, which makes its use pointless in our case.
2
0
1.2k
1w
Lockpicking - Steuerung
Hallo, mein Spiel Lockpicking ist exakt gleich programmiert für Android und Apple. Warum sehen die links rechts Tasten bei beiden Apps verschieden aus ? https://apps.apple.com/us/app/lockpicking/id6793054294
1
0
383
1w
view protocol update ?
Hello ! Thank you guys for all the hard work you are doing on RealityKit For now in my studying Im trying to understand, in general, what will cause my Main app view to redraw everything? Or any view? If i have a struct that use the view protocol, and that struct is being called inside RealityView on the main app, or outside a reality view within a ZStack on the main app, if this view updates, does this will cause everything in my main app view to redraw as well? Or is it only true to @State variables of the main app? or the @State variables of the external view i try to implement? and what about @Observable ? Is there an accurate table that tells the developer what will cause a redraw of things? (not only the things the logic asks for, but all things sitting idle within the view) I try to understand how to separate UI updates, to avoid full redraw of things that havent been changed. to minimize UI compute in my games Before i play around with instruments i need to understand the general architecture.. if i work in a way that is counter designed to the way reality kit should work then the instrument results will not make sense to me. so i feel like i should ask you guys first. Depending on your answer i will know how to arrange my data in my game. And how to design and instantiate all my views Thanks
1
0
972
2w
Game Center matchmaking fails for all non-default users on Apple TV — no IDS registration for secondary users (FB24156316)
Game Center matchmaking fails for all non-default users on Apple TV — no IDS registration for secondary users (FB24156316) On a multi-user Apple TV (tvOS 26.5, Apple TV 4K 3rd gen), Game Center real-time matchmaking fails for every user except the default user, in every app I've tested — including Apple Arcade titles. Filed as FB24156316 with full logs and sysdiagnose; posting here for visibility and in case anyone has shipped multi-user GC multiplayer on tvOS successfully. My game adopts com.apple.developer.user-management (runs-as-current-user-with-user-independent-keychain). The entitlement itself works: on a secondary user's profile the app runs under that user's persona and GKLocalPlayer authenticates as them — the welcome banner shows the right account. But any GKMatchmakerViewController quickmatch hard-fails within ~9 seconds ("Failed to find players"), and accepting an invite fails with GKError 35 ("not signed in to iCloud") even though Settings shows that user's iCloud as signed in. Unified logs show the root cause. When matchmaking starts, gamed can't provision the player's pseudonym because the current user has no identity-services registration: gamed No URI found on any account -- returning nil gamed Failed to fetch pseudonym for local player. Error: GameDaemonCore.PseudonymManagerError.failedToProvision( internalError: Error Domain=com.apple.ids.IDSPseudonymErrorDomain Code=400 "Invalid URI") For the default user, the identical flow succeeds (identityservicesd … resultCode: 0). Across a full day of log capture — profile adds, a remove/re-add, multiple user switches — identityservicesd never once references the secondary users' accounts: registration for them is never attempted, not attempted-and-failed. Meanwhile gamed advertises the nearby-matchmaking Bonjour service with the default user's identity while the foreground app runs as the secondary user. Reproduction matrix: two apps (my shipping game Extreme Violence and Apple Arcade's Crossy Road Castle, which also runs under the correct persona), both sandbox and production Game Center, two unrelated secondary accounts (both healthy elsewhere). Persists across reboot and profile remove/re-add. Default user unaffected. The documentation says the entitlement is all that's needed ("each person who uses your app will have access to… their own Game Center… you don't have to make any code changes" — WWDC20 session 10645). As far as I can tell that promise is currently unfulfillable for online play: there is no API or Settings path that creates the missing IDS registration. Has anyone seen non-default-user matchmaking work on tvOS, on any version? Is there anything an app can do here, or is this purely an OS-side fix? (Related: thread 782163 — a different tvOS matchmaking failure that DTS confirmed as a bug.)
4
0
1.1k
2w
Core Animation Background Thread CATransaction
Hey everyone 👋 I'm trying to initialize a part of a CALayer hierarchy on a background thread and then attach the root of that hierarchy to a CALayer that backs a UIView. The motivation is to keep the main thread responsive when constructing a complex layer hierarchy. This isn't a case where I'm creating two or three layers and then switching back to the main thread. The hierarchy can potentially contain a large number of layers, with animations being created/configured for those layers as well. My first approach was to create and configure the layers entirely on a background thread. While the output might be the expected one (not always), CoreAnimation emits an assertion along the lines of: "Modifications to the layer tree from a background thread may not be committed" (or something like this). This makes sense to me if implicit CATransaction is thread-local. In that case, the implicit transaction opened by the layer modification on the background thread would not be part of the transaction that is already open on the main thread. Therefore, committing the main-thread transaction would not commit the changes made on the background thread. My second approach was to explicitly create and commit a CATransaction on the background thread. This appears to be accepted by Core Animation's threading model, but I'm seeing unreliable results. Sometimes parts of the hierarchy are missing, and in other cases the hierarchy is present but the animations don't appear to run at all. I do understand that this is private behavior of the framework, but I wanted to know if what I am trying to achieve is possible and, if so, what the solution would be (obviously if you can share this information). Besides this, I would also like to know what behavior CATransactions have when they are created on different threads. What I mean by this is that the transactions work as a stack, and the changes are committed when the stack is empty. Does this behavior still apply when having transactions on different threads? Any weird behaviours that might appear between transactions operated on main vs background threads? Thank you! Vlad.
Replies
2
Boosts
0
Views
24
Activity
7m
Behaviour of a 0-value `accelerationStructureID`
When constructing a MTLIndirectAccelerationStructureInstanceDescriptor, one specifies an accelerationStructureID. In the equivalents in both Vulkan and DirectX12, one can set it to zero to be an "inactive" instance. However, on Metal, this field does not appear to have any documentation, and thus it is difficult to figure out if there is similar behavior (and no other Metal documentation seems to mention this). Does setting this field to 0 (i.e. null) disable the instance? If not, is there any other way to have an equivalent effect?
Replies
5
Boosts
0
Views
1.5k
Activity
4h
CGSetDisplayTransferByTable is broken on macOS Tahoe 26.4 RC (and 26.3.1) with MacBook M5 Pro, Max and Neo
The CGSetDisplayTransferByTable() is not working on the latest round of Mac hardware, namely the MacBook Neo (external display), MacBook M5 Pro (both built-in and external display) and possibly the M5 Max. All tested apps (BetterDisplay, MonitorControl, f.lux, Lunar) exhibit the very issue both in macOS Tahoe 26.3 and macOS Tahoe 26.4 RC. Tested on multiple Macs and installations on the MacBook Neo and MacBook M5 Pro. This issue breaks several display related macOS apps. Way to reproduce the issue using an affected app: Install the app BetterDisplay (https://betterdisplay.pro) Launch the app, open the app menu, choose Image Adjustments and try to adjust colors. Adjustments take no effect Way to reproduce the issue programmatically: Attempt to use the affected macOS API feature: https://developer.apple.com/documentation/coregraphics/cgsetdisplaytransferbytable(::::_:) Here are the FB numbers: FB22273730 (Filed this one as a developer on an unaffected MBP M3 Max) FB22273782 (Filed from an affected MBP M5 Pro running 26.4 RC, with debug info attached)
Replies
10
Boosts
5
Views
4.5k
Activity
2d
Stress-testing Metal compute pipelines using Autolykos workload characteristics
I have been using a small macOS research project to exercise Metal with a workload that differs from rendering and dense machine-learning kernels. Autolykos v2 is useful for this because it combines a large, height-dependent working set with pseudo-random reads, integer-heavy hashing, sustained execution, and periodic replacement of the dataset. The project happens to be a miner, but my question here is strictly about Metal compute behaviour. On the Apple M4 system used for these measurements, the full dataset contained 216,430,305 elements of 32 bytes each: 6.93 GB, or about 6.45 GiB, held in a .storageModePrivate buffer. For every nonce, the search kernel: computes an index seed, performs 32 pseudo-random 32-byte dataset reads, accumulates the eight 32-bit limbs into a 256-bit sum, and applies a final BLAKE2b compression and target comparison. The normal dispatch uses 128 threads per threadgroup. The wider pipeline also builds the next height's dataset in chunks on a separate command queue while search continues, and keeps two search command buffers in flight. I record command-buffer wall time, gpuStartTime/gpuEndTime, unions of overlapping intervals, and thermal state. To estimate the ceiling imposed by the random gathers, I added a non-consensus microbenchmark. It retains the normal seed calculation, index distribution, all 32 dataset reads, and the complete accumulation, but omits the final BLAKE2b compression. The accumulated result remains observable through a comparison, so the gather loop cannot simply disappear. I expected this stripped kernel to be at least slightly faster. Instead, an order-balanced campaign on an M4 produced: complete search kernel: 3.108 million nonces/s median active throughput gather-only kernel: 2.952 million nonces/s ratio: 105.3% All four same-round ratios were between 103.18% and 105.74%. Each measured run used the full dataset, a 30-second search interval, an excluded warm-up, and a start-temperature gate below 50 °C. Both compute pipeline states reported maxTotalThreadsPerThreadgroup == 1024. My conservative conclusion was not to pursue speculative register-pressure or manual memory-level-parallelism rewrites. The access pattern appears sufficiently dominant, while the supposedly simpler microbenchmark may have changed the compiled pipeline in a way that makes it a poor upper-bound model. My questions are: Can removing the trailing arithmetic legitimately make a memory-latency-heavy Metal kernel slower by changing register allocation, instruction scheduling, or the amount of useful latency hiding? Or would you first suspect a flaw in this kind of gather-only benchmark construction? Also, which Metal GPU counters are the most reliable way to distinguish memory-latency saturation from register-limited occupancy in a long-running compute kernel? I am looking at compute occupancy, buffer and ALU limiters, bandwidth, and cache behaviour, but maxTotalThreadsPerThreadgroup alone is clearly too coarse to explain the result. This is one hardware-specific observation rather than a general claim about Apple GPUs. If useful, I can reduce the workload to a smaller standalone reproducer. The source code, benchmark driver, and complete campaign report are available here: https://github.com/giffeler/ergometal The detailed measurements and validation procedure for this comparison are documented here: https://github.com/giffeler/ergometal/blob/main/Benchmarks/2026-08-15-search-gather-ceiling-ab.md
Replies
0
Boosts
0
Views
583
Activity
2d
Metal-cpp usability issue with MTL::Buffer and MTL::ResidencySet
I know this might be a peeve of mine, but looking into programming a simple Metal4 Compute Shader example, essentially updating the Performing Calculations on a GPU example code to work with CPP and Metal4. I found that MTL::Allocation and MTL::Buffer pointers can't be used interchangeably when you are trying to add allocations to a MTL::ResidencySet, this is forcing you to: Know by heart that they inherit from each other and that you can just cast them (this is a bit suspicious though, it did work for me). Forcefully either C-cast or reinterpret_cast the MTL::Buffer pointer to a MTL::Allocation pointer as the MTL::ResidencySet will only accept that type. I might as well just be plain wrong about how this is used, any tips on correct usage in that case? Is there any expectation to either provide a typecast operator or add inheritance to support the expected behaviour seen in Swift and ObjC, which is just passing the thing? Opened a report with # FB24534953 with some extra information. Bear in mind that the example code uses Premake5, but it can generate an Xcode solution easily.
Replies
0
Boosts
0
Views
591
Activity
3d
On-screen RealityView starves CADisplayLink to 30 Hz on ProMotion (Mac Catalyst)
FB24536235 On Mac Catalyst under macOS 27, a plain CADisplayLink asking for CAFrameRateRange(minimum: 60, maximum: 60, preferred: 60) gets serviced at 30 Hz for as long as a RealityView is on screen in the same window. The link does nothing per tick but count, so there's nothing of mine to blame it on. RealityKit's own statistics overlay reads 60.41 fps in the same frame. Click a segmented control that removes the RealityView and the same link goes straight back to 60. Nothing else changes. That's the whole reproducer, and I've attached it to the radar. It only happens while the display panel is in ProMotion mode. Set the built-in to a fixed 60 Hz and it's correct again. With an external 60 Hz display attached the roles swap: the built-in is fine and the external drops to somewhere between 18 and 30, and setting the built-in to 60 Hz fixes that one too without touching the external's own settings. A raw MTKView presenting continuously at 60, at 120, and on a 120 Hz link presenting every second callback are all fine, so it isn't continuous presentation and it isn't the requested rate. It's RealityKit specifically. Worth knowing if you're testing: RealityView on Catalyst is an ARView underneath, so both paths give you the same answer. This is VERY rough for anything that puts RealityKit next to a UI. In an editor that's the sidebar, the inspector, gizmos, drag handles, every display-link-driven or UIKit animation in the window running at half rate around a viewport that stays smooth. Likely Related to FB24091347, which is the same defect seen as SwiftUI scroll judder. If you can reproduce either, please file a duplicate. Attached two screenshots; first with promotion enabled, second with promotion off. PLEASE fix this, it drives me crazy and there seems to be no workaround. On release day of macOS 27 our app will likely be blamed for it by users and my hands are tied. Thank you!
Replies
0
Boosts
0
Views
144
Activity
3d
Xcode 27.0 b5, macOS 26.6.1, Metal build fails: symbols not found for air64_v28
I've just downloaded the Xcode 27.0 beta 5 on a macOS 26.6.1 machine and tried to build my app (which includes Metal CoreImage kernels). I'm met with a new (to me) error; /Users/…/Developer/…/air-lld:1:1 symbol(s) not found for target 'air64_v28-apple-macosx26.0.0' and from the build log; air-lld: warning: ignoring file '/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/CoreImage.framework/Versions/A/CoreImage.metallib', file AIR version (2.9) is bigger than the one of the target being linked (2.8) air-lld: error: symbol(s) not found for target 'air64_v28-apple-macosx26.0.0' metal: error: air-lld command failed with exit code 1 (use -v to see invocation) I have no MTL_LANGUAGE_REVISION in my build settings. If I add one, with value Metal41 the app builds fine, but crashes at runtime as Metal 4.1 isn't supported on macOS 26. I imagine this is a beta Xcode and or macOS SDK bug, is there a workaround?
Replies
1
Boosts
0
Views
1.1k
Activity
5d
Can Materials not assigned to entities be retrieved from a .reality file?
like: let mat = try await ShaderGraphMaterial(named: "matname", from: "reality") currently I use an USD file with materials like so and it works: try await ShaderGraphMaterial(named: "/Root/matname", from: "file.usda", in: appBundle) when i try it with .reality i get "NameNotFound". so is it possible or do i have to have a bunch of dummy entities with my materials assigned so i can find the entity>components>material? or what's the best way to author materials in RCP3 for quick access in realitykit?
Replies
3
Boosts
0
Views
1.8k
Activity
5d
Is there a working example for Fog post effect for non AR game?
i can read the depth and mix it with the rendered image and get a linear fog effect but I can't get a true radial fog. I've been going back and forth with gemini and chatgpt and neither can do it. gemini got me a radial gradient but it's jsut projected flat across all 3d objects. it's been all day trial after trial this is what gives me the flat radial gradient using namespace metal; struct DepthFogEffectConstants { float4 fogColor; float density; // We no longer need the inverse projection matrix here! }; kernel void depthFogKernel( texture2d<half, access::read> inColor [[texture(0)]], texture2d<float, access::read> inDepth [[texture(1)]], texture2d<half, access::write> outColor [[texture(2)]], constant DepthFogEffectConstants& uniforms [[buffer(0)]], uint2 gid [[thread_position_in_grid]]) { float w = outColor.get_width(); float h = outColor.get_height(); if (gid.x >= w || gid.y >= h) { return; } half4 originalColor = inColor.read(gid); float rawDepth = inDepth.read(gid).r; // 1. Guard check for empty backgrounds/skyboxes if (rawDepth <= 0.00001f || rawDepth >= 0.9999f) { outColor.write(originalColor, gid); return; } // 2. Map screen pixels from the center of the lens (-1.0 to 1.0) float2 screenPos = float2( ((float(gid.x) / w) * 2.0f) - 1.0f, 1.0f - ((float(gid.y) / h) * 2.0f) ); // 3. Since rawDepth is already acting as a view-space Z proxy, // we use it to calculate the true spherical ray distance from the lens center. // The hypotenuse of screen offset (X, Y) and depth (Z) gives the radial distance. float radialDistance = sqrt(screenPos.x * screenPos.x + screenPos.y * screenPos.y + rawDepth * rawDepth); // 4. Calculate exponential fog matching your visual test float fogFactor32 = exp(-radialDistance * uniforms.density); half fogFactor = half(clamp(fogFactor32, 0.0f, 1.0f)); half4 fogColor = half4(uniforms.fogColor); // Mix and write colors out cleanly half4 finalColor = mix(fogColor, originalColor, fogFactor); outColor.write(radialDistance, gid); } in this code i'm just outputing the radial distance to see that calculation and it's just wrong. i don't know what to do anymore
Replies
1
Boosts
0
Views
1.5k
Activity
1w
CGFloat Float fix to one type
AI was getting confused and kept correcting, but didn’t have a overriding translation.
Replies
8
Boosts
0
Views
1.3k
Activity
1w
macOS 27 beta: ProMotion refresh cadence is unstable, causing constant scroll judder
FB24091347 On macOS 27.0 beta (26A5388g), MacBook Pro M4 Pro, the built-in ProMotion display never settles on a stable refresh cadence. Scrolling in SwiftUI judders constantly. The same app binary was smooth on macOS 26, and is smooth on a 120 Hz ProMotion iPad. I captured two 60-second Instruments traces — same app, same scene, same scrolling, no external display — changing only the display's refresh-rate setting. On ProMotion the vsync interval standard deviation is 4.093 ms across six different cadences, mostly flip-flopping between 120 Hz and 60 Hz. Forced to a fixed 60 Hz it drops to 0.391 ms with a single cadence. The app presented an identical 59 fps median in both runs — frame production is perfectly steady, the display just holds each frame for an unpredictable length of time. That's what makes this nasty: it's invisible to every frame-rate metric, so it looks like the app got slow when nothing about the app changed. I spent most of a day profiling my own code before realising the app was never the problem. Workaround: force the built-in display to 60 Hz. Worth noting, because it complicates the picture: attaching a 60 Hz Studio Display makes the built-in smooth, but the Studio itself then judders — despite its own vsync cadence measuring perfectly stable. So refresh rate alone isn't the whole story, and there may be a second mechanism. The clean, reproducible, single-variable result is the ProMotion vs forced-60 Hz comparison on the built-in panel. If you can reproduce this on an M-series MacBook Pro on 27 beta, please file a duplicate referencing FB24091347.
Replies
4
Boosts
0
Views
826
Activity
1w
D3DMetal: crash on Cmd+Tab out of a fullscreen D3D11 app — FindClosestMatchingMode reads modes[count-1] (FB24422691)
Filed as FB24422691. Posting here as well because the crash leaves no usable stack in the application's own crash handler, and searching for "0x1BFFFFFFE4" or "FindClosestMatchingMode" returns nothing anywhere, so this may save someone else the debugging. SYMPTOM A Direct3D 11 Windows application (Unity 2021.3) running fullscreen under Game Porting Toolkit dies when you Cmd+Tab out of it and back in. Exclusive and borderless fullscreen both crash; windowed never does. It is intermittent: on my machine it takes 5 to 9 switches. Always the same signature: EXCEPTION_ACCESS_VIOLATION (0xC0000005), reading address 0x1BFFFFFFE4, faulting RIP at D3DMetal+0xFA8F. Identical in all 16 crash reports I collected, which is what makes it a deterministic underflow rather than heap corruption. CAUSE D3DMetal's DXGIOutput::FindClosestMatchingMode calls GetDisplayModeList and then reads the last element of the list without checking the count or the buffer pointer: call DXGIOutput::GetDisplayModeList(...) ; count returned in [rsp+0x3c] mov eax, [rsp+0x3c] ; eax = count dec eax ; 0xFFFFFFFF when count == 0 lea rcx, [rax + 8rax] ; rcx = 28 * eax (28 = sizeof DXGI_MODE_DESC) lea rcx, [rcx + 2rcx] add rcx, rax mov rax, [r14 + rcx] ; reads modes[-1] 28 * 0xFFFFFFFF = 0x1BFFFFFFE4, and r14 (the mode buffer) is NULL on that path, so the read lands exactly on the address seen in the crash reports. WHY THE LIST IS EMPTY winemac.drv rebuilds the display device list on every application activation. With WINEDEBUG=+display, four Cmd+Tab activations produce exactly four full rebuilds (macdrv_UpdateDisplayDevices: GPU count, adapter, monitor). An application that queries the closest matching mode mid-rebuild gets zero modes back. Fullscreen makes that query on focus changes; windowed does not, which is exactly why windowed never crashes. The empty-list condition is not unique to this race: GetDisplayModeList has also been reported returning 0 modes for DXGI_FORMAT_R16G16B16A16_FLOAT on D3DMetal 2.1 (github.com/vec715/enfusion-dxgi-fix). DXVK and DXMT both return DXGI_ERROR_NOT_FOUND for an empty list instead of dereferencing it. MEASUREMENTS Alternating applications automatically and verifying every focus change: borderless fullscreen: crash after 5, 6, 6 and 8 switches (4 of 4 runs) exclusive fullscreen: crash after 9 switches windowed: 105+ switches, no crash As a control I patched a local copy of D3DMetal so the read is skipped when count == 0 or the buffer is NULL, keeping the requested mode. Same machine, same setup: 140 switches in fullscreen with no crash, and the unpatched binary crashed again after 8 switches immediately afterwards. VERSIONS The unchecked read is present in both D3DMetal builds I have: 2.0 (built for macOS 13.3) at 0x1453A, and 3.0 (built for macOS 15.4) at 0xFA82. Environment: macOS 26.5.2 (25F84), Apple M5, D3DMetal 3.0 inside Game Porting Toolkit, Wine 7.7, 64-bit prefix, fullscreen at 2560x1664 with winemac.drv Retina mode on. WORKAROUND UNTIL IT IS FIXED Run the application windowed, or interpose a dxgi proxy DLL that returns DXGI_ERROR_NOT_FOUND from FindClosestMatchingMode when the mode count is 0. Suggested fix: return DXGI_ERROR_NOT_FOUND from FindClosestMatchingMode / FindClosestMatchingMode1 when the count is 0 or the buffer is NULL, instead of indexing modes[count-1].
Replies
0
Boosts
0
Views
85
Activity
1w
Photogrammetry with Object masks hangs and terminates with masks of objects
[PhotogrammetrySample]) with objectMask set and traps on my ios26.5.2, see the attached screenshot on feedback FB24379913 , it gets to the function and hangs . Even the folder reconstruction with lazy sequence as recommended from your video sample also doesn;t complete as it can't find alignment and displays the CoreOC.PhotogrammetrySession.Error error 6 means alignment failed. What can be done or do you guys expose any functions that can be used to check or trace or handle these internally The ObjectMasks are actually segmentation masks from an segmentation algorithm I will appreciate a timely response and willing to provide more clarity and informations, thank you so much for your understanding
Replies
2
Boosts
0
Views
617
Activity
1w
MPS bf16 softmax produces NaN on M5 Max (regression from M4) — breaks all on-device diffusion inference
Metal Performance Shaders produces from bf16/fp16 softmax for large attention tensors on , forcing the entire local generative-AI ecosystem to fall back to fp32. This is a . Environment Minimal reproduction Decomposed softmax on MPS — diffs = x - maxes produces NaN even though every element is identical (result should be all zeros): Real-world impact Running ComfyUI (the dominant local generative-AI UI) on M5 Max: Root cause (per PyTorch MPS maintainers) PyTorch maintainers (@drisspg, @albanD) have traced this to in the MPS/MPSGraph fused kernels. The NaN originates in the x - maxes subtraction inside softmax, then propagates through the attention block and the entire network. PyTorch cannot fix this — it is in the Metal/MPS kernel layer. Not isolated The M4-era fix ("fixed on macOS 15.1") did not survive onto M5, indicating the MPS fused-kernel precision fix was either reverted or not ported to the M5 GPU architecture. Request
Replies
1
Boosts
0
Views
832
Activity
1w
PhotogrammetrySession(input: [PhotogrammetrySample]) Hangs or terminates
Xcode hangs when I call PhotogrammetrySession(input: [PhotogrammetrySample]) with objectMask set and traps on some devices, see the attached screenshot, it gets to the function and hangs. Even the folder reconstruction also doesn't complete as it can't find alignment and displays the CoreOC.PhotogrammetrySession.Error 6 and I understand to mean alignment failed. In this case it failed while object masking was ON, so RealityKit could not find enough consistent feature tracks inside the masked pixels across the image set. What can be done or do you guys expose any functions that can be used to aid, or handle these internally, can't find any internally. The ObjectMasks are actually segmentation masks from an ML algorithm . To replicate try calling PhotogrammetrySession(input: [PhotogrammetrySample]) with contentsOf as captured on your documentation, even with like 30 image set or is there something I'm missing. I will appreciate a timely response and willing to provide more clarity and informations, thank you so much for your understanding
Replies
4
Boosts
0
Views
2.6k
Activity
1w
Metal Shader Converter thread safety
Hello Apple! We've got offline shader compilation from HLSL -> Metallib using DXC -> SPIR-V -> metal.exe. This works okay for the most part, but it requires the creation of intermediate files to pass to/from the metal.exe process and we've had some issues with metal.exe sometimes not launching (probably our fault). Then we noticed Metal Shader Converter (MSC) exists and has a DLL - this looks way better since there's no need to launch processes or store intermediate files. However, upon trying to replace metal.exe with it I quickly ran into rampant heap corruption. I was surprised because the docs claim this: Each thread in your program needs to create its own instance of IRCompiler to avoid race conditions. But once I start calling IRCompilerAllocCompileAndLink in parallel all hell breaks loose, whether or not each thread has its own IRCompiler. I figured I must be doing something wrong, so I removed my attempt and compiled DXC locally with the MSC integration and encountered the exact same heap corruption. So I'm inclined to think the library isn't actually thread safe, but I'm wondering if there's something I'm missing? I tried all 3 versions of MSC just in case it was a problem with 3.0, but I got the same result each time. The only way to make it work was to surround compilation with a mutex, which makes its use pointless in our case.
Replies
2
Boosts
0
Views
1.2k
Activity
1w
Residency Set vs storage mode
What's the point of residency sets if you can just make a buffer accessible to the GPU through storage mode in metal?
Replies
1
Boosts
0
Views
546
Activity
1w
Lockpicking - Steuerung
Hallo, mein Spiel Lockpicking ist exakt gleich programmiert für Android und Apple. Warum sehen die links rechts Tasten bei beiden Apps verschieden aus ? https://apps.apple.com/us/app/lockpicking/id6793054294
Replies
1
Boosts
0
Views
383
Activity
1w
view protocol update ?
Hello ! Thank you guys for all the hard work you are doing on RealityKit For now in my studying Im trying to understand, in general, what will cause my Main app view to redraw everything? Or any view? If i have a struct that use the view protocol, and that struct is being called inside RealityView on the main app, or outside a reality view within a ZStack on the main app, if this view updates, does this will cause everything in my main app view to redraw as well? Or is it only true to @State variables of the main app? or the @State variables of the external view i try to implement? and what about @Observable ? Is there an accurate table that tells the developer what will cause a redraw of things? (not only the things the logic asks for, but all things sitting idle within the view) I try to understand how to separate UI updates, to avoid full redraw of things that havent been changed. to minimize UI compute in my games Before i play around with instruments i need to understand the general architecture.. if i work in a way that is counter designed to the way reality kit should work then the instrument results will not make sense to me. so i feel like i should ask you guys first. Depending on your answer i will know how to arrange my data in my game. And how to design and instantiate all my views Thanks
Replies
1
Boosts
0
Views
972
Activity
2w
Game Center matchmaking fails for all non-default users on Apple TV — no IDS registration for secondary users (FB24156316)
Game Center matchmaking fails for all non-default users on Apple TV — no IDS registration for secondary users (FB24156316) On a multi-user Apple TV (tvOS 26.5, Apple TV 4K 3rd gen), Game Center real-time matchmaking fails for every user except the default user, in every app I've tested — including Apple Arcade titles. Filed as FB24156316 with full logs and sysdiagnose; posting here for visibility and in case anyone has shipped multi-user GC multiplayer on tvOS successfully. My game adopts com.apple.developer.user-management (runs-as-current-user-with-user-independent-keychain). The entitlement itself works: on a secondary user's profile the app runs under that user's persona and GKLocalPlayer authenticates as them — the welcome banner shows the right account. But any GKMatchmakerViewController quickmatch hard-fails within ~9 seconds ("Failed to find players"), and accepting an invite fails with GKError 35 ("not signed in to iCloud") even though Settings shows that user's iCloud as signed in. Unified logs show the root cause. When matchmaking starts, gamed can't provision the player's pseudonym because the current user has no identity-services registration: gamed No URI found on any account -- returning nil gamed Failed to fetch pseudonym for local player. Error: GameDaemonCore.PseudonymManagerError.failedToProvision( internalError: Error Domain=com.apple.ids.IDSPseudonymErrorDomain Code=400 "Invalid URI") For the default user, the identical flow succeeds (identityservicesd … resultCode: 0). Across a full day of log capture — profile adds, a remove/re-add, multiple user switches — identityservicesd never once references the secondary users' accounts: registration for them is never attempted, not attempted-and-failed. Meanwhile gamed advertises the nearby-matchmaking Bonjour service with the default user's identity while the foreground app runs as the secondary user. Reproduction matrix: two apps (my shipping game Extreme Violence and Apple Arcade's Crossy Road Castle, which also runs under the correct persona), both sandbox and production Game Center, two unrelated secondary accounts (both healthy elsewhere). Persists across reboot and profile remove/re-add. Default user unaffected. The documentation says the entitlement is all that's needed ("each person who uses your app will have access to… their own Game Center… you don't have to make any code changes" — WWDC20 session 10645). As far as I can tell that promise is currently unfulfillable for online play: there is no API or Settings path that creates the missing IDS registration. Has anyone seen non-default-user matchmaking work on tvOS, on any version? Is there anything an app can do here, or is this purely an OS-side fix? (Related: thread 782163 — a different tvOS matchmaking failure that DTS confirmed as a bug.)
Replies
4
Boosts
0
Views
1.1k
Activity
2w