James Stanley


Tagged: all | software | 3dprinting | electronics | cnc | cpu | science | bitcoin | puzzle | metalwork | smsprivacy | philosophy | chess | futurology | keyboard | wigwag | cryptography | cybercrime | lawnmower | magic | protohackers | banglejs | clocks | ipfs | pikon | rc2014 | steganography | tor | ricochet

Bare minds
Sun 6 October 2024
Back in the Stone Age, humanity was just scraping by with not much more than our bare hands. Working with AI has showed me that, all this time: we've just been scraping by with our bare minds. If computers were meant to be bicycles for the mind, then AI is jetpacks for the mind. Read more

Encyclopedia Mechanica
Tue 10 September 2024
I've been working on a new online encyclopedia project, and it is almost ready to rival Wikipedia. It's called Encyclopedia Mechanica. Pages are created on-demand by an LLM in response to user queries, so in a way we actually have more pages than Wikipedia already, albeit with more errors. Read more

I made an LLM-powered Colonel Blotto game
Sun 21 July 2024
Today I made a Colonel Blotto game where you play against GPT-4o, and after each round you can chat with GPT-4o to get commentary/analysis/coaching. Play with it at blotto.incoherency.co.uk until I run out of OpenAI credit. Read more

Secrets of the ChatGPT Linux system
Sun 16 June 2024
Have you noticed that ChatGPT sometimes writes out Python code and somehow executes it? How does that work? What kind of environment is it using? Can we co-opt it for our own ends? Let's find out! Read more

How to read from a TCP socket (but were too afraid to ask)
Sat 10 February 2024
You can get surprisingly far, before it bites you, with only a fuzzy and incorrect understanding of how you should read from a TCP socket. I see this often in (failing) Protohackers solutions. Once you are over the initial hurdle of reading enough documentation to actually get a TCP session connected, there are 2 key things you need to understand: Read more

dnstweak: quick local DNS spoofing tool
Tue 11 July 2023
I spent most of today writing dnstweak, a program that temporarily inserts itself as the local DNS resolver (by writing to /etc/resolv.conf) and spoofs responses to selected DNS requests. Read more

Exploiting an insecure cipher in the wild
Thu 6 July 2023
I found that the topology_hiding module for OpenSIPS encodes data using an insecure cipher, such that it can be decoded without knowing the key, leaking both the plaintext and the key. Read more

Revisiting oscillating engine loss calibration
Mon 1 May 2023
Since my Wig-Wag has run in a bit now, I have revisited the loss calibration. Read more

Calibrating losses in the oscillating engine simulator
Thu 13 April 2023
The biggest unknown variable in the oscillating engine simulator is the amount of friction loss that an engine is likely to experience. To calibrate the simulation I have measured the speed of my engine at various supply pressures and then simulated the same conditions, adjusting the simulated loss until the speed matches. Read more

Oscillating Engine Simulator
Sun 19 March 2023
I've been working on an oscillating engine simulator. It's a type of steam engine where instead of valve gear, the cylinder swings back and forth, exposing a hole in the cylinder to an inlet port for the power stroke, and to an exhaust port for the exhaust stroke. Very simple. (I've also been working on building one, in the form of a Wig-Wag, but I haven't got very far with that). Read more

Solving Protohackers with Fly.io
Sat 24 September 2022
This post walks you through hosting a Go solution for the Protohackers Smoke Test problem using Fly.io for free hosting. Read more

Nightdrive
Fri 16 September 2022
I've made a JavaScript simulation of driving at night time on the motorway. It's hard to classify what it is. It's not a video, because it's generated dynamically. It's not a game, because you just watch. It's not a screensaver, because it's not the 90s. Maybe it's a "demo"? Read more

Protohackers problem 1 retrospective
Sat 27 August 2022
I released Protohackers problem 1 on Thursday evening. The problem asks you to implement a server that accepts JSON-encoded requests, tests numbers for primality, and gives JSON-encoded responses. (This post contains spoilers for the problem; if you have not solved it yet, and you would like to solve it, then to avoid disappointment you should not read this until after you've solved it!). Read more

Protohackers: a new server programming challenge
Tue 23 August 2022
For the last couple of weeks I've been working on Protohackers, which is a programming challenge where you have to implement a server for a network protocol, and your server is automatically checked to see if it works properly. It's a bit like Advent of Code, but for networking instead of algorithms. Read more

A SLANG interpreter for SCAMP
Wed 10 August 2022
I made the interpreter by ripping the parser out of the compiler, making it produce an AST instead of assembly code, and writing a recursive evaluator for the AST. It was way less work than writing the Lisp interpreter, and it runs programs about 100x faster than the Lisp interpreter. Read more

A Lisp interpreter for SCAMP
Wed 3 August 2022
Lisp has been the most recent step in my search for the ultimate SCAMP programming environment. Unfortunately what I have so far is so slow that it's probably another dead-end. It's about 300x slower than compiled SLANG code. Read more

Cheating at chess with a computer for my shoes
Sat 30 July 2022
I have come up with a new way to win at chess: I have connected up a Raspberry Pi Zero in my pocket to some buttons and vibration motors in my shoes, so that I can surreptitiously communicate with a chess engine running on the Pi. The project is called "Sockfish" because it's a way to operate Stockfish with your socks. Read more

Do I really want a lambda calculus cyberdeck?
Wed 13 July 2022
A cyberdeck is an inconvenient portable computing device, often with a retro sci-fi aesthetic. Lambda calculus is an inconvenient mathematical model of computing. A lambda calculus cyberdeck, therefore, is an inconvenient device for inconvenient computing. Read more

Eldood: what Doodle used to be
Fri 1 July 2022
I have made Eldood as a replacement for Doodle, because Doodle is now shit. If you used to like Doodle but have grown frustrated with it, try Eldood. Read more

The ultimate SCAMP development environment
Wed 15 June 2022
I've been thinking about what I want the SCAMP development workflow to look like for this year's Advent of Code. At first I was planning to do it in FORTH, but I've tried to get into FORTH several times and haven't got on with it. I like the simple REPL of FORTH but I very much do not like the language. So the plan is to come up with a way to make a REPL for SLANG. Read more

Meshmill: open source 3D CAM
Tue 3 May 2022
For the last couple of weeks I've been working on Meshmill. It's a new 3D CAM program for Linux. Read more

An Arduino-based USB interface to the Psion Organiser II
Sat 5 February 2022
I built a hacky USB interface to the Psion Organiser II that lets you send messages to it over USB serial via an Arduino Nano. It involves the organiser executing machine code stored in a string in its BASIC-like language, and it totally abuses the CPU's bus design. But it's simple and it works. Read more

Waypointer Moto: motorcyle navigation for Bangle.js
Thu 27 January 2022
I have made a Bangle.js app for motorcycle navigation. It's called "Waypointer Moto" which is a bit of a mouthful but it doesn't matter. Instead of telling you exactly which roads to use to reach your destination, it just points an arrow directly at your destination and tells you the straight-line distance. It tells you where you're trying to end up, but leaves the route-finding and exploring of the environment up to the user. The idea is that you end up riding new roads and discovering places you would never normally come across. It's a middle ground between riding around at random, and following a route dictated by a satnav. Read more

Advent of Code on my homemade CPU
Fri 31 December 2021
This year I've built a 16-bit CPU, along with custom operating system and programming language. It runs at 1 MHz and has 64 KWords of memory. This December I used it to do Advent of Code. Read more

Choozi for Bangle.js
Tue 14 September 2021
Do you know Chwazi? It is an Android app that chooses a person at random. Everyone puts in their finger and it selects one at random to highlight. It's useful for example if you're playing a board game and need to select a person at random. Read more

Approximating Lenna with a neural net
Wed 8 September 2021
Last night, inspired by a comment on HN about creating images with randomised neural nets by mapping inputs (x,y) to outputs (r,g,b), I spent some time trying to train a small neural net to approximate Lenna, the famous image processing test input. The outputs are quite interesting to look at, but don't approximate Lenna very well. But I don't know anything about machine learning, so I think you could do much better than I managed. Read more

Play with SCAMP from the comfort of your browser
Mon 9 August 2021
Today I ported the SCAMP emulator to the web, using emscripten to compile C to WebAssembly, and Xterm.js to provide the terminal emulator. Read more

Porting Hamurabi to SCAMP
Fri 6 August 2021
That's right! 1968's most exciting video game release is coming to 2021's most disappointing CPU architecture. Hamurabi is a single-player text-based game in which you play the leader of ancient Sumeria for 10 years. Each year, you decide how much land to buy or sell, how much food to feed to the population, and how much land to plant with seeds. Occasionally a plague comes along and kills half the population, or rats eat some of the harvest. Land values, harvest yields, and immigration rates fluctuate unpredictably. At the end of the 10 years (if you haven't been forcibly removed from office already) your performance is evaluated. Read more

SCAMP update
Thu 24 June 2021
I've made a bit more progress on my SCAMP CPU. I/O performance is improved significantly since last time, the CompactFlash card now lives on a PCB instead of a breadboard, I'm using a real (ish) serial console instead of an FTDI cable, and I have a more permanent power supply instead of the bench power supply. Read more

SCAMP has booted up to the shell for the first time
Sun 25 April 2021
I reached another good milestone on SCAMP this week: the physical hardware booted all the way up to the shell. Granted, it only happened once, and I couldn't type any input once it got there. But it suggests that there are no fundamental problems with the hardware design that will prevent the computer from working, which I am very happy about. Read more

The kilo editor
Sat 3 April 2021
Thanks to the excellent Build Your Own Text Editor tutorial, SCAMP/os now has an editor. It's pretty bare-bones, but perfect for what I need. Read more

SCAMP is alive
Sun 21 March 2021
I have reached a good milestone on the SCAMP hardware: it can now execute code! It runs all the way through the test program correctly. Read more

The SCAMP kernel
Sat 27 February 2021
You might think it's a bit early to be working on an operating system, given that I don't have a CPU to run it on. Maybe you're right. But working on software is easy and working on hardware is time-consuming, so here we are. Read more

A compiler for SCAMP, and machine code profiling
Fri 19 February 2021
I've been working on a compiler for the SCAMP CPU. It compiles a language I'm calling "SLANG" (which just stands for "SCAMP Language" pending a better backronym) into SCAMP assembly language. Read more

How to use an AT28C16 EEPROM with an Arduino Uno without a port expander
Wed 17 February 2021
The AT28C16 EEPROM stores 2048 bytes, which means to access it all you need to control 11 address lines and 8 data lines. You also need to operate "chip enable" (pull low to enable the AT28C16), "output enable" (pull low to enable output), and "write enable" (pull low to enable writing). That means in total you need to control 22 pins, but the Arduino Uno only has 12 general-purpose digital IO pins. Problem. Fortunately, there are some tricks that make it workable. Read more

My first attempt at milling a PCB
Fri 12 February 2021
I'm going to get most of the PCBs for SCAMP made by JLCPCB, but I'd like to try to mill the backplane on the CNC machine because it is both large (expensive at JLCPCB) and simple (single-sided, no vias, easy to make). Yesterday some small pieces of copper-clad board arrived and today I had a first attempt to see what would go wrong. Read more

Designing the instruction set for my TTL CPU
Sun 31 January 2021
I (believe I) am making good progress on designing the TTL CPU. Most of the actual CPU design is relatively stable now, and bug discoveries in the hardware design are infrequent, so now I get to move up a level and work on the instruction set. After that, it's just the bootloader, operating system, and application software. Oh, and the small matter of the physical hardware assembly... Read more

Adventures in CPU design
Fri 15 January 2021
On Graham's recommendation, I recently bought an iCE40 FPGA and have been learning a bit about how to use it. The iCE40 is good to get because there is good open-source tooling that supports it. I was originally going to get the iCEstick evaluation board, but there are other alternatives available more cheaply and with more logic elements. I ended up getting an iceFun and have found it to be quite easy to use. The example projects are helpful. Read more

I wrote a semi-literate brainfuck compiler for CP/M
Tue 29 December 2020
Literate Programming is "a programming paradigm introduced by Donald Knuth in which a computer program is given an explanation of its logic in a natural language". It's something I've wanted to have a go at for a while but never got around to. Yesterday, for fun, I wrote a brainfuck compiler for the RC2014 and it seemed like a good fit for Literate Programming because it's short enough to get my feet wet but has enough detail that there is some interesting stuff to explain. Read more

My Advent of Code Story
Sat 26 December 2020
4.40am. The alarm wakes me up, but I was pretty much awake already. I get out of bed, put on my dressing gown, make a cup of tea, and sit down at the computer. I warm up my fingers with a few rounds of 10fastfingers. I open up vim and type out my template: #!/usr/bin/perl, use strict; use warnings; while (<>) { chomp; }. I drink a sip of the tea and wait for the clock to tick down. 4:59:40. Almost time. My heart races. 4:59:55. I hover the mouse cursor over the number 22. 4:59:58. Why is time passing so slowly? The wait is agonising. 5:00:00. Finally. I click the left mouse button and off we go. Day 22 part 1: Crab Combat. The next 4 minutes and 58 seconds pass in a furious blur of reading, thinking, and typing. I submit my answer. 158th place. Gah, close. On to part 2. More reading, thinking, coding, debugging, until at 5:22:55 I submit my part 2 answer. 139th place. 0 points. Better luck next time. I browse Hacker News and /r/adventofcode for half an hour while the adrenaline wears off, and then go back to bed. Read more

Seasonal.css: Give your website a seasonal colour scheme
Fri 6 November 2020
I've been working on a project that gives a CSS colour scheme that varies based on the day of the year, with a vague attempt to match the colour to the season. In case you're wondering why my blog has a new purple colour scheme (at time of writing): this is why. Have another look tomorrow if you want to see the same content in an imperceptibly-different purple. Read more

CNC toolpath generation from heightmaps
Sat 24 October 2020
I've been struggling with generating complex toolpaths in FreeCAD and thought that an easy approach would be to render a heightmap of the part, and then generating a toolpath from that should be easy. I understand that this is already a recognised technique, although I could not find an open source tool that would do it for me. Most of the heightmap-related stuff I found on DuckDuckGo was to do with auto-levelling the bed. And, anyway, it's a relatively simple idea and a fun challenge, so I did it myself. Read more

I'm working on a VR car racing game for Oculus Quest
Sun 26 July 2020
I've been playing a bit of Mini Motor Racing X on the Oculus Quest recently. It's good. The experience of driving a car in virtual reality is amazing, but this particular game is too much "game" and not enough "simulator" for my taste. I've always preferred Gran Turismo to Mario Kart, for example. Unfortunately, the Quest is quite an unusual platform, and none of the popular racing games are available for it. I recently discovered that the open source game engine Godot has Oculus Quest support, so I'd like to make a basic car racing simulator for Oculus Quest. Read more

Making a game with 24a2
Sun 28 June 2020
24a2 is an "ultra-minimalist" game engine. It was posted on Hacker News this morning and I found it so interesting that I decided to take a day off from breaking keyboard switches and make a tiny game instead. Read more

An easy way to package Perl programs
Sat 16 May 2020
The right way to package Perl programs is with RPM, or DEB, or on CPAN with ExtUtils::MakeMaker or similar. But this is a hassle. Read more

Zero-downtime Docker container deployments with nginx
Thu 14 May 2020
Docker doesn't let you reassign port mappings while containers are running. That means if you want to deploy a new version of your application, you need to stop the old one and then start the new one, and there is a brief period of downtime in between. I wrote Ngindock to solve this problem. Read more

My RC2014 Web Server
Tue 10 December 2019
I wrote a web server for my RC2014. It runs from CP/M, which has no built-in concept of networking, so I had to implement every layer of the networking stack, which in this case is SLIP, IP, TCP, and HTTP. It totals about 1200 lines of C, all of which was written on the RC2014 in the ZDE 1.6 text editor, and compiled with the Hi-Tech C compiler. Read more

Telescope tracking with software auto-guiding
Wed 23 January 2019
The Earth rotates around its axis at a rate of ~360°/day, or ~15°/hr (it's actually slightly slower than this because "1 day" is the amount of time it takes for the sun to come around again, but we are also moving around the sun, so we don't need to rotate a full 360° per day). When zoomed in with a field-of-view only 0.25° wide, objects that are not very close to the North star appear to move quite quickly across the frame. For this reason, my telescope control software continually updates the coordinates that it wants to point at, in order to keep the scope pointed at the same part of the sky. Read more

Hiding messages in chess games
Tue 9 October 2018
I designed a steganography system that encodes data as a chess game. A convenient way to communicate chess games is PGN, but any means of communicating the moves of the game would work, as the information is encoded conceptually in the moves themselves, rather than taking advantage of any redundancy in the PGN format. Read more

A Rock-Paper-Scissors AI that is too good
Fri 25 May 2018
Yesterday I had an idea for a simple Rock-Paper-Scissors AI based on Markov chains. The "state" would be what the opponent played in the last N rounds, and would be used to predict the probability that the opponent would play Rock, Paper, or Scissors next. The AI would choose what to play, to beat what the opponent is expected to play, weighted by the expected probability for each possible action. Read more

How to run SSH and HTTP on the same port
Mon 26 February 2018
Last month I ran a small puzzle in which, after having picked up an SSH key in one of the rounds, a subsequent round involved connecting to a (supposed) web server using an SSH client. It's quite a neat trick so I thought it deserved sharing. Read more

Double-check Bitcoin addresses when pasting (Bitcoin TX Generator malware)
Sun 9 July 2017
Back in April I wrote about the Large Bitcoin Collider and how it is probably malware. Well, now there's another (even more blatant) piece of malware being spread via reddit. Read more

Hardbin: The World's Most Secure Encrypted Pastebin
Fri 19 May 2017
Over the past week I've been working on hardbin. Hardbin is an encrypted pastebin, with the decryption key passed in the URL fragment, and the code and data served securely with IPFS. (IPFS is a distributed content-addressable storage system that is web-compatible; it's basically bittorrent for the web). Read more

Steganographic Bitcoin seeds: Hiding cash in plain sight
Wed 22 February 2017
I made a tool, stegoseed, to generate sentences which steganographically encode Bitcoin wallet seeds, and to decode such sentences to retrieve wallet seeds. It comes with an example BIP39 seed to play with. Read more

How to copy Wordpress theme customisations to a child theme
Mon 23 May 2016
I've been working with Wordpress a little lately. I learnt that you're supposed to create a child theme in order to make modifications to it, but I'd already modified the theme settings (colours, etc.) using the Wordpress 'Customise' tool and couldn't see how to copy these settings to the child theme. Read more

How to defeat naive image steganography
Wed 27 April 2016
As a teenager, I wrote a C program to do image steganography. It hid the secret image in the least significant bits of the cover image. I also made a PHP web interface to it, which now sees about 3,000 users per month. So I've made a better version, it gives previews of the input images, doesn't upload the images to my server (privacy, yo), and is faster. Read more

How (and why) to make your software faster
Fri 15 April 2016
Have you ever been bothered by how slowly your webapp loads, but never profiled it? Much like test-driven development and A/B tests, performance profiling almost always throws up surprises and big wins, and yet most people never bother to do it. If you have anything that runs too slowly, you should profile it today, you will find improvements to make. Read more

Logrotate race condition with copytruncate
Thu 11 June 2015
The logrotate tool has a mode called copytruncate which copies the log file and truncates the original, rather than renaming the original, so that the daemon doesn't need to reopen the log file. Read more

How to close a running process's socket
Thu 9 April 2015
I had a problem this morning of a process that was stuck waiting for an HTTP fetch to complete, and had been stuck for 8 hours. Obviously the fetch had not been successful, and additionally some sort of timeout had broken, but I wanted the process to continue executing for the time being. What to do? Read more

West Country Place Name Generator
Fri 18 July 2014
I've recently written a West Country Place Name Generator. Read more

Yurt Lush Live Tracking
Sun 29 June 2014
In about 3 weeks' time I'm setting off on the Mongol Rally as one half of team Yurt Lush. Read more