swiftship/internal/skills/data/features/game-assets/SKILL.md
Download free game sprites/textures/3D models and generate procedural assets. Covers nw_download_asset tool, texture factories, sprite atlas organization, 3D model loading, and programmatic asset creation.
npx skillsauth add abdullah4ai/apple-dev-docs game-assetsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use nw_download_asset to download sprites, backgrounds, textures, sounds, and 3D models from free CC0 sources:
nw_download_asset:
project_dir: /path/to/project
app_name: MyGame
url: https://example.com/sprite.png (HTTPS only)
asset_name: paddle (becomes Assets.xcassets/paddle.imageset/)
asset_kind: sprite | background | texture | sound | model
After download, use in SpriteKit:
let texture = SKTexture(imageNamed: "paddle")
let sprite = SKSpriteNode(texture: texture)
After download, use in SceneKit (3D models):
let scene = SCNScene(named: "car.usdz")!
let modelNode = scene.rootNode.childNodes.first!
Trusted free sources:
Generate sprites in code — no external files needed:
import UIKit
import SpriteKit
class TextureFactory {
static func circle(diameter: CGFloat, color: UIColor) -> SKTexture {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: diameter, height: diameter))
let image = renderer.image { ctx in
color.setFill()
ctx.cgContext.fillEllipse(in: CGRect(x: 0, y: 0, width: diameter, height: diameter))
}
return SKTexture(image: image)
}
static func roundedRect(size: CGSize, color: UIColor, cornerRadius: CGFloat = 8) -> SKTexture {
let renderer = UIGraphicsImageRenderer(size: size)
let image = renderer.image { ctx in
color.setFill()
UIBezierPath(roundedRect: CGRect(origin: .zero, size: size), cornerRadius: cornerRadius).fill()
}
return SKTexture(image: image)
}
static func gradient(size: CGSize, colors: [UIColor]) -> SKTexture {
let renderer = UIGraphicsImageRenderer(size: size)
let image = renderer.image { ctx in
let cgColors = colors.map { $0.cgColor } as CFArray
let gradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: cgColors, locations: nil)!
ctx.cgContext.drawLinearGradient(gradient,
start: .zero, end: CGPoint(x: 0, y: size.height),
options: [])
}
return SKTexture(image: image)
}
}
Always use SKSpriteNode with generated textures — SKShapeNode is significantly slower and drops FPS. Convert shapes:
let shape = SKShapeNode(circleOfRadius: 15)
shape.fillColor = .white
let texture = view.texture(from: shape)!
let sprite = SKSpriteNode(texture: texture) // Use this instead of shape
Assets.xcassets/
├── AppIcon.appiconset/
├── AccentColor.colorset/
├── Game/
│ ├── player.imageset/ (individual game sprites)
│ ├── enemy.imageset/
│ ├── background.imageset/
│ └── UI_Atlas.spriteatlas/ (grouped UI sprites for performance)
Rules:
.spriteatlas folders for rendering performanceGenerate WAV data in memory — no audio files needed:
func generateTone(frequency: Float, duration: Float, volume: Float = 0.5) -> AVAudioPlayer? {
let sampleRate: Float = 44100
let samples = Int(sampleRate * duration)
var data = Data()
// ... WAV header + PCM samples (see spritekit-game skill for full implementation)
return try? AVAudioPlayer(data: data)
}
Common game sound recipes:
Alternative: SKAction.playSoundFileNamed("hit.wav", waitForCompletion: false) if you download WAV files via nw_download_asset.
If no suitable download exists, generate colored shapes:
// Paddle
let paddle = SKSpriteNode(texture: TextureFactory.roundedRect(
size: CGSize(width: 120, height: 20),
color: .systemBlue,
cornerRadius: 10
))
// Ball
let ball = SKSpriteNode(texture: TextureFactory.circle(
diameter: 20,
color: .white
))
// Background
let bg = SKSpriteNode(texture: TextureFactory.gradient(
size: scene.size,
colors: [UIColor(red: 0, green: 0.3, blue: 0, alpha: 1), UIColor(red: 0, green: 0.2, blue: 0, alpha: 1)]
))
Downloaded or well-crafted procedural assets always look better than plain colored rectangles.
Use nw_download_asset with asset_kind: "model" to download 3D models (USDZ, OBJ, DAE, SCN):
nw_download_asset:
project_dir: /path/to/project
app_name: MyGame
url: https://example.com/car.usdz
asset_name: car
asset_kind: model
Models are placed in <AppName>/Models/ and loaded via:
// USDZ/OBJ via ModelIO
import ModelIO
import SceneKit.ModelIO
let url = Bundle.main.url(forResource: "car", withExtension: "usdz")!
let modelNode = SCNReferenceNode(url: url)
// SCN/DAE directly
let scene = SCNScene(named: "car.scn")!
let modelNode = scene.rootNode.childNodes.first!
Many 3D games can be built entirely from SceneKit primitives:
// Bowling pin from cylinder + sphere
let pinBody = SCNCylinder(radius: 0.15, height: 0.8)
let pinHead = SCNSphere(radius: 0.18)
// Race car from boxes
let carBody = SCNBox(width: 1.5, height: 0.4, length: 3.0, chamferRadius: 0.1)
let wheel = SCNCylinder(radius: 0.3, height: 0.15)
// Board game piece from capsule
let piece = SCNCapsule(capRadius: 0.2, height: 0.6)
Use programmatic materials (diffuse color, metalness, roughness) instead of texture files for clean, stylized looks.
Generate textures for 3D materials programmatically:
class TextureFactory3D {
static func solidColor(_ color: UIColor, size: CGFloat = 64) -> UIImage {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: size, height: size))
return renderer.image { ctx in
color.setFill()
ctx.fill(CGRect(x: 0, y: 0, width: size, height: size))
}
}
static func woodGrain(size: CGFloat = 256) -> UIImage {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: size, height: size))
return renderer.image { ctx in
UIColor.brown.setFill()
ctx.fill(CGRect(x: 0, y: 0, width: size, height: size))
UIColor(white: 0.3, alpha: 0.3).setFill()
for i in stride(from: 0, to: size, by: 8) {
ctx.fill(CGRect(x: 0, y: i, width: size, height: 2))
}
}
}
}
// Apply to material
material.diffuse.contents = TextureFactory3D.woodGrain()
testing
Use for 3D games: racing, 3D sports, board games, marble maze, tower defense, bowling. SceneKit + SceneView architecture, 3D scene hierarchy, physics, game loop, primitives, materials, cameras, particles, audio.
documentation
Game UI patterns: SwiftUI HUD overlays on SpriteKit, menus (main/pause/game-over), virtual joystick/d-pad, score displays, health bars, tutorial onboarding.
testing
Use for 2D games: arcade, puzzle, sports, ping pong, platformer, shooter, 2D racing. SpriteKit + SpriteView architecture, scene hierarchy, physics, game loop, audio, particles, game feel.
tools
Share extension with NSExtensionActivationRule filtering, SLComposeServiceViewController handling, App Group data sharing, and shared content processing for URLs, text, and images. Use when adding share sheet integration to an iOS app.