Tag Archives: Apple

Scripting macOS Image Playground to Create Game Assets for free, automatically, and locally.

TL;DR

https://github.com/wojtczyk/game-art-generator

Sample images created in one go by scripting Image Playground.

Introduction

I like agentic coding. All you need is an idea… and some technical understanding to course-correct, when the agent wanders off. I have never been short on ideas, but rather short on time to implement and execute on every one of those.

When I was ~14, we got our first computer – an IBM PC compatible with VGA graphics running MS-DOS. We had three games: a racing game, a point and click adventure, and I forgot what the third was. Maybe we had just two. Anyways, I enjoyed playing them. I got good at playing them. I wonder if my parents worried that I played too much.

However after a while I was really curious how games are made and I wanted to make my own. This is what got me into programming. My older brother had a programming class at school in Turbo Pascal. I wanted to learn from him everything he learned. I made my first game and sold one copy to a friend for 1 Deutsche Mark. Mission accomplished.

In the meantime I went to college, studied computer science, worked on sensor guided and ML enabled robots for most of my professional life and here I am on a Friday evening with a ChatGPT Plus subscription for $20 and a ten year old game idea popping back into my head. “Well, you better do it – now”.

Within two hours I had a playable prototype on my iPhone. I was pumped. Only the graphics looked… lousy. Codex created a python script, that used Pillow to draw lines into a canvas and save PNGs. “If it creates line art, then have it at least create SVGs”… so shortly after it had SVGs. Still – I felt many of the assets were too abstract and it burned tokens too fast without the results that I wanted. Here for example is the image of a Bull.

A Bull, I guess. An abstract Bull.

I should add: you can add skills or plugins to Codex for image creation. It suggested the Canva plugin and the HuggingFace plugin with an image creation model. But it required to create accounts and add credit cards and I didn’t feel like it.

The next Friday evening – it sounds much worse than it is: having a Friday evening with no plans is wonderful. The next Friday evening I wanted to get back to the game. I recalled my mac has this Image Playground. What if I prompt it to create the game art I need. A few minutes in, I had an illustrated Bull, that looked neat, but had background clutter…

…a few minutes later it was on a white background – easy to cut out as a sprite.

Problem Statement

Great – I could use my M1 MacBook with Apple Intelligence and local models to create the game assets I needed for free without burning tokens. The only issue was: at the current stage of the game prototype I already needed 41 game art pieces and I didn’t feel like clicking around and entering the prompts and exporting the images manually. And I knew, there were more to come.

I needed a solution that scales. I went to sleep and woke up thinking about writing an angry blog post that Image Playground should be scriptable. Then I thought: “Check first, if it is scriptable!” – An online search was negative on Apple Script but positive on an Image Playground API. https://developer.apple.com/documentation/ImagePlayground/ImageCreator. “Oh nice! That saves me an angry blog post nobody would care about.”

The Journey

I wrote up a prompt for codex:

Implement a macos program that uses Image Playground ImageCreator https://developer.apple.com/documentation/ImagePlayground/ImageCreator to generate gameplay artwork. It shall take in as parameters...

Four minutes later with GPT-5.4 Extra High it appeared I had a Swift script that should create the assets, only that it turned out errors:

[1/9] Generating 3 image(s) for backgrounds/forest/day-sky
Image generation failed for backgrounds/forest/day-sky: Image creation is not available when the application is hidden or running in the background.

What followed was a bit back and forth of me executing and pasting the errors, then telling codex to do it itself, codex burning through 60% of my daily token allowance not getting anywhere until I stopped it. I did some research and instructed it to create an application window that gets pushed into the foreground to try to circumvent the issue. Codex changed the code, created a windowed app wrapper and off we go. Assets were created in batch as described in the prompt file and stored in the directory structure as needed. I felt accomplished. 🎉

.build/release/game-art-generator --assets assets/example.txt --style illustration --n 3
Writing artwork to /Users/martin/Projects/codex/game-art-generator/assets/2026-04-19_11.39_example-art-for-review
[1/9] Generating 3 image(s) for backgrounds/forest/day-sky
prompt: "bright forest canopy with soft clouds and layered parallax depth"
created /Users/martin/Projects/codex/game-art-generator/assets/2026-04-19_11.39_example-art-for-review/backgrounds/forest/day-sky-1.png
created /Users/martin/Projects/codex/game-art-generator/assets/2026-04-19_11.39_example-art-for-review/backgrounds/forest/day-sky-2.png
[...]

I was asked if I can turn this into a product. 🦄 “Maybe, but I don’t feel like it. I’d rather just put it on GitHub for others to use if they run into the same issue”. Enjoy!

Learnings

A prompt can give you a solution within 5 minutes. Then you still need an hour to refine the result. The most difficult part for scripting Image Playground was to realizing that the API needs a foreground window. Probably to justify loading the neural networks and occupying the CPU and GPU.

Overall I am happy with the results of Image Playground. At least happier than with the outputs of Codex. Sometimes you just have to look and you already have what you need and can throw your own compute at it.

The Game Art Generator

Below is the GitHub URL. Instructions on howto build and use it are in the README.md. Maybe it will help someone else out there to create their game or unblock them on their prototype.

https://github.com/wojtczyk/game-art-generator

Some more image variations it created with the example assets file. Now I just need to adapt the prompts in one text file and hope for the best.

Is my vision that bad? No, it’s just a bug in Apple’s Calculator.

While programming on my Mac and converting decimal numbers to hex and binary and using Apple’s Calculator for it – because it is built-in and works decent – I thought, I saw some wobbly lines of numbers.

My first thought was: my eyes are getting tired. But it looked annoyingly wobbly and there went my focus on the task. I had to investigate, what was going on. I took a screenshot. Can you see it in the image above?

Let me highlight the annoying detail in the image below.

Maybe you are reading this on a tiny screen, or your eyes are tired, but also… I had to see it for myself. Here is a zoomed in version below:

Yes, indeed! Some digits in the binary display section are off by one pixel. Nice anti-aliased rendering by the way, but still, why are some digits misplaced by a pixel?

How did this happen? I should add, the calculator app has been open for many days. Maybe the UI coordinate system is using floats and a rounding error aggregated over many days… I’d love to find out, but I guess I won’t. Anyways, at least my vision is not that bad.

I would contact Apple, if there was a feedback option, but there isn’t, so I won’t. Instead I’ll just share the bug on the Internet. Enjoy!

How-to allow Mac OS X’s Gatekeeper to run an unsigned application

Eclipse sandboxed by Mac OS X Gatekeeper.

Eclipse sandboxed by Mac OS X Gatekeeper.

After I recently reinstalled my MacBook Air with Mac OS X Mavericks, I encountered for the first time Gatekeeper – the sandbox, that won’t allow to run applications from unverified sources to improve Mac OS X security. However that also excludes the commonly used IDE Eclipse.

Problem: Eclipse (or other application) won’t launch in Mac OS X Mavericks.

Solution: delete extended quarantine attribute – which probably Safari or Finder added after the download. Enter the following command in the Terminal to allow Eclipse to launch.

$ xattr -d com.apple.quarantine eclipse.app

This way you can leave the sandbox in place and only add exceptions for applications, that you cannot live without. For further information on and graphical configuration options of Gatekeeper check out this Ars Technica article.

Apple Scholarship for WWDC 2012

Apple’s annual Worldwide Developers Conference is an exciting event providing an in-depth and inside look at the latest in iOS and OS X. Tickets are always high in demand and have sold out within two hours this year. In addition to the regular tickets, which sold for $1599, Apple accepted applications for one of 150 scholarships.

I have been very excited all day when I received an email from Apple granting me a scholarship to attend WWDC 2012. Thank you, Apple!

Scholarship notification email for WWDC2012

Scholarship notification email for WWDC2012

iChem

iChem Logo

iChem

iChem is a case study to bring aquatic chemistry calculations on the iPhone to the classroom. The computational nature of aquatic chemistry lends itself well to the iPhone platform and by providing students with a simple means of performing laborious calculations, the underlying chemistry of the problem being studied can be the primary focus rather than the calculations.

The application features Activity Coefficient, Ionization Fraction and Equilibrium Constant computations. The goal is to provide a user friendly tool for chemistry students, which enables them to quickly solve standard computations on their fingertips. The tool will be made available to the public, soon.

iChem Screenshots

iChem Screenshots

[1] Martin Wojtczyk, Mark A. Nanny, and Chetan T. Goudar. Aquatic Chemistry on the iPhone: Activity Coefficient, Ionization Fraction and Equilibrium Constant determination. In 239th American Chemical Society National Meeting & Exposition, San Francisco, USA, March 2010.

Sync your Motorola C390 with iSync for free

Motorola C390

Recently my SonyEricsson cellphone broke and I wanted to replace it by my Bluetooth enabled Motorola C390. Apple’s iSync is really great to keep your address book and calendar in sync with your cellphone. Unfortunately the C390 is not supported by default. Your Mac can pair with the phone and use it for data connections but iSync does not support it, see [1].

There seem to be some commercial solutions which may help, though I didn’t test one of them, just search the web for iSync and C390 and you will find them.

iSync C390

Luckily I also found this guy’s Howto in a forum about adding Motorola C390 support to iSync for free just by modifying a xml file [2]. However, since I am running Mac OS X 10.4.9, I recognized slight changes in the xml tag names. That’s why I noted the instructions below.

Enabling Motorola C390 for iSync

  • Right click on the iSync Application
  • Show Package Contents
  • Goto Contents/Plugins/ApplePhoneConduit.syncdevice/Contents/ Plugins/PhoneModelsSync.phoneplugin/Contents/ Resources
  • Backup and modify the MetaClasses.plist file to make it look like below in the beginning
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.motorola.C390</key>
    <dict>
        <key>Identification</key>
        <dict>
            <key>com.apple.gmi+gmm</key>
            <string>"Motorola CE, Copyright 2000"+C390</string>
        </dict>
        <key>InheritsFrom</key>
        <array>
            <string>com.motorola.usb-bt.0x22B8/0x4902</string>
        </array>
            <key>Services</key>
        <array>
            <dict>
                <key>ServiceName</key>
                <string>com.apple.model</string>
                <key>ServiceProperties</key>
                <dict>
                    <key>ModelIcon</key>
                    <string>MOTC390.tiff</string>
                    <key>ModelName</key>
                    <string>C390</string>
                </dict>
            </dict>
        </array>
    </dict>
</dict>
  • You will need a tiff file, with the name you entered under ModelIcon, but you can just copy it from another one in the same folder as the MetaClasses.plist file
  • Start iSync
  • Select Devices->Add Device from the menu
  • et voilà, your Motorola C390 should show up as a supported phone

I synced my address book and calendar successfully with it, so I don’t know, why the phone is not supported by default. Anyways, use at your own risk.

Wiimote controls Front Row on a PowerBook

Wiimote

I have this 2005 12″ PowerBook G4 with Mac OS X Tiger 10.4.9 and was jealous of the new MacBooks’ Remote Controls. One day I found a movie on youtube about someone controlling Front Row with a Wiimote. I just didn’t find all the links in one place. Maybe this is of help for you. It should work on other Bluetooth enabled Macintosh computers as well.

1. Get Front Row to work on a Mac without Remote Control

2. Install DarwiinRemote

  • Get DarwiinRemote
  • The key mapping matches the one of Front Row by default, though, you might want to change the Wiimote’s + and – buttons to change volume control as well

Works like a charme.

You can also use the Wiimote with DarwiinRemote to go through your PowerPoint Presentations 🙂

xerces-c-src_2_6_0 on Mac OS X Tiger

Issue

When I tried to compile Xerces-C++ Version 2.6.0 from source on Mac OS X Tiger 10.4.2 with gcc-4.0.0 the compiler complained:

MacOSUnicodeConverter.cpp:78: error: 'static' may not be used when defining 
(as opposed to declaring) a static data member
MacOSUnicodeConverter.cpp:84: error: 'static' may not be used when defining 
(as opposed to declaring) a static data member
make[2]: *** [MacOSUnicodeConverter.o] Error 1
make[1]: *** [transcoders] Error 2
make: *** [Util] Error 2

Solution

The solution is easy, just delete the word static in the source code manually and build again or use this patch:

xerces-c-src_2_6_0-tiger.diff

Patch instructions

Download the Xerces-C++ source distribution from [1].

The sources contained in my case version 2.6.0.

Extract sources and apply patch:

tar xzf xerces-c-current.tar.gz
cd xerces-c-src_2_6_0
patch -p1 <../xerces-c-src_2_6_0-tiger.diff

Please make sure that the paths are adjusted to your system. Follow the official build instructions Building Xerces-C++ from the Mac OS X command line at [2] afterwards.

Qt-mac-free-3.3.4 on Mac OS X Tiger

Hint

If you don’t need specifically qt-mac-free-3.3.4 but any 3.3.x would do it, you might want to check out Trolltech’s recently published Version 3.3.5. If you ever wondered – like me – where you can still download the 3.3.x branch have a look at

ftp://ftp.trolltech.com/qt/source/

It seems that you can’t find any more download links for 3.3.x at Trolltech’s webpage.

Issue

When I tried to compile Qt for Mac 3.3.4 from source on Max OS X Tiger 10.4.2 with gcc-4.0.0 the compiler complained:

kernel/qaccessible_mac.cpp:189: error: non-local variable 
'<anonymous struct> text_bindings [][10]' uses anonymous 
type
make[2]: *** [.obj/release-shared/qaccessible_mac.o] Error 1
make[1]: *** [sub-src] Error 2
make: *** [init] Error 2

and

network/qsocketdevice_unix.cpp: In function `int qt_socket_accept(int, 
sockaddr*, int*)':
network/qsocketdevice_unix.cpp:47: error: invalid conversion from 'int*' to 
'socklen_t*'
network/qsocketdevice_unix.cpp:47: error:   initializing argument 3 of 'int 
accept(int, sockaddr*, socklen_t*)'
network/qsocketdevice_unix.cpp: In member function `QSocketDevice::Protocol 
QSocketDevice::getProtocol() const':
network/qsocketdevice_unix.cpp:132: error: invalid conversion from 'int*' 
to 'socklen_t*'
network/qsocketdevice_unix.cpp:132: error:   initializing argument 3 of 
'int getsockname(int, sockaddr*, socklen_t*)'
network/qsocketdevice_unix.cpp: In member function `int 
QSocketDevice::option(QSocketDevice::Option) const':
network/qsocketdevice_unix.cpp:324: error: invalid conversion from 'int*' 
to 'socklen_t*'
network/qsocketdevice_unix.cpp:324: error:   initializing argument 5 of 'int 
getsockopt(int, int, int, void*, socklen_t*)'
network/qsocketdevice_unix.cpp: In member function `virtual Q_LONG 
QSocketDevice::readBlock(char*, Q_ULONG)':
network/qsocketdevice_unix.cpp:784: error: invalid conversion from 'int*' 
to 'socklen_t*'
network/qsocketdevice_unix.cpp:784: error:   initializing argument 6 of 
'ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*)
network/qsocketdevice_unix.cpp: In member function `void 
QSocketDevice::fetchConnectionParameters()':
network/qsocketdevice_unix.cpp:1053: error: invalid conversion from 'int*' 
to 'socklen_t*'
network/qsocketdevice_unix.cpp:1053: error:   initializing argument 3 of 
'int getsockname(int, sockaddr*, socklen_t*)'
network/qsocketdevice_unix.cpp:1057: error: invalid conversion from 'int*' 
to 'socklen_t*'
network/qsocketdevice_unix.cpp:1057: error:   initializing argument 3 of 
'int getpeername(int, sockaddr*, socklen_t*)'
make[2]: *** [.obj/release-shared/qsocketdevice_unix.o] Error 1
make[1]: *** [sub-src] Error 2
make: *** [init] Error 2

Additionally with both compilers gcc 4.0 and gcc 3.3 linking an application against qt-mac-free-3.3.4 resulted in warning messages like the following, because Mac OS X Tiger comes with additional dynamic library handling functions which now conflict with qt:

/usr/bin/ld: warning multiple definitions of symbol _dlsym
/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/../../../libpthread.dylib
(dyldAPIsInLibSystem.o) definition of _dlsym
/usr/local/lib/libqt-mt.dylib(dlfcn.o) definition of _dlsym
/usr/bin/ld: warning multiple definitions of symbol _dladdr
/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/../../../libpthread.dylib
(dyldAPIsInLibSystem.o) definition of _dladdr
/usr/local/lib/libqt-mt.dylib(dlfcn.o) definition of _dladdr
/usr/bin/ld: warning multiple definitions of symbol _dlclose
/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/../../../libpthread.dylib
(dyldAPIsInLibSystem.o) definition of _dlclose
/usr/local/lib/libqt-mt.dylib(dlfcn.o) definition of _dlclose
/usr/bin/ld: warning multiple definitions of symbol _dlerror
/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/../../../libpthread.dylib
(dyldAPIsInLibSystem.o) definition of _dlerror
/usr/local/lib/libqt-mt.dylib(dlfcn.o) definition of _dlerror
/usr/bin/ld: warning multiple definitions of symbol _dlopen
/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/../../../libpthread.dylib
(dyldAPIsInLibSystem.o) definition of _dlopen
/usr/local/lib/libqt-mt.dylib(dlfcn.o) definition of _dlopen
/usr/bin/ld: warning suggest use of -bind_at_load, as lazy binding 
may result in errors or different symbols being used
symbol _dladdr used from dynamic library /usr/lib/gcc/
powerpc-apple-darwin8/4.0.0/../../../libpthread.dylib
(dyldAPIsInLibSystem.o) not from earlier dynamic library 
libqt-mt.3.dylib(dlfcn.o)
symbol _dlclose used from dynamic library /usr/lib/gcc/
powerpc-apple-darwin8/4.0.0/../../../libpthread.dylib
(dyldAPIsInLibSystem.o) not from earlier dynamic library 
libqt-mt.3.dylib(dlfcn.o)
symbol _dlerror used from dynamic library /usr/lib/gcc/
powerpc-apple-darwin8/4.0.0/../../../libpthread.dylib
(dyldAPIsInLibSystem.o) not from earlier dynamic library 
libqt-mt.3.dylib(dlfcn.o)
symbol _dlopen used from dynamic library /usr/lib/gcc/
powerpc-apple-darwin8/4.0.0/../../../libpthread.dylib
(dyldAPIsInLibSystem.o) not from earlier dynamic library 
libqt-mt.3.dylib(dlfcn.o)
symbol _dlsym used from dynamic library /usr/lib/gcc/
powerpc-apple-darwin8/4.0.0/../../../libpthread.dylib
(dyldAPIsInLibSystem.o) not from earlier dynamic library 
libqt-mt.3.dylib(dlfcn.o)

Solution

Apply the following patch:

qt-mac-free-3.3.4-tiger.diff

Patch instructions

Extract sources and apply patch:

tar xjf qt-mac-free-3.3.4.tar.bz2
cd qt-mac-free-3.3.4
patch -p1 <../qt-mac-free-3.3.4-tiger.diff

Please make sure that the paths are adjusted to your system. Follow the official build instructions afterwards. After applying the little patch qt-mac-free-3.3.4 and applications linked to it should build fine with gcc 4.0 and gcc 3.3.

References

My patch is based on the following Articles: