A while back I was asked to work on something a bit different: an iPhone app to control the lighting on high end yachts.
The lighting on a boat like that is not a wall switch. It is an LED system wired back to a dedicated colour wheel controller, and the job was to put a phone in front of that controller so the owner or the crew could walk around and set the boat up rather than hunting for panels.

The brief
Turn lights on and off. Dim them. Pick a colour off a wheel and watch every light on the boat follow it. Group them so a room, a deck or the whole vessel moves together. And drive them in time with the music, which is the feature everyone asks to see first.
All of it over the boat's own network, speaking to the lighting controller directly. No cloud, no account, no internet. The phone and the controller were on the same local network and that was the whole system.
Art-Net, over UDP
The controller spoke Art-Net, which is the lighting world's way of carrying DMX512 over an ordinary network. DMX comes from stage lighting: a universe of 512 channels, each one a byte, and a fixture listening on the channels assigned to it. Art-Net wraps that in UDP so you can send it over Ethernet or wifi instead of a dedicated cable run.
UDP is the right fit for it. Small datagrams fired at a known address and port, nothing to connect, nothing to keep open, and no handshake sitting between a finger on a colour wheel and a light actually changing. When someone is dragging across a wheel you are sending a stream of values, and the last one matters far more than any of the ones before it.
The thing you learn quickly is that sending is not the same as arriving. UDP gives you no acknowledgement and no ordering, so the app cannot treat its own last packet as the truth about the boat. A lighting protocol handles that by repeating itself rather than by asking for confirmation, and once that clicks, a lot of the design follows from it.
Appcelerator and UDP sockets
The app was built in Appcelerator Titanium, so it was JavaScript driving genuinely native iOS controls. The networking came from Titanium's UDP socket API: create a socket, bind it to a port, send a datagram to the controller's address, and listen for what comes back on the same one.
Low level networking is the kind of thing cross platform frameworks are usually bad at, and it was genuinely one of the smoother parts of the project. Everything above the socket was ordinary app work. Everything below it was the boat.
Why I enjoyed it
I love building things where the software has a physical result. Most of what I work on ends with pixels moving on a screen. This one ended with a room full of light changing colour because someone dragged a thumb across a wheel, and the gap between those two things is a few bytes on a wire.
The video above is a short walkthrough of the app, and there is a second clip below.