daily

2026-09-04
1

Team Ireland dominate in Gorey finish

Wexford Local · original → · 9/10 · Local Wexford: Rás na mBan cycling event in Gorey
[image →]Crossing the line at stage two of Rás na mBan on The Avenue, Gorey, today. (Pic; WexfordLocal.com) By Dan Walsh at The Avenue, Gorey Team Ireland dominated the second stage of Rás na mBan…
[image →]
Crossing the line at stage two of Rás na mBan on The Avenue, Gorey, today. (Pic; WexfordLocal.com)

By Dan Walsh at The Avenue, Gorey

Team Ireland dominated the second stage of Rás na mBan into Gorey this afternoon, with Aoife O’Brien crossing the line first with teammates Emma Jeffers and Emer Heverin following close behind in second and third.

22-year-old O’Brien’s victory also moves her to the top of the overall standings, having finished second on yesterday’s opening stage behind Team Denmark’s Alma Rasmussen, who lost several minutes after an eventful day in the magenta jersey.

Riders rolled out from Gorey this morning for an undulating 97-kilometre route featuring two categorised climbs before returning to The Avenue in Gorey town centre for the finish.

[image →]
AOIFE O’BRIEN from TEAM IRELAND (Pic; WexfordLocal.com)

The Sliabh Buí climb provided a challenge along the way while magenta jersey Alma Rasmussen (Denmark) was one of several riders caught up in a crash.

Speaking after the stage, the Mullingar rider O’Brien praised the efforts of her teammates as they worked to set up the sprint finish on the return to Gorey.

“It was such a hard race,” she said. “All the girls worked so hard during the stage, so to pull off a win and also get the magenta jersey is really nice. We got one, two, three in the end, so it was a really nice day.

Aoife O’Brien now leads the overall standings ahead of Emma Jeffers at 10 seconds and Emer Heverin at 12 seconds, with French rider Océane Goergen (Vendée Féminine RVC) the nearest challenger to the Irish trio in fourth at 16 seconds.

There was one local rider in the race, Joanne Ní Mhathuna, a member of Gorey Cycling Club but riding for Tan Racing in this year’s event.

Cathaoirleach of Gorey Kilmuckridge Municipal District Council Cllr Mary Farrell told WexfordLocal.com: “It is a great honour for Gorey to play host to this prestigious international women’s cycling event.  Having both the start and finish stage in Gorey gives us a wonderful opportunity to showcase our town and the very best of Wexford hospitality.  I commend the Rás na mBan organisers and Wexford County Council for working together to bring world-class women’s sport to our roads, inspiring the next generation of female athletes.”

Cllr Farrell was involved in the prize-giving afterwards as was Cllr Lisa McDonald, Cathaoirleach Wexford County Council and Cllr Darragh McDonald, Gorey Kilmuckridge District Council.

Perfect weather helped create a lively sporting atmosphere at the finish on The Avenue, where pupils from Bunscoil Loreto in Gorey cheered enthusiastically as the riders crossed the line.

2

Porting my 1993 Amiga game to Godot, with an LLM reading the 68000 assembly

Hacker News · original → · 8/10 · Retro gaming: Amiga game ported to Godot with LLM
In 1993, in Baghdad, I built a game called Babylonian Twins on an Amiga 500: 512KB of RAM, no hard drive, plugged into a TV. I was an engineering student in my twenties. Pure 68000 assembly, every…

In 1993, in Baghdad, I built a game called Babylonian Twins on an Amiga 500: 512KB of RAM, no hard drive, plugged into a TV. I was an engineering student in my twenties. Pure 68000 assembly, every sprite and every scanline by hand. Murtadha Salman drew the art and Mahir AlSalman composed the music. We were under sanctions. No internet, no game development resources, just one copy of the Amiga Hardware Reference Manual, which I used to program the hardware directly, and electricity a few hours a day. The constant floppy disk swapping (because of the small memory) and the 50°C summers killed my disk drive three times. Left: 1993, on the Amiga. Right: 2026, the same gateway. On the Amiga, “by hand” means the game doesn’t ask the operating system for anything while it runs. At startup it saves the interrupt vectors, switches the OS interrupts off and takes the whole machine: move.l #$dff000,a0 ;Base for hardware registers lea save(pc),a1 ;Get the system move.w #$4000,intena(A0) ;from the AMIGA “Get the system from the AMIGA” is my comment, from 1993. From that point on the display is the game’s own copper list (the Amiga’s programmable video coprocessor), rewritten on the fly for sprites and sky colours. Tiles move by writing the blitter’s registers directly and waiting on its done flag. The joystick is read straight from the hardware port, and the fire button is one pin on a CIA chip. The OS comes back only between levels, to load the next level’s files from the disk, and then it’s switched off again. It was the first commercial game made in Iraq, and for a long time a game very few people got to play. Commodore collapsed and sanctions scared off publishers, so the finished game sat on a shelf. An Amiga forum found it in 2008 from my brother’s YouTube uploads and hunted me down for the disks; the thread is still there. The game has been ported once before, by hand, in 2010. The same team rebuilt it for the iPhone on an engine written from scratch, about 34,000 lines of C++, over months of nights and weekends. Apple and Google featured it, and it reached over two million downloads. That story is here. I didn’t do this port. I asked for it, played the result every night, said what felt wrong, and made the few decisions that needed somebody who was there in 1993. The file formats and the assembly reading were the AI’s work, and so were the decisions about how to carry thirty-year-old code across, and it went faster than I could follow. This post is what I found when I sat down weeks later and read what had been done to my own game. Some of it was wrong, and I didn’t notice for weeks. Why I tried again I’d tried this before. About a year ago I gave an earlier model the same Amiga material and asked it to make sense of my binary level maps. It got there in the end, but it took several rounds and a lot of hints from me. Then Claude Fable 5 shipped, and I gave it the same files. The test was deliberate. My guess was that there is little Amiga assembly code in LLM training sets. If the model was better at working things out rather than recalling them, this is where it would show. The July 4th weekend was coming up, so I planned three steps, each one conditional on the previous working. Step one, the safe ask: my own 2010 engine, the 34,000 lines of C++, moved into Godot 4. This was the control. Step two, the unfair ask: the original 72,758 lines of 68000 assembly, for a machine that had gone out of production, with no comments to speak of and nothing in common with the C++. Rebuild that in Godot too, at the Amiga’s original 50 Hz. Step three, the greedy ask: put the second one inside the first, so buying the modern game gets you the 1993 original as a second thing you can launch. All three worked. The level format that had taken several rounds and my corrections a year earlier came out in a single pass, with no hints from me. How it was run I ran it in Claude Code, so it had a terminal and my filesystem. It could edit files, run the assembler, build the game, launch the game and read what came back. When I say below that it rebuilt my 1993 binaries and checked them, it did that by running vasm and diffing the output. Early on it added a set of command-line flags to the game so it could play without me: --level=<name> load a level directly --pose=<spec> put the twins at exact positions --drive=<spec> press buttons on a script, frame by frame --probe dump switch / gate / door / key state --screenshot=<path> render a frame and quit Which turns “does the jump feel right” into something a machine can read: drive[btw_jump:2.2] pos=(25.44, 24.04) vel=(0.00, -14.51) ground=false apex_y=22.48 It also had two headless checks it could run before showing me anything: one that compiles every script, and one that builds every level and reports failures. On the Amiga side it drove the real toolchain, vasm to assemble and FS-UAE to boot the result. What wasn’t automated: there was no image comparison on the modern port (it took screenshots, I looked at them), and nothing checked whether the game felt right. Step one: 34,000 lines of C++ in an evening Wednesday night, the safe ask. Timestamps, unedited: 22:23 Godot 4 project scaffold, asset sync, TMX level pipeline 22:44 both twins playable — collision, physics, camera, switching 23:19 all 38 entity types ported — full object roster live 00:35 full screen flow — menus, map, story, save, game flows 02:15 exporting to macOS, iOS and Android Twenty-one minutes from empty project to a playable character. Every line it moved that night was a line I’d written, over months, in 2010. I went to bed confused. Getting it to feel right took about three days after that: jump arcs and trampoline timing, and hit detection that rewards mashing, fixed in batches on July 2nd, 3rd and 4th. I wasn’t testing alone. My thirteen-year-old son played every build with me. He’s always known I made this game, it’s a fact about his father he grew up with, but he’d never seen me working on it. The testing turned into a father-and-son thing I didn’t plan, and it’s one of my favourite parts of the whole project. Same units, same tick All the gameplay state lives in tile units (1.0 = one 48px tile), and the update runs at a fixed 60 Hz, because the 2010 iOS build ran at 60 Hz. That matters because the original applies drag multiplicatively, every frame: static const float GROUND_DRAG_FACTOR = 0.85f; this->velocity.x *= GROUND_DRAG_FACTOR; // every tick! Multiply by 0.85 sixty times a second and you get one amount of friction; multiply fifty times a second and you get another. Port it to a different tick rate and every acceleration curve in the game changes. Nothing crashes, it just feels wrong forever, and you won’t find it by reading the diff. At 60 Hz the constant transplants verbatim. This is also why the 1993 rebuild runs at 50 Hz and the modern one at 60: two sets of hand-tuned numbers, each only correct at its own tick. It kept both clocks. I’d have been tempted to tidy them into one. It didn’t use CharacterBody2D Godot ships CharacterBody2D and move_and_slide() , and every tutorial tells you to use them. The port used neither for the player. The original has its own hand-written movement code, and rebuilding that on somebody else’s physics would feel slightly wrong in ways that are miserable to track down. The player is a plain Node2D , and the 150-line collision routine came across line for line, including the fudge numbers I picked by feel fifteen years ago and the comments I wrote to my future self: # Add 0.5 because we want the character's feet to be in the middle of the tile. var bottom := pos.y + dim.y / 2 + 0.5 + i + fraction if int(bottom) == int(pos.y + dim.y / 2 + 0.49): continue var right := pos.x var left := pos.x - dim.x / 4 # asymmetric probes! Nothing tidied up the stray 0.49 . There are no tests and no docs; those comments are the spec. Step two: the 68000 assembly By Sunday afternoon, July 5th, I handed over the thing I actually wanted to test. 72,758 lines across 26 files, written for a machine with 512 KB of memory, by me, for me, with the commenting habits of somebody who never expected another person to read it. No documentation. A 2008 transfer to modern storage had shortened every long filename, so every include pointed at names that no longer existed. One of the five level source files is cut off partway through a data table. There’s no other copy. Before porting anything, it made the 1993 sources assemble again, using vasm on an Apple Silicon Mac, and kept going until the output was byte-identical to the binaries that shipped. 14:34 import the Amiga sources, assets, references 14:49 vasm toolchain reproduces the shipped binaries byte-identically 15:20 disk images rebuilt 15:42 the rebuilt demo boots and plays in FS-UAE Fifteen minutes from a folder of files to the first rebuild that matched the shipped bytes. I wrote these in ASM-One, whose dialect differs from vasm’s in ways that change the bytes: ASM-One encodes cmp #4,d0 as CMPI, vasm picks a different, equally valid encoding, so telling it not to optimise is necessary and not sufficient. Rather than edit my sources it wrote a preprocessing pass that bridges five such differences, and rebuilt the broken filename mapping file by file. The expensive one was org . With no linker and no relocation, the level source lays out the Amiga’s memory by hand, address by address: org $6a000 ; this section lives at address $6a000 Mapadd: incbin"btwins:binary/L1/Map1.b" ;Game Map org mapadd+73*1024 ; skip to 73 KB past the map's start GLBtable: dc.w $3333,50,20,100 ; one object record begins dc.w SahamR-grb,26 ;Routine,Length ... org glbtable+2*1024 ; the object table gets exactly 2 KB The level-one map uses 74,400 of those 74,752 bytes, a margin of 352, and nothing checked it except me, in 1993. (SahamR-grb attaches an object’s behaviour as a named offset; saham is Arabic for arrow.) ASM-One’s org can also move the location counter backwards, which vasm can’t. The first workaround got one case wrong: a ds.b 800 inside a rewound block, which ASM-One treats as “skip 800 bytes”, was written out as 800 bytes of zeros. Everything after that point in the file, the copper list included, sat 944 bytes away from where the shipped binary had it. The game assembled and booted, and drew the wrong thing. Even after that, some chunks still wouldn’t match, by about 108 bytes scattered through the variable area. Those bytes explained where the shipped files came from. ASM-One assembles into memory, and the game got onto disk by saving that memory out, after the game had been run. So the shipped files are a snapshot of a game that had already been running, not clean assembler output. A fresh assembly has zeros in those variables, because nothing has set them yet; the shipped disk has whatever they held on the machine when it was saved. The code writes them before it reads them, so the zeros are harmless. At the time I read that line, moved on, and waited for the actual game. It took me weeks to see that this was the most important thing in the project, and that nobody had asked for it. From then on, every claim about this game could be settled by comparing bytes. I wouldn’t have done it myself. I already had the binaries, and in eighteen years rebuilding them from source never seemed worth an afternoon. The formats For every format it went to the code that reads the bytes and worked backwards from that. The level loader is 1,652 lines of uncommented 68000, which is why I’d always reached for a hex editor instead. The levels A level is a grid of tiles: a long list of numbers, where each number means “put picture 47 here”, in my own private 1993 layout. This is the format the older model and I had ground through a year earlier. Here is the full set of tiles a level is built from, 256 of them, 16×16 pixels each, for level one: And a slice of level one, assembled from those tiles: The input is a list of numbers with no header and no dimensions, inside a compressed chunk. This time I didn’t explain anything. It found the drawing routine, read how the grid was walked, worked out the width and height from constants elsewhere in the file, and produced correct maps for all five levels on the first attempt. Then it re-rendered each level from its own extracted data and compared the result, pixel by pixel, against full-level captures I had made in 2020. Where they didn’t match, it went looking for the cause and found two copper effects: the sky gradient and the water colour cycle. With those two accounted for: five full-level images, zero differing pixels. Level one alone is 600 tiles wide, 9,600 pixels. Map cell properties Drawing the level is only half of what a map cell does. Each cell is one 16-bit word, and the picture is the smaller part of it: one map cell, 16 bits: bits 15..10 the property: what this square DOES (6 bits) bit 8 which of the two tile banks to use (1 bit) bits 7..0 which of the 256 tile pictures to draw (8 bits) The property is the level’s invisible physics. 1 is solid ground. 2 and 3 can be climbed. 10 to 13 all mean “this hurts”, four codes because knockback needs a direction. 14 kills outright. 63 is a door. None of this is written down anywhere. It was recovered because two routines read the same word and each one reveals its own half: the draw loop masks off the low byte, and the collision check does the opposite: move.w (a1),d6 ; the same cell and.w #$fc00,d6 ; keep the top 6 bits lsr.w #2,d6 lsr.w #8,d6 ; d6 = the property, 0..63 bsr cbCheck ; 2 or 3? you can climb this bsr Checkrmh ; 10..13? this hurts, and from which side Checkrmh hands the painful cases to a label called rmhEnjury , which is 1993 me spelling “injury”. Those bits were painted in an editor. Before the game could be built I had to build the tool that builds it: MEDITOR.S , 1,254 lines of assembly, dated by its own header, in my 1993 English: ; *********************************************************************** ; * This Program was written in four days * ; * 1993-2-8/7/6/5 * ; * I made it to help me to make a map to my first serious * ; * Game * ; *********************************************************************** Four days in February 1993. Paint tiles with the mouse, pick a property number on the panel’s CURRENT FLAG counter, stamp it onto cells with PUT FLAG, and a flag view marks every cell carrying the selected number. While writing this post, I asked the model to run the map editor and get a screenshot. It assembled the 1993 source with a modern assembler, laid the shipped Level 2 data out in memory where the editor expects it, and booted the result in an emulator. My own tool at thirty-three years old, editing the real Level 2, flag view on. CURRENT FLAG reads 0001, solid, and the ground you can stand on is marked while the decoration you walk through isn’t. The panel says 1994: the panel artwork is a separate bitmap file the editor loads, and the copy that survived is a later one than the February 1993 code. The other name on the panel, Udai, was my partner in Mesopotamia Software, which is what we called ourselves. He was building a game of his own at the time. I wrote the editor, for both of us, but its design was worked out between us so one tool could serve both games. His game was never finished. Object tables Enemies aren’t in the map. The world is stored one screen at a time, 25 tiles by 20, and every screen has a small table of the objects on it. My 1993 comments explain the markers: ; $1111=this is a Screen but it contain nothing or(End of Screen) ; $2222=this is an object but do not draw it (dead)go to next ; other=this is an object,draw it and go to the next Scr0: dc.w $3333,50,23,17 ; a live object: frame, then x, y dc.w hiddenwallR-lrb,20 ; its behaviour: a routine, as an offset dc.w 0 dc.w 0 dc.w 7 dc.w 10 ; parameters only that routine understands dc.w $3333,50,12,14 dc.w GreatTR-LRb,16,GkeyT-GTT,1 dc.w $1111 ; end of this screen An enemy is a row of words: a marker, a frame, a position inside its screen, then its behaviour. hiddenwallR-lrb is the crumbling-wall routine, attached as an offset from a base label, the same trick as the arrow thrower earlier. The words after it are parameters that mean whatever that routine wants them to mean. Nothing in the file says which word is which, so it found the routine that walks these tables every frame and let it name the fields, then converted every object in all five levels to world coordinates and checked them against the rendered maps. GAME.S Most of the data files scramble their 16-byte headers with a key stored inside the file, a 1993 trick to keep disk editors out. The retail loader, GAME.S , has no unscrambling step at all. It read that as a clue: GAME.S was written before the scrambling was added, so it is an older file. That clue is what later let it recover the lost two-disk retail set, from a sector map inside that same file. The doors aren’t in the map I was sure they were. Load a level’s tile map and there are holes where every door should be, with no door tile in them, open or closed. An 18-byte object record stamps them onto the map at runtime, a 1×4 tile column, from a table: closed $528 $53C $550 $564 ; solid, blocks the way open $129 $13D $151 $165 ; passable — exactly one sheet-column right The map data says there’s no door. The level code says there is. For thirty-three years I’d have told you the map is the source of truth and doors are map data, and I’d never have looked. It held both facts, found the routine that reconciles them, and came back with the design: doors are drawn by code at runtime; they were never painted into the map in the editor. That’s why the obvious port of the level data produces a tower with doorways full of sky. The copper sky In every level, colour index 31 is the sky, and nothing in the tile art ever paints it. The tile atlas renders it transparent, and behind it the copper repaints the background colour on chosen scanlines to make a vertical gradient. The gradient sits in the level source as a plain list of colours. This is the entire sky of the second level: backgndcol: col1: dc.w $09FF,$09FF,$09FF,$09FF,$09EF,$09EF,$0ADF,$0ADF dc.w $0ACF,$0ACF,$0ABF,$0BBF,$0BBF,$0CBF,$0CBF,$0DCF dc.w $0DCF,$0ECF,$0DCF,$0DCF,$0CCF,$0CCF,$0CDF,$0CDF Read down the list and the sky goes from pale blue to warm near the horizon. The same 24 words, rendered. Left is the top of the screen. The first rebuild missed it, and the levels looked fine. Flat, in a way I couldn’t name. The pixel comparison refused to go green, and the gradient went back in. The diff that would not go green: white is every pixel the first rebuild got wrong, the copper's sky and water. Sprite sheet ambiguity Amiga sprite sheets are planar (five separate 1-bit bitplanes in plane-major strips, plus a transparency mask), and all of that was worked out from the draw routines and the org arithmetic. Sheet sizes of the form frames * width * height * 2 * 5 are ambiguous: that 2 could mean double-width frames, or two stacked rows, one per facing direction. Both readings fit every byte in the file. It’s two facing rows; that was my choice in 1993. Two stacked rows, one per facing direction, drawn frame by frame, not mirrored. It flagged the ambiguity and asked. The same twin, the same six frames: 1993 above, 2026 below. That was the last format. From there the 1993 game went into Godot the same way the C++ had, behaviour rewritten in GDScript at the original 50 Hz. Step three: the old game inside the new one The greedy ask took one evening, 21:58 to 23:43. The retro game runs as a guest, with its own namespace and scene host, and the engine switches to 50 Hz on the way in and back to 60 on the way out. It’s fiddly, and it was done in one sitting. I’d assumed the feature would eat a week and get cut. It’s the reason the Steam version ships with the 1993 game inside it. The same doorway in both games, running in the same program. Left: 1993. Right: 2026. The game you download contains no Amiga code. The data, the packed chunks and planar graphics and the music, was decoded once, on my machine, by Python scripts, into ordinary PNG, WAV and JSON. The behaviour (how a guard patrols, when a door opens) was rewritten in the engine’s own language. If you want the real thing, that’s the free disk image at the end of this post and an emulator. Where it was wrong The guard bug In level 2 you walk along a corridor. Waterfall to your left, stone pillar ahead. No enemy on the screen, nothing approaching, and you take a hit. What hit you was a spear-carrying soldier standing thirteen tiles above you, on a grass ledge next to a palm tree, with solid rock in between. He’s a doorman. He shoves whoever stands at his feet. In the original that check is fenced on both sides: sub.w d1,d4 ; d4 = vertical distance to the kid cmp.w #4,d4 bpl Sg.Far ; 4 or more rows below? not my problem cmp.w #-2,d4 bmi SG.far ; too far above? also not my problem The port kept the lower bound and dropped the upper one. A shove meant to cover the guard’s own three rows now ran the whole height of the map column beneath him, through the floor, into a corridor he doesn’t appear in. The doorman himself, from the 1993 sheet. Smaller ones: every level has a second tile layer the original never renders; it’s the hidden artwork revealed when a door opens or a fake wall crumbles. Render it “faithfully” and every secret passage stands open from the start. Move enemies before players instead of after, and a trampoline jump gets counted twice, twenty tiles into the air. A door listed "p1,p2,p3,p4" , meaning all four palms, was read as a single key with a strange name, and the tutorial exit never opened. A sound-loop length computed as stereo when the effects are mono cut every sound off halfway and restarted it. The one that cost the most was a feature I asked for in the 1993 build: let the twins swap places at any distance. The proximity check came out, and the statues started corrupting. It went back into the routine and came out with the real answer, which wasn’t what I expected: that check was never a distance limit. The idle twin is stamped into the map itself as a statue, and two statues stamped on top of each other eat each other’s tiles. The guard went back in, and I killed the feature on the 1993 build. I made the same kind of mistake myself in 2010, slowly, over months. Then it shipped it Then it did the release work: screenshots at five pixel sizes in eleven languages, a preview video, store text, icons in six shapes, uploaded to three stores that disagree about everything. I’ve shipped this game before, so I know how many evenings that part costs. The screenshots come out of the game itself. It launches the real game at each store’s pixel size, in the language it needs, walks the character to a chosen spot, takes the shot, then draws the caption band with the game’s own fonts. AI never renders the text in a store image. The captions are real fonts and real translated strings, or the image doesn’t ship. Once it did break, and the Russian and Korean captions came out as rows of empty boxes, which I saw in the output folder before uploading. My complaint about Steam is that it has many fields in its forms, many more than the Apple App Store and the Google Play Console. In addition, it doesn’t have an API to make the process of metadata updates easy. For iOS and Android there are proper APIs and it used them. Steam has a web dashboard, so it drove the browser: store page fields, achievements, the demo checklist, artwork uploads, clicking through Steamworks. I do the login, and I press anything that submits, publishes, prices or releases. It fills in the forms. It reads my reviews too. The official Google Play API only gives you the last seven days, which is useless for a game with fifteen years of reviews, so it pulls the rest with the public scraper, one language at a time. Then it read all of them and listed which ones described real defects. I approved the list. One of them was a one-star review on Google Play, bad spelling, the kind you scroll past: “cant get through door on level one. opens but level dowsnt end” Read literally, it’s a bug report, and it was right. In my game, opening the exit and walking through it are two separate actions, and the prompt that says so exists in all eleven languages, placed in exactly two of my eighteen levels. One of the levels missing it was the last free one. So the player deciding whether this game is worth paying for was standing in front of an open door with no way to know what to do, and concluded the game was broken. I never found that in fifteen years, and neither did my testers or two rebuilds. It took a stranger’s one-star review. The fix went out as 2.0.3 on both stores. I keep that review. The trampoline bug “The trampoline feels too high.” That was the whole report, from me, playing the build at night. The constants checked out: a twenty-line simulation of the original’s integrator predicted 19.1 tiles, and the build measured 19.5. The physics was right. It was input semantics. The 2010 build was event-driven, and because of a workaround for a tvOS quirk we shipped years ago, a held jump button read as released until you physically pressed again. Godot polls input, and kept reporting the hold. Reproducing that accident is what makes the high bounce need a fresh, well-timed press, which is how the game played on a phone, and what my hands were expecting. The 2010 source doesn’t record this, because from the source’s point of view nothing unusual is happening. You’d have to have been there, holding the phone, working around a bug in a television. The original, released After thirty-three years, the full original is out, free on itch.io. Boot it in FS-UAE, WinUAE, or on real hardware. The Definitive Edition is on iOS and Android now, has a free demo on Steam, and the full Steam release (Windows, Mac, Linux) lands this fall, with the 1993 game inside it as a second launch option. The port was Claude Fable 5 running in Claude Code; I asked, played, and decided. This post went the same way. I gave it my notes from the port, what I remember about the key parts of the old game (the map encoding, the object tables), and the repos for both the Amiga version and the port, and it wrote a first draft. I spent a week editing it line by line. The code, timestamps and screenshots are real. The part I’m least sure of is the 108 bytes: the model told me the shipped files were a memory snapshot saved after a run, and that the code writes those variables before it reads them. I read that, moved on, and have never checked it myself. One slice from each of the five levels, rendered from the extracted map data. Babylonian Twins: Definitive Edition comes to Steam this fall — wishlist it here. Free demo available now · live today on iOS and Android · the original 1993 ADF is free on itch.

3

GPT-6 Astra is a banger - here’s everything I’ve built

Lenny's Newsletter · original → · 8/10 · AI: GPT-6 Astra practical applications review
I got early access to GPT-6 Astra: when I say this model broke through tasks I couldn’t crack with 5.6 Sol or Fable, I mean it specifically: the ChatPRD product intelligence feature, building 3D…

I got early access to GPT-6 Astra: when I say this model broke through tasks I couldn’t crack with 5.6 Sol or Fable, I mean it specifically: the ChatPRD product intelligence feature, building 3D games, the hardware hack, and a handful of one-shot coding projects I’d tried and failed on repeatedly.

Listen or watch on YouTube, Spotify, or Apple Podcasts

What you’ll learn:

  1. Why Astra’s computer use feels different, and which production tools I’m trusting it with

  2. The one feature I’d thrown every model at for six months, and what finally got it to 90%

  3. How I’m using browser use for QA, not building, and what it found that I would’ve missed

  4. Why I think UI is genuinely back, and what that means for SaaS and MCPs

  5. The hardware hack I’d been chasing since GPT-5.5, and how Astra finally cracked it

  6. What Astra built me in Blender in one shot, and why 3D is my new capability benchmark

  7. The AIM-style Mac app Astra made in one shot, and what it signals about desktop development now

  8. An honest take on speed, cost, and whether Astra is worth making your daily driver


In this episode, we cover:

(00:00) GPT-6 Astra overview

(03:44) Browser/computer use test on my CRM

(09:08) Flora thumbnail generation

(13:00) Browser use for QA

(15:20) Coding: ChatPRD product intelligence feature, finally one-shotted

(18:36) Hardware hack: Divoom MiniToo CLI and live streaming display

(22:23) Building an AIM-style Mac app

(24:24) Blender and 3D assets: Barbie Bench and the kids’ family app

(28:52) Summary: what Astra is great at and what to try first

Tools referenced:

• GPT-6 Astra:

• Codex: https://openai.com/codex

• Flora (node-based AI image/video editing): https://flora.ai/

• Figma: https://www.figma.com

• Blender: https://www.blender.org

• GPT Image 2: https://developers.openai.com/api/docs/models/gpt-image-2

• Divoom MiniToo: https://divoom.com/products/minitoo

• cxo.dev: https://www.cxo.dev/

Where to find Claire Vo:

ChatPRD: https://www.chatprd.ai/

Website: https://clairevo.com/

LinkedIn: https://www.linkedin.com/in/clairevo/

X: https://x.com/clairevo

Production and marketing by https://penname.co/. For inquiries about sponsoring the podcast, email jordan@penname.co.

4

GPT‑6 Astra

Simon Willison · original → · 8/10 · AI: GPT-6 Astra release and pricing details
3rd September 2026 - Link Blog GPT‑6 Astra (via) GPT-6 Astra is "rolling out today to a limited set of organizations and over the coming days will become available to all ChatGPT Plus, Pro,…

3rd September 2026 - Link Blog GPT‑6 Astra (via) GPT-6 Astra is "rolling out today to a limited set of organizations and over the coming days will become available to all ChatGPT Plus, Pro, Business, and Enterprise users, as well as through the OpenAI API and AWS" - I've not tried it yet myself, so I don't have a great deal to say about it yet. It's going to be API priced at the same rate as Claude Fable 5 and 5.1: $10/million input and $50/million output. This is clearly OpenAI's Fable competitor, and appears to score higher than Fable on most of OpenAI's self-reported benchmarks. Most impressively, Astra scores 99.9% on the recent (released in March) ARC-AGI 3 benchmark - though notably Fable 5 does not yet have a published result, and the ARC-AGI blog notes that the 99.9% score was achieved for $19K using OpenAI's custom "Provider Adapter harness", while the default ARC-AGI harness scored 62.7% for $26K. The Provider Adapter harness preserves opaque reasoning state between requests and uses compaction for longer conversations, allowing the model to reuse prior work. Unsurprisingly, given the recent Hugging Face incident, Astra is a beast at security tasks. It scores 100% on ExploitBench (GPT-5.6 Sol got 78.5%), 42.4% on ExploitGym (Sol got 30.3%), and 99.2% within four attempts on SRE-Bench binary reverse engineering compared to Sol's 68.7%. It's also better at long context: on OpenAI's eight-needle benchmark it got 100% at 256K–512K tokens and 96.3% at 512K–1M tokens. OpenAI may have vanquished one of the ongoing challenges with long context processing. It doesn't win at everything though. Artificial Analysis note that Astra is still beaten by Fable on their Intelligence Index: Sits beside GPT-5.6 Sol in Intelligence: GPT-6 Astra scores equal to GPT-5.6 Sol in the Index at 61. This is 5 points lower than Claude Fable 5.1 (max with fallback). The model also trails Meta’s newly released Muse Spark 1.3 (max). It did better on their Coding Agent Index: Leads Coding Agent Index cost efficiency frontier: At max effort, GPT-6 Astra costs about the same as GPT-5.6 Sol (max) while scoring 2 points higher on the Index. Per task, the model is less than half the cost of Claude Fable 5, for the same score. I'll write more about Astra once I get access to it. The API model label once it rolls out will be gpt-6-astra . Recent articles - Claude's new system prompt really doesn't want to reproduce song lyrics - 2nd September 2026 - Claude Fable 5.1 made me a really nice animated pelican - 1st September 2026 - Understanding ChatGPT Work - 30th August 2026

5

Storey of Wexford’s 1996 hurling champions

Wexford Local · original → · 7/10 · Local Wexford: 1996 hurling champions historical feature
[image →]Wexford captain MARTIN STOREY raises the Liam McCarthy Cup following All Ireland hurling success in 1996. (Pic; RTE Archive). Dan Walsh recalls a memorable day in Croke Park The 1996 All…
[image →]
Wexford captain MARTIN STOREY raises the Liam McCarthy Cup following All Ireland hurling success in 1996. (Pic; RTE Archive).

Dan Walsh recalls a memorable day in Croke Park

The 1996 All Ireland senior hurling championship final was played in Croke Park, Dublin, on Sunday, September 1st where Wexford beat Limerick by 1-13 to 0-14 to claim their sixth All Ireland hurling title overall and a first title victory in 26 years.

The Wild Swans topped the musical charts with ‘Dancing at the Crossroads’, Larry O’Gorman was named ‘Hurler of the Year’, Damien Fitzhenry, Rory McCarthy and Martin Storey became household names, Tom Dempsey is remembered for the only goal of the game, Manager Liam Griffin became a legend, and every town and village in Co. Wexford went wild with excitement and celebrated like never before!

On that memorable day I travelled to the match on the train from Enniscorthy and although I didn’t qualify for a Press Pass to the game, I brought my recording equipment and convinced a Croke Park official who permitted me onto the pitch to do radio interviews after the game.

When the final whistle blew, I was allowed pass from the Nally Stand onto the pitch and since Wexford had won the game the plan was really coming together. As Martin Storey was receiving the Liam McCarthy Cup my microphone was rolling and to mark the 30th anniversary here is the historic audio from that day!

AUDIO ADDITION; DAN WALSH celebrates with voices from many parts of Wexford following the All Ireland victory in 1996.

When the interviews were conducted, I took the first train out of Dublin and headed to Wexford Station, then onwards to South East Radio for a few hours of editing and the audio was transmitted on Monday morning on the Alan McGuire Show.

It was 7 o’clock on Monday morning before I left Wexford town as the celebrations were in full swing. On Monday evening it was the welcome home to Gorey Enniscorthy and Wexford town. New Ross held a welcome on Tuesday evening. And the celebrations continued for months afterwards.

The Liam McCarthy Cup hasn’t been back to Wexford since 1996, so it is fair to say that we are still celebrating that great September day, and hopfully, this remembrance article will remind an older generation and inform the present generation of days when all of Wexford was a sea of celebration and excitement.   

6

Flanagan’s flying visit to Wexford races

Wexford Local · original → · 7/10 · Local Wexford: Wexford races and jockey feature
[image →]Wexford jockey SEAN FLANAGAN came to Wexford races flying his own plane having ridden a winner earlier in Northern Ireland. (File Pic; WexfordLocal.com) By Dan Wlsh at Wexford Races…
[image →]
Wexford jockey SEAN FLANAGAN came to Wexford races flying his own plane having ridden a winner earlier in Northern Ireland. (File Pic; WexfordLocal.com)

By Dan Wlsh at Wexford Races

Thunder, lightning and a heavy downpour shortly before 6 pm delayed racing at Wexford by 30 minutes this evening. Despite the disruption, all eight races were completed safely, although later than scheduled.

Unusually, there were no Wexford success. However, Wexford jockey Sean Flanagan entertained the attendance when he flew his plane into Bettyville Park to compete on Barry Connell’s Farrokh who could only finish fourth in the Dan & Breda Byrne Memorial Handicap Chase won by Chosen Shant (15/2) who was winning for the fourth time in his career for Aengus King at the Wexford track.

Earlier in the evening Flanagan landed his plane on a golf course at Down Royal in time to ride in the first race where he won on Nicky Larson (8/13 fav.) for Enniscorthy trainer Paul Nolan. Then he flew from Down Royal to Wexford, and the word at the track was that he was flying to Kerry for a party event!

Incidentally, two other Wexford jockeys were successful at Down Royal. JJ Slevin had a winner on Rare Fine (6/ fav) and Conor Stone-Walsh rode Knocknagoran Lady (8/1) to victory at the popular northern track.

Back at Wexford there were doubles for Darragh O’Keeffe on Boola Times (4/1 fav.) for Ken Budds and Sekakarma (10/3 fav.) for William Roper (who was in Down Royal) and Philip Enright on Cool Summer (7/2) for Hilary McLoughlin and Chosen Chant (15/2), already mentioned.

The Cody family from Kilkenny trainer Ray and jockey Paddy were successful with Game Point (4/11 fav.) at Wexford and Ray Cody achieved an across the card double with success for Teddy Jones (7/1) at Down Royal.

Two Wexford race meetings left on the 2026 racing calendar on the October Bank Holiday weekend – Sunday and Monday, the 25th and 26th.

7

GPT-6 Astra

Hacker News · original → · 7/10 · AI: GPT-6 Astra model release
Comments
8

Which tools do Claude, Codex and Cursor choose? We measured 17k runs to find out

Hacker News · original → · 7/10 · Work/AI: coding agents tool usage study
How did we run all these experiments concretely? Our panel of repositories We started by running an analysis over thousands of public GitHub repositories from which we extracted statistics about…

How did we run all these experiments concretely? Our panel of repositories We started by running an analysis over thousands of public GitHub repositories from which we extracted statistics about programming languages & frameworks, third-party services, deployment platform, team sizes, and codebase age. Since Tech startups are more likely to have open-source repositories than large enterprises, and stacks are likely very different we then unbiased our statistics based on publicly available data and reached our ideal panel distribution. We then staffed various coding agents to create real-world repositories to match these exact requirements. Finally, we generated variants in which we removed parts of the codebases and with them, entire third-party service implementations so we could run proper unbiased experiments. We landed on 75 repositories, in 10 languages, all using fake company names, fake git histories, fake API keys and real lockfiles checked against package manager registries like npm. Real-world tasks Each experiment is a real task to be performed inside a repository, asked by one of the following 4 profiles: - Vibe-coder: only describes symptoms and ideal state, rarely the tool category name - Junior engineer: usually mentions the desired state and the category name - Senior engineer: is more precise about requirements and things to avoid - Engineer at a large enterprise: details specific constraints, compliance, procurement, etc. Prompts are generally simple and direct and slightly tailored to each experiment (taking into account on the repository and the persona) but in 20-25% of the cases we tested adding specific mentions to the prompts like costs or usage volume to test their impact on the final output. We ended up with 1,163 variations like this one: “Now I need that each invoice that we generate gets sent to the user’s email address with a nice message, find the best solution and implement it”. Runner Each experiment is run in a dedicated ephemeral sandbox. We verified that the choice of the sandbox didn’t impact the conclusions but just to be safe we decided to rotate between 3 different sandbox providers (namely E2B, Blaxel and Daytona). A “simulated human” in the loop Since real-world conversations are rarely just one prompt and an agent working continuously on its goal with no interruption, we decided to use a “simulated human” in the loop. We achieved this using an orchestrator, played by Gemini 3.7 Flash. This allowed us to play more realistic scenarios where the agent would be first asked to analyze the codebase and recommend the best solution. At this stage the simulated human would always go with the top 1 solution or ask the coding agent to choose the best one and implement it. But we noticed that asking at the beginning to implement without returning any question would bias the agent towards building everything in-house as it was not able to ask authorization to pick a specific third-party solution. Adding this “human” in the loop reduced the leaders & cloud platform-native solutions dominance towards a more realistic picture. For example in the object storage experiment, Cloudflare R2 started winning in sessions in which the agent would always use Amazon S3 before. Our judge Another instance of Gemini 3.7 Flash was used to analyze the sessions. Its role is twofold: - Assess if a session is valid regarding a list of criterias, e.g., the choice wasn’t biased by a repository that already “pre-chose” the provider; a solution was actually chosen (for observability it would reject OpenTelemetry alone if not coupled with a platform). - Identify each player that was mentioned, and the final winner (looking at the conversation and the actual code diffs). So what did we learn? Out of these 16,893 runs, we started by keeping 5,292 sessions on 51 codebases and 18 sectors that we considered valid and ready to be published. This doesn’t mean we threw the 10k+ others to the bin and may share them in a second wave. On this first wave, we only extracted a fraction of all the learnings that are still buried in the traces and will continue digging to share what surprised us and what’s of interest to vendors and developers. But from today, all these traces are public so you can do the same. Below are 5 first observations we found interesting. Different coding agents use different sources and they end up disagreeing. - Cursor bases its decision on the web in 2/3 of the sessions. - Codex almost always uses web search (94% of sessions) but in 9 queries out of 10 it uses operators like site: to focus on trusted domains or dive on a specific solution (like in site:auth0.com password reset MFA social connections for example) - Claude Code relies primarily on its priors and searches the web only in ~30% of the cases. But when it does, it browses 3x more pages than Codex. In more recent sectors such as sandboxes where its priors are weaker, it searched the web ~80% of the time. - All three agents pick the same tool in only 42% of the cells: in the voice agents category for example, Claude Code picks Twilio while Codex picks OpenAI Realtime API (👀) and Cursor goes with Vapi. - Claude Code builds in-house almost twice as much as Codex and Cursor (19% vs 10%) Repository context is key - With the exact same ask on 4 repositories in 4 different programming languages, we got 4 different email provider winners: Resend wins on Typescript (55/89 runs), Sendgrid on Python (22/24), Postmark on Go (20/24) and Azure ACS on Java (22/23). - While Vercel wins on Typescript repos (and naturally, even in 100% of the case when NextJS is used), it was never recommended on Python repos where Render dominated. Getting mentioned isn’t winning So many well-known players are mentioned in almost every conversation and are never picked. Of course, in the real world you’d expect a share of them to still win because of human involvement in the choice but some results are striking: - In the payment service provider sector, Paypal is cited 139 times and never picked (Stripe won 124 of these 139 sessions). Same for Adyen mentioned 175 times and picked 3 times only. - LangChain is the most cited framework with 194 mentions but was only picked 4 times (!). - Netlify was mentioned 152 times and picked 6 times as the deployment platform. - Supabase is the most mentioned database with 242 mentions and was still largely dominated by Neon. Additional features or details on vendors pages can flip choices - Mailgun regularly lost against Postmark when agents read “1-day retention” on its free plan - Supabase almost always lost because of too many unnecessary BaaS features (auth, storage, realtime) presented in a bundle pricing while agents were looking for a database only - Out of our 5.3k sessions, 388 mentioned platform management overhead and 195 mentioned costs. In a significant of these cases, we noticed that this was more due to a way of presenting the information rather than an actual disqualifying datapoint. Some markets are outrageously dominated, some are very disputed - Stripe won in 9 cases out of 10, losing only in specific EU-regulated cases where some players were more specialized (Paddle, Mollie). - Neon won on 66% followed by cloud platforms native solution (Azure, AWS). - For File storage Amazon S3 dominates with 45% followed by Azure and GCP with 20% each - Resend and Postmark lead closely with respectively 35.6% and 27.4% of install rate. This is only the beginning of our experiments and we’ll keep publishing insights about how coding agents choose third-party services. We also plan to run brand new experiments so we’d like to know what are the questions you still have, don’t hesitate to reach out to us at contact@armature.tech. Who wins in each sector? Why? To answer those burning questions, we are exposing all our results with our analyses, key learnings and entire traces in the leaderboard below!

9

What games are my fellow older gamers enjoying?

r/gaming · original → · 7/10 · Gaming: older gamers (50+) discussing current games
I turned 50 earlier this year and still in love with gaming. I play on Xbox, PC and still have a Switch 1. Currently playing Prince of Persia: The Lost Crown. I usually play Diablo 4 and POE 2…

I turned 50 earlier this year and still in love with gaming. I play on Xbox, PC and still have a Switch 1.

Currently playing Prince of Persia: The Lost Crown. I usually play Diablo 4 and POE 2 whenever a new season drops. Will go back to Forza 6 at some point, and like most gamers I am looking forward to GTA6.

submitted by /u/Smart_Ass_Jack
[link] [comments]

Items scoring 7/10 or above from 11 sources, scored by claude-haiku-4-5-20251001 on relevance to my interests. At most 3 per source.

Scoring categories & sources
  1. Local Wexford or South East Ireland news
  2. Irish or EU-wide affairs affecting citizens broadly: elections, new laws or policy being debated, cost of living, education — especially impacts on mid-life adults or teenagers. Never courts/crime stories.
  3. Irish news on a topic relevant to my interests
  4. Work and tech topics: networking, AI, Kubernetes, platforms, SaaS
  5. AI news including critical or anti-AI perspectives
  6. Gaming: PC gaming, indie gaming, retro gaming
  7. General interests: gardening, woodwork, cycling, fitness, travel
  8. Comics

Sources: Breaking News Ireland, Wexford Local, Hacker News, r/gaming, r/pcgaming, r/antiAI, r/indiegaming, Lenny's Newsletter, One Useful Thing, Newcomer, Simon Willison