I'm currently converting my game from SceneKit to RealityKit. What's the easiest way to run an animation in which every frame I want to run custom code, similar to SCNAction.customAction which accepts a callback that is called repeatedly until the action completes?
Delve into the world of graphics and game development. Discuss creating stunning visuals, optimizing game mechanics, and share resources for game developers.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I am attempting to load a jpeg image into a vImage_Buffer.
I am just trying to get the data in an ARGB format. This code works fine in the Xcode 15 build , but fails with kvImageInvalidParameter error from vImageBuffer_InitWithCGImage in the Xcode 26 build.
This code is written in ObjectiveC++.
Here is a code fragment:
int CDib_ARGB::Load(LPCSTR pFilename)
{
int rc = 0;
if (NULL == m_pRaw_vImage_Buffer)
{
NSString *pNS_filename = [[NSString alloc]initWithUTF8String:pFilename];
NSImage *pNSImage = [[NSImage alloc] initWithContentsOfFile:pNS_filename];
if (nil == pNSImage)
rc = -1;
else
{
int width = pNSImage.size.width;
int height = pNSImage.size.height;
if (pNSImage.representations)
{
NSImageRep *imageRep;
int jj;
width = 0;
height = 0;
for (jj = 0; jj < pNSImage.representations.count; jj++)
{
imageRep = pNSImage.representations[jj];
if (imageRep.pixelsWide > width)
width = imageRep.pixelsWide;
if (imageRep.pixelsHigh > height)
height = imageRep.pixelsHigh;
}
}
NSSize imageSize = NSMakeSize(width, height);
NSRect imageRect = NSMakeRect(0, 0, width, height);
pNSImage.size = imageSize;
CGImageRef cgImage = [pNSImage CGImageForProposedRect:&imageRect context:NULL hints:nil];
if (nil == cgImage)
rc = -1;
else
{
//Alloc and load vImage_Buffer.
vImage_Buffer *pvImage_Buffer = new vImage_Buffer;
if (NULL == pvImage_Buffer)
rc = -1;
else
{
vImage_CGImageFormat format;
format.bitsPerComponent = 8;
format.bitsPerPixel = 32;
format.colorSpace = nil;
format.bitmapInfo = kCGImageAlphaFirst | kCGBitmapByteOrderDefault;//ARGB8888
format.version = 0;
format.decode = nil;
format.renderingIntent = kCGRenderingIntentDefault;
memset(pvImage_Buffer, 0, sizeof(vImage_Buffer));
long status = vImageBuffer_InitWithCGImage(pvImage_Buffer, &format, nil, cgImage, kvImagePrintDiagnosticsToConsole);
if (kvImageNoError != status)
{ //This is where Xcode 26 sends me.
delete pvImage_Buffer;
rc = -1;
}
=========================
We are developing a video processing app that applies CIFilter chains to video frames. To not force the user to keep the app foregrounded, we were happy to see the introduction of BGContinuedProcessingTask to continue processing when backgrounded.
With iOS 26, I was excited to see the com.apple.developer.background-tasks.continued-processing.gpu entitlement, which should allow GPU access in the background. Even the article in the documentation provides "exporting video in a film-editing app" or "applying visual filters (HDR, etc) or compressing images for social media posts" as use cases. However, when I check BGTaskScheduler.shared.supportedResources.contains(.gpu) at runtime, it returns false on every iPhone I've tested (including iPhone 15 Pro and iPhone 16 Pro).
From forum responses I've seen, it sounds like background GPU access is currently limited to iPad only. If that's the case, I have a few questions:
Is this an intentional, permanent limitation — or is iPhone support planned for a future iOS release?
What is the recommended approach for GPU-dependent background work on iPhone? My custom CIKernels are written in Metal (as Apple recommends since CIKL is deprecated), but Metal CIKernels cannot fall back to CPU rendering. This creates a situation where Apple's own deprecation guidance (migrate to Metal) conflicts with background processing realities (no GPU on iPhone).
Should developers maintain deprecated CIKL kernel versions alongside Metal kernels purely as a CPU fallback for background execution? That feels like it defeats the purpose of the migration.
It seems like a gap in the platform: the API exists, the entitlement exists, but the hardware support isn't there for the most common device category. Any clarity on Apple's direction here would be very helpful.
I've been using Metal compute shaders for lattice quantum chromodynamics simulations and wanted to share the experience in case others are doing scientific computing on Metal.
The workload involves SU(2) matrix operations on 4D lattice grids — lots of 2x2 and 3x3 complex matrix multiplies, reductions over lattice sites, and nearest-neighbor stencil operations. The implementation bridges a C++ scientific framework (Grid) to Metal via Objective-C++ .mm files, with MSL kernels compiled into .metallib archives during the build.
Things that work well:
Shared memory on M-series eliminates the CPU↔GPU copy overhead that dominates in CUDA workflows
The .metallib compilation integrates cleanly with autotools builds using xcrun
Float4 packing for SU(2) matrices maps naturally to MSL vector types
Things I'm still figuring out:
Optimal threadgroup sizes for stencil operations on 4D grids
Whether to use MTLHeap for gauge field storage or stick with individual buffers
Best practices for double precision — some measurements need float64 but Metal's double support varies by hardware
The application is measuring chromofield flux distributions between static quarks, ultimately targeting multi-quark systems. Production runs are on MacBook Pro M-series and Mac Studio.
Code: https://github.com/ThinkOffApp/multiquark-lattice-qcd
I have noticed that the performance drop on SpriteKit-based projects running on iOS 26 is still ongoing
With iOS 26 back in Sep 2025 a framerate problem was introduced. My app was always running smoothly with 60fps even on very old devices suddenly started to stutter with 40fps - and lower on a rather normal iPhone 13.
This problem continued with BETA 26.1
The problem was fixed in 26.2.
But 26.3 brought the problem back and its still ongoing with 26.4 of yesterday
This is easily reproducible with a very simple example
//
// BareboneSpriteKitApp.swift
// BareboneSpriteKit
//
// Created by Bernd Beyreuther on 24.02.26.
//
import SwiftUI
import SpriteKit
@main
struct BareboneSpriteKitApp: App {
var body: some Scene {
WindowGroup {
BareboneSceneView()
}
}
}
final class BareboneScene: SKScene {
override func didMove(to view: SKView) {
size = view.bounds.size
scaleMode = .resizeFill
anchorPoint = CGPoint(x: 0.5, y: 0.5)
backgroundColor = .darkGray
let s = SKSpriteNode(color: .cyan, size: CGSize(width: 64, height: 64))
addChild(s)
let action = SKAction.rotate(byAngle: .pi, duration: 2)
s.run(.repeatForever(action))
let t = SKLabelNode(text: deviceInfoString())
t.fontSize = 15
t.position.y = -100
addChild(t)
}
}
struct BareboneSceneView: View {
var body: some View {
SpriteView(
scene: BareboneScene(),
debugOptions: [.showsFPS]
)
.ignoresSafeArea()
}
}
func deviceInfoString() -> String {
let os = ProcessInfo.processInfo.operatingSystemVersion
let osString = "iOS \(os.majorVersion).\(os.minorVersion).\(os.patchVersion)"
let model = UIDevice.current.model // "iPhone", "iPad"
let machine = {
var sysinfo = utsname()
uname(&sysinfo)
return withUnsafePointer(to: &sysinfo.machine) { ptr -> String in
ptr.withMemoryRebound(to: CChar.self, capacity: 1) { cptr in
String(cString: cptr)
}
}
}() // z.B. "iPhone15,2"
return "Model Identifier: \(model) (\(machine)), \(osString)"
}
I file a bugreport via Feedback Assistant FB22038921
The problem is no around for such a long time ! This is deeply concerning, because it questions if it is really feasable to continue to develop using Spritekit ?
Hello,
I have noticed a performance drop on SpriteKit-based projects running on iOS 26.3.
The issue seems very similar to the issue reported on iOS 26.0, and later solved from iOS 26.2 beta 3:
https://developer.apple.com/forums/thread/800952?answerId=870617022#870617022
With 26.3, it seems a regression occured.
Below is the same SpriteKit scene used to test framerate on different devices:
import SpriteKit
import SwiftUI
class BareboneScene: SKScene {
override func didMove(to view: SKView) {
size = view.bounds.size
anchorPoint = CGPoint(x: 0.5, y: 0.5)
backgroundColor = .darkGray
let roundedSquare = SKShapeNode(rectOf: CGSize(width: 150, height: 75), cornerRadius: 12)
roundedSquare.fillColor = .systemRed
roundedSquare.strokeColor = .black
roundedSquare.lineWidth = 3
addChild(roundedSquare)
let action = SKAction.rotate(byAngle: .pi, duration: 1)
roundedSquare.run(.repeatForever(action))
}
}
struct BareboneSceneView: View {
var body: some View {
SpriteView(
scene: BareboneScene(),
debugOptions: [.showsFPS]
)
.ignoresSafeArea()
}
}
#Preview {
BareboneSceneView()
}
Running this very basic spritekit scene on my device and I can not reach an FPS of 60. Instead, it stalls around 40.
I see the same in my AppStore published SpriteKit games.
As you can see in the discussion of the linked forum topic, the regression has been noticed by others as well. Can you please look into this, and let us know if there is an outstanding action to resolve it already?
It's very problematic for published games suddenly dropping to 40FPS on even the most modern iOS devices.
Dear colleagues, when will you add the ability to manually adjust the display's color temperature? Everyone is familiar with the color rendering issue on the 17 series. Many complain about the display's yellowish tint. I'm one of those people, with a G9N panel, but I can't get whites right; there's a persistent yellow tint. TrueTone only solves this problem under cool, white lighting conditions. So, the display might work as intended, but how can I make it work consistently? If there were a way to manually adjust TrueTone, many users wouldn't be so upset when buying a new device, fearing the display would be yellow. I'd like users to be able to choose their preferred color, warm or cool, and have a scale to adjust it! This would solve the yellowish tint issue on 17 series displays! Thank you.
Topic:
Graphics & Games
SubTopic:
General
Setup: MSAA rendering using a memoryless texture as the color attachment (render_image) and a "normal" texture as the resolve attachment (resolve_image). MTL_DEBUG_LAYER / API validation is enabled for this.
When trying to add the memoryless texture to a residency set, I get the following error:
-[MTLDebugResidencySet validateResource:], line 114: error 'residency sets do not support memoryless resources.
Which is as expected and identical to Metal 3.
However, if I don't add it to the residency set, I then get the following error when committing to the command queue:
-[MTL4DebugCommandQueue commit:count:options:], line 67: error 'Commit With Options Validation
Attachment texture (Label: render_image) used in command buffer (at index 0) is not added to any residency set on the command buffer or command queue.
So which way around is actually correct in Metal 4?
Either way, this makes the use of memoryless textures/attachments impossible right now when validation is enabled.
FWIW: when disabling all validation, either way seems to work just fine.
Tested on: M1 Max, macOS 26.3, Xcode 26.2 & 26.4b2
Topic:
Graphics & Games
SubTopic:
Metal
The sample code just draw a triangle and sample texture.
both sample code can draw a correct triangle and sample texture as expected. there are no error message from terminal.
Sample code using constexpr Sampler can capture and replay well.
Sample code using a argumentTable to bind a MTLSamplerState was crashed when using Metal capture and replay on Xcode.
Here are sample codes.
Sample Code
Test Environment:
M1 Pro
MacOS 26.3 (25D125)
Xcode Version 26.2 (17C52)
Feedback ID: FB22031701
When I enter webp image to the assets catalog I get warrning:
/Users/..../Assets.xcassets The image set "Card-Back" references a file "Card-Back.webp", but that file does not have a valid extension.
It works, I see all my images perfect.
How can I fix the 200+ warrnings?
I am working on a remote control application for macOS where I need to maintain two "virtual" cursors:
Remote Cursor: Follows the remote user's movements.
Local Cursor: Follows the local user's physical mouse/trackpad movements.
To move the system cursor (for the remote side), I use CGWarpMouseCursorPosition as follows:
void DualCursorMac::UpdateSystemCursorPosition(int x, int y) {
CGPoint point = CGPointMake(static_cast<CGFloat>(x), static_cast<CGFloat>(y));
// Warp the cursor to match remote coordinates
CGWarpMouseCursorPosition(point);
}
Meanwhile, I use a CGEventTap to monitor local physical movements to update my local virtual cursor's UI:
CGEventRef Mouse::MouseTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
if (remoteControlMode) {
// We want to suppress system cursor movement but still read the delta
const int deltaX = static_cast<int>(CGEventGetIntegerValueField(event, kCGMouseEventDeltaX));
const int deltaY = static_cast<int>(CGEventGetIntegerValueField(event, kCGMouseEventDeltaY));
NSLog(@"MouseTapCallback: delta:(%d, %d)", deltaX, deltaY);
// Update local virtual cursor UI based on deltas...
return nullptr; // Consume the event
}
return event;
}
The Problem:
When CGWarpMouseCursorPosition is called frequently to update the system cursor, it interferes with the kCGMouseEventDeltaX/Y values in the Event Tap.
Specifically, if the local user moves the trackpad slowly (expecting deltas of 1 or 2), but a "Warp" occurs simultaneously (e.g., jumping the cursor from (100, 100) to (300, 300)), the deltaX and deltaY in the callback suddenly spike to very large values. It seems the system calculates the delta based on the new warped position rather than the pure physical displacement of the trackpad.
This makes the local virtual cursor "jump" erratically and makes it impossible to track smooth local movement during remote control.
My Question:
Is there a way to get the "raw" or "pure" physical relative movement (delta) from the trackpad/mouse that is independent of the system cursor's absolute position or warping?
Are there alternative APIs (perhaps IOKit or different CGEvent fields) that would allow me to get consistent deltas even when the cursor is being warped programmatically?
Hello,
In our game we enforce an age gate before showing Game Center sign‑in. Only after the user passes the age gate do we call GKLocalPlayer.localPlayer.authenticateHandler.
The reason I’m asking is that we want to reliably detect if the game was launched from a Game Center activity in the Games app (iOS 26+). If the user prefers to enter via activities, we don’t want to miss that event during cold start.
Our current proposal is:
Register a GKLocalPlayerListener early in didFinishLaunchingWithOptions: so the app is ready to catch events.
Queue any incoming events in our dispatcher.
Only process those events after the user passes the age gate and authentication succeeds.
My questions are:
Does player:wantsToPlayGameActivity:completionHandler: ever fire before authentication, or only after the local player is authenticated?
If it only fires after authentication, is our “register early but gate processing” approach the correct way to ensure we don’t miss activity launches?
Is there any recommended pattern to distinguish “activity launch” vs. “normal launch” in this age‑gate scenario?
We want to respect Apple’s age gate requirements, but also ensure activity launches are not lost if the user prefers that entry point.
Sorry if this is a stupid question — I just want to be sure we’re following the right pattern.
Thanks for any clarification or best‑practice guidance!
I'm currently learning Metal. While reading the reference, I came across a strange description.
Page 78 in Version 4 Reference (2025-10-25) says:
It is legal to call the following set_indices functions to set the indices if the position in the index buffer is valid and if the position in the index buffer is a multiple of 2 (uchar2 overload) or 2 (uchar4 overload). The index I needs to be in the range [0, max_indices).
void set_indices(uint I, uchar2 v);
void set_indices(uint I, uchar4 v);
However, it seems that the uchar4 overload should be multiple of 4.
Furthermore, there is no explanation of what these methods actually do. I believe it involves setting two to four consecutive indices at once, but there is no mention of that here.
I would like to know if the above understanding is correct.
When building a Unity iOS game, the app name displays incorrectly as "BigBall" on the iPhone home screen, despite setting the project name and bundle identifier to "Big Ball" in Unity and Apple Developer account. The correct name, "Big Ball," appears in TestFlight.
I tried solutions from ChatGPT and DeepSeek, but none were satisfactory.
Please help me.
In my project I need to do the following:
In runtime create metal Dynamic library from source.
In runtime create metal Executable library from source and Link it with my previous created Dynamic library.
Create compute pipeline using those two libraries created above.
But I get the following error at the third step:
Error Domain=AGXMetalG15X_M1 Code=2 "Undefined symbols:
_Z5noisev, referenced from: OnTheFlyKernel
" UserInfo={NSLocalizedDescription=Undefined symbols:
_Z5noisev, referenced from: OnTheFlyKernel
}
import Foundation
import Metal
class MetalShaderCompiler {
let device = MTLCreateSystemDefaultDevice()!
var pipeline: MTLComputePipelineState!
func compileDylib() -> MTLDynamicLibrary {
let source = """
#include <metal_stdlib>
using namespace metal;
half3 noise() {
return half3(1, 0, 1);
}
"""
let option = MTLCompileOptions()
option.libraryType = .dynamic
option.installName = "@executable_path/libFoundation.metallib"
let library = try! device.makeLibrary(source: source, options: option)
let dylib = try! device.makeDynamicLibrary(library: library)
return dylib
}
func compileExlib(dylib: MTLDynamicLibrary) -> MTLLibrary {
let source = """
#include <metal_stdlib>
using namespace metal;
extern half3 noise();
kernel void OnTheFlyKernel(texture2d<half, access::read> src [[texture(0)]],
texture2d<half, access::write> dst [[texture(1)]],
ushort2 gid [[thread_position_in_grid]]) {
half4 rgba = src.read(gid);
rgba.rgb += noise();
dst.write(rgba, gid);
}
"""
let option = MTLCompileOptions()
option.libraryType = .executable
option.libraries = [dylib]
let library = try! self.device.makeLibrary(source: source, options: option)
return library
}
func runtime() {
let dylib = self.compileDylib()
let exlib = self.compileExlib(dylib: dylib)
let pipelineDescriptor = MTLComputePipelineDescriptor()
pipelineDescriptor.computeFunction = exlib.makeFunction(name: "OnTheFlyKernel")
pipelineDescriptor.preloadedLibraries = [dylib]
pipeline = try! device.makeComputePipelineState(descriptor: pipelineDescriptor, options: .bindingInfo, reflection: nil)
}
}
I am just starting to learn SpriteKit and I'm having trouble selecting a scene to preview an action in the actions editor.
I created a new macOS Game project (Language: Swift, Game Technology: SpriteKit). When I open the generated 'Actions.sks' file, I see the message "No Preview Scene Selected" in the editor. I see the 'GameScene.sks' scene listed in the "Select..." control in the lower right, but it is greyed out. I'm not able to figure out how to select a scene to preview the action.
I'm running Xcode 26.2 on macOS 15.
Thanks very much for the help.
Topic:
Graphics & Games
SubTopic:
SpriteKit
Hello Apple Developers and users I am writing this message reguarding some help on some performance codes/settings I can use for my Macbook since I recently downloaded the MacOs Tahoe 26.2 and its been very glitchy and laggy with gaming and just using my mac normally I have tried using a FPS unlocker and downloading Metal 4 the FPS unlocker hasent worked at all I am still stuck on the normal 60 FPS and need some advice/help. Thank you. Kind regards Zachary
Hello,
I'm working on a game that features online multiplayer. The game is developed using Unity and Apple Unity plugins.
The "isUnderAge" property restricts the online multiplayer feature. Everything works as expected on all platforms (Mac, iPhone, iPad, AppleTV, and visionPro) except on Macs equipped with an Intel chip.
Using the same iCloud and GameCenter, with no restrictions enabled, "isUnderAge" returns false, as expected, but on Mac equipped with an Intel chip, it returns true.
Is there any restriction or compatibility issue with those chips? Is there a workaround?
Thanks
Topic:
Graphics & Games
SubTopic:
GameKit
Hi — we’re testing our app on iOS 26 and ran into strange behavior with GKLocalPlayer.local.authenticateHandler.
GKLocalPlayer.local.authenticateHandler = { [weak self] viewController, error in
// additional code
}
What happens:
When we assign authenticateHandler on iOS 26 and the user is not signed in to Game Center, the system shows a full-screen Game Center overlay asking the user to sign in.
If the user taps Cancel, nothing further happens — the closure is not invoked again, so we don’t receive an error or any callback. The app never learns whether the auth was cancelled or failed.
In previous iOS versions the closure was called (with viewController / error as appropriate) and the flow worked as expected.
What we tried:
Verified authenticateHandler is being set.
Checked GKLocalPlayer.local.isAuthenticated after the overlay dismisses — it’s unchanged.
Observed system logs: a com.apple.GameOverlayUI scene is created and later removed (so the auth overlay is shown by the system).
Confirmed the same code works on earlier iOS versions. :thinking:
Question:
Has anyone seen authenticateHandler not being invoked on iOS 26 when the Game Center auth overlay is presented? Could this be a behavioral change in iOS 26 (overlay runs in a separate system process), or a bug? Any suggested workarounds to reliably detect that the user cancelled the sign-in (for example: listening for willResignActive / didBecomeActive, watching for a system overlay, or saving/presenting the viewController manually)?
Thanks in advance for any advice — we’d appreciate pointers or suggested diagnostics ?
I've coded a text-adventure game in SwiftUI. (My game has no graphics or sound effects.)
My app already supports keyboard navigation; I would like to add support for game controllers on iPhone. I can't figure out how to do it. I especially can't see any way to allow controller users to enter text in a TextField.
I've read https://developer.apple.com/documentation/gamecontroller/supporting-game-controllers and it's all about button events. There's no reference to SwiftUI at all in that documentation, or any input-method editing at all. The only mention of "keyboard" is about treating the keyboard itself as if it were a game controller providing button events.
How do I implement this?