我尝试用BASIC语言编写Vibe编码,结果不太好。
I tried vibe coding in BASIC and it didn't go well

原始链接: https://www.goto10retro.com/p/vibe-coding-in-basic

## 使用雅达利BASIC进行“氛围编码”:一项令人沮丧的实验 作者探索了“氛围编码”——即通过与大型语言模型(如ChatGPT)进行长时间对话来编写代码——但有一个特别之处:使用雅达利BASIC,这是一种简单但具有历史意义的语言。虽然LLM在作为现代代码的文档搜索工具和创意生成器方面表现出色,但实验表明,对于较旧的系统存在显著挑战。 BASIC语言的网络资料有限,语言家族内部存在变体,并且依赖于晦涩的系统调用(如PEEK和POKE),这些都给ChatGPT带来了困难。尽管在编写简单程序方面最初取得了一些成功,但即使是创建一个基本的《太空侵略者》克隆游戏,也需要大量的修正和提示。 ChatGPT经常生成语法错误的程序,无法理解图形命令,并且难以掌握雅达利BASIC的基本概念。这个过程变得非常繁琐,作者最终需要对AI生成的输出进行大量修改。 结论是?虽然LLM在现代语言方面显示出潜力,但使用雅达利BASIC进行“氛围编码”在很大程度上是无效的,需要大量的现有知识来克服AI的局限性。这突显了这种方法的有效性很大程度上取决于语言的普及程度以及LLM可用的训练数据量。

我尝试用BASIC语言进行Vibe编码,结果并不顺利 (goto10retro.com) 13点赞,ibobev 发表于2小时前 | 隐藏 | 过去 | 收藏 | 1条评论 firesteelrain 发表于21分钟前 [–] 一点也不惊讶;BASIC有太多变种了,除非你用大量的代码示例和上下文来训练ChatGPT,否则它能达到的程度有限。试试本地LLM然后训练它。 考虑申请YC 2025秋季批次!申请截止日期为8月4日。 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请YC | 联系我们 搜索:
相关文章

原文

With the rise of LLM systems (or “AI” as they are annoyingly called), the term “vibe coding” is all the rage recently. Vibe coding is when you rely almost entirely on these “AI” system to write your code for you via a series of drawn-out conversations.

Putting on my cranky old man hat, I find most of it rather frustrating. Now I’m not some retro-sycophant who refuses to use modern tools. I’ve been a software professional for over 30 years at this point and I’ve used lots of tools throughout the years. Many that were cool and hip have long since disappeared or fallen out of fashion. I’ve also actually used these AI systems myself to help figure out some code. I find they function really well as a better search engine for documentation and can also serve as a way to “rubber duck” ideas and get some outlines. Any code I get back rarely seems to work as-is, but it often can provide ideas for something I hadn’t considered or perhaps point out something I did not know about.

After all, today’s technology is complex and it is not always easy to find what you need in the documentation.

But how does vibe coding work with something far simpler, such as the simplest programming language of them all: BASIC?

I suspect this might be a little tricker than it first appears. First of all, usage of BASIC largely predates the internet so there is far less BASIC code out there for LLMs to learn from. Many online retro BASIC books and docs are often scanned copies rather than easily digested plain text. Also, BASIC is not a single language, but more of an umbrella term for a family of languages all of which have the same “vibe”, but often very different commands and capabilities, some of which rely heavily on PEEKs and POKEs to really take advantage of their system’s features. And those ancient forms of API calls are poorly documented online.

So this should be an interesting challenge and to make it even slightly trickier, I’m going to use Atari BASIC rather than a much more common Microsoft BASIC variant, such as AppleSoft. Why? Because this is an Atari newsletter and I have plenty of Atari equipment to test things with. Alas, I don’t have any Apple II-era systems.

With that said, I will be using the Atari800MacX emulator because it makes it easy to paste in the generated code.

Now with all that out of the way, which LLM AI system should we try? Considering ChatGPT is the most commonly known and one most are familiar with, that’s I’m using for this experiment, although Anthropic Claude is also great for use with coding.

To do proper vibe coding, I need to refrain from correcting the generated code or even telling the AI what exactly is wrong.

So what should be do first? Let’s start with a typical first BASIC program, the precursor to “Hello World”.

Prompt: Please write me a simple program in Atari BASIC that repeatedly prints “Hello, World” to the screen.

ChatGPT aced this simple test. I have to say, I do love seeing “GOTO 10” like that!

Atari BASIC does not have a built-in way to draw a circle so let’s ask for that:

Prompt: Write me an Atari BASIC program that draws a blue circle in graphics mode 7.

So far, the vibes are flowing. This program ran perfectly, although it only drew a rough, dotted circle.

I asked it for a solid outline instead of a dotted outline and it came back with this code:

10 GRAPHICS 7
20 COLOR 1
30 X=80:Y=48:R=30
40 A=0
50 X1=X+R*COS(A)
60 Y1=Y+R*SIN(A)
70 FOR A=0 TO 6.28 STEP .05
80 X2=X+R*COS(A)
90 Y2=Y+R*SIN(A)
100 DRAWTO X2,Y2
110 X1=X2:Y1=Y2
120 NEXT A
130 GOTO 130

That drew a solid outline using DRAWTO, but it did not set the starting position correctly.

It was able to fix things, however:

This new code draws correctly:

I then asked it to get rid of the blue bar at the bottom and it did that admirably by using GRAPHICS 7+16.

That all went well!

Continuing the graphics theme, let’s take it up a notch. Atari BASIC does have built-in commands for drawing lines and accessing the joystick, which are more than enough to make a simple drawing program.

Prompt: Write an Atari BASIC program that lets you draw on the screen using a joystick. It should use graphics mode 7 and allow you to rotate between colors by pressing the fire button.

The resulting code had several errors:

To use COLOR as a variable name, LET is required. The “;” is not used for comments in any version of BASIC I’ve ever seen.

Prompt: Line 30 shows this error: ERROR- COLOR=1. There are also errors on any lines that use ";" for a comment.

It fixed these errors by changing COLOR to just C and getting rid of most comments:

10 GRAPHICS 7+16
20 X=80:Y=48
30 C=1
40 POKE 77,0
50 REM === MAIN LOOP ===
60 ST=STICK(0)
70 BT=STRIG(0)
80 IF ST=11 THEN Y=Y-1
90 IF ST=7 THEN Y=Y+1
100 IF ST=13 THEN X=X-1
110 IF ST=14 THEN X=X+1
120 IF X<0 THEN X=0
130 IF X>159 THEN X=159
140 IF Y<0 THEN Y=0
150 IF Y>95 THEN Y=95
160 IF BT=0 THEN GOSUB 200
170 COLOR C
180 PLOT X,Y
190 GOTO 60
200 REM === CYCLE COLORS ===
210 C=C+1
220 IF C>3 THEN C=1
230 FOR D=1 TO 20:NEXT D
240 RETURN

That code ran fine, but the joystick directions were wrong. Joystick up draws right; down draws left; left draws up; right draws down.

After telling it about the joystick problem, it fixed it to this:

10 GRAPHICS 7+16
20 X=80:Y=48
30 C=1
40 POKE 77,0
50 REM === MAIN LOOP ===
60 ST=STICK(0)
70 BT=STRIG(0)

80 IF ST=14 OR ST=10 OR ST=6 THEN Y=Y-1  : REM UP
90 IF ST=13 OR ST=9 OR ST=5 THEN Y=Y+1   : REM DOWN
100 IF ST=11 OR ST=10 OR ST=9 THEN X=X-1 : REM LEFT
110 IF ST=7 OR ST=6 OR ST=5 THEN X=X+1   : REM RIGHT

120 IF X<0 THEN X=0
130 IF X>159 THEN X=159
140 IF Y<0 THEN Y=0
150 IF Y>95 THEN Y=95

160 IF BT=0 THEN GOSUB 200

170 COLOR C
180 PLOT X,Y
190 GOTO 60

200 REM === CYCLE COLORS ===
210 C=C+1
220 IF C>3 THEN C=1
230 FOR D=1 TO 20:NEXT D
240 RETURN

The resulting program works fine, although I don’t think line 40 is needed:

How about a simple game? Using sprites (player/missiles) in Atari BASIC requires a machine language subroutine, so that’s probably not realistic. Other types of games use a redefined character set which only require some PEEKs and POKEs. We can ask ChatGTP to make a rudimentary version of Space Invaders this way and that seems worth a try. With the game being so well known, hopefully I don’t need to provide a ton of prompting.

Prompt: Create a simple version of Space Invaders using Atari BASIC. Use a large text graphics mode with a redefined character set for the aliens, spaceship and missiles. The player’s ship should be controlled with the joystick.

It’s first response was rather simple:

10 GOSUB 1000       :REM Setup custom characters
20 GRAPHICS 0
30 POKE 77,0        :REM Disable cursor
40 DIM AL$(5)
50 FOR I=0 TO 4:AL$(I)="A":NEXT I
60 FOR I=0 TO 4:POKE 752+I*2,ASC(AL$(I)):NEXT I

70 SHIPX=20 :MISSILE=0 :MX=0 :MY=0 :C=0
80 FOR I=5 TO 35 STEP 6
90 POSITION I,5 :PRINT "A"; :NEXT I

100 REM === MAIN LOOP ===
110 ST=STICK(0) :BT=STRIG(0)

120 IF ST=11 AND SHIPX>0 THEN SHIPX=SHIPX-1
130 IF ST=7 AND SHIPX<38 THEN SHIPX=SHIPX+1

140 POSITION 0,22 :PRINT "                                        "
150 POSITION SHIPX,22 :PRINT "S";

160 IF MISSILE=0 AND BT=0 THEN MISSILE=1 :MX=SHIPX :MY=21

170 IF MISSILE=1 THEN
180   POSITION MX,MY :PRINT "|";
190   FOR T=1 TO 100:NEXT T
200   POSITION MX,MY :PRINT " ";
210   MY=MY-1
220   IF MY<0 THEN MISSILE=0:GOTO 240
230   POSITION MX,MY :IF PEEK(PEEK(88)+MX+MY*40)=ASC("A") THEN POSITION MX,MY:PRINT " ";:MISSILE=0
240 END IF

250 GOTO 100

1000 REM === CUSTOM CHARACTER SET ===
1010 CHB=57344      :REM RAM for new charset
1020 FOR I=0 TO 1023
1030   POKE CHB+I,PEEK( CHB+I )  :REM Copy original
1040 NEXT I
1050 POKE 756,CHB/2048  :REM Point to new set
1060 RETURN

The MISSILE variable name causes a syntax error, as does the use of “END IF”.

After I pointed out those errors, it came back with this:

10 GRAPHICS 0
20 POKE 77,0        :REM Disable cursor
30 DIM AL$(5)
40 SHIPX=20 :FIRE=0 :MX=0 :MY=0
50 FOR I=5 TO 35 STEP 6
60 POSITION I,5 :PRINT "A"; :NEXT I

100 REM === MAIN LOOP ===
110 ST=STICK(0) :BT=STRIG(0)

120 IF ST=11 AND SHIPX>0 THEN SHIPX=SHIPX-1
130 IF ST=7 AND SHIPX<38 THEN SHIPX=SHIPX+1

140 POSITION 0,22 :PRINT "                                        "
150 POSITION SHIPX,22 :PRINT "S";

160 IF FIRE=0 AND BT=0 THEN FIRE=1 :MX=SHIPX :MY=21

170 IF FIRE=1 THEN GOSUB 300

180 GOTO 100

300 REM === MOVE MISSILE ===
310 POSITION MX,MY :PRINT "|";
320 FOR T=1 TO 75:NEXT T
330 POSITION MX,MY :PRINT " ";
340 MY=MY-1
350 IF MY<0 THEN FIRE=0 :RETURN
360 POSITION MX,MY
370 IF PEEK(PEEK(88)+MX+MY*40)=ASC("A") THEN POSITION MX,MY :PRINT " " :FIRE=0 :RETURN
380 RETURN

That code did run without any errors, but it didn’t really work. There was a ton of flicker and the aliens scrolled off the top of the screen. Moving the ship and firing did work, though.

I then suggested that it try to use Graphics 1 and that it not redefine any characters and instead use “A” for alien, “S” for ship and a vertical bar for the missile.

The code that came back ran OK, but it was still using Graphics 0.

10 GRAPHICS 1+16
20 POKE 77,0       :REM Disable cursor
30 SHIPX=10 :FIRE=0 :MX=0 :MY=0

40 REM === DRAW ALIEN ROW ===
50 FOR I=2 TO 18 STEP 3
60 POSITION I,5 :PRINT "A"; :NEXT I

100 REM === MAIN LOOP ===
110 ST=STICK(0) :BT=STRIG(0)

120 IF ST=11 AND SHIPX>0 THEN SHIPX=SHIPX-1
130 IF ST=7 AND SHIPX<19 THEN SHIPX=SHIPX+1

140 POSITION 0,22 :PRINT "                    "
150 POSITION SHIPX,22 :PRINT "S";

160 IF FIRE=0 AND BT=0 THEN FIRE=1 :MX=SHIPX :MY=21

170 IF FIRE=1 THEN GOSUB 300

180 GOTO 100

300 REM === MOVE MISSILE ===
310 POSITION MX,MY :PRINT "|";
320 FOR D=1 TO 50:NEXT D
330 POSITION MX,MY :PRINT " ";
340 MY=MY-1
350 IF MY<0 THEN FIRE=0 :RETURN
360 POSITION MX,MY
370 IF PEEK(PEEK(88)+MX+MY*20)=ASC("A") THEN POSITION MX,MY :PRINT " " :FIRE=0 :RETURN
380 RETURN

That is because it is using PRINT instead of PRINT #6. I told ChatGPT that it was still using Graphics 0, but it was not able to fix it on its first revision.

I again told it that it was still running in Graphics 0 to see if it might figure it out. But it did not figure it out, instead going off on a tangent about screen memory and character sets, neither of which were relevant.

I decide to tell it what was wrong: The problem is that you are using PRINT instead of PRINT #6;. You don't need to alter memory or character sets. Please try again.

It came back with better code, but it took several back-and-forths before it came back with code that actually ran. And even then it later crashed with an ERROR 141, Cursor out of range because it was using INPUT #6, which doesn’t make sense here.

Instead it really should use LOCATE to check for a collision with an alien ship.

Frankly, this vibe coding was exhausting and I gave up trying to coerce ChatGPT into getting this working. I think ChatGPT gave me a reasonable program outline, but the back-and-forth was just tedious! I certainly could have fine-tuned things faster.

So I did. Here is the working code for this simple game:

10 GRAPHICS 1+16
20 POKE 77,0:REM Turn off text cursor
30 SHIPX=10:FIRE=0:MX=0:MY=0
40 REM === DRAW ALIEN ROW ===
50 FOR I=2 TO 18 STEP 3
60 POSITION I,5:PRINT #6;"a";:NEXT I
100 REM === MAIN LOOP ===
110 ST=STICK(0):BT=STRIG(0)
120 IF ST=11 AND SHIPX>0 THEN SHIPX=SHIPX-1
130 IF ST=7 AND SHIPX<19 THEN SHIPX=SHIPX+1
140 POSITION 0,22:PRINT #6;"                    ";
150 POSITION SHIPX,22:PRINT #6;"S";
160 IF FIRE=0 AND BT=0 THEN FIRE=1:MX=SHIPX:MY=18
170 IF FIRE=1 THEN GOSUB 300
180 GOTO 100
300 REM === MOVE MISSILE ===
310 LOCATE MX,MY,C
315 POSITION MX,MY:PRINT #6;"."
320 FOR D=1 TO 50:NEXT D
330 POSITION MX,MY:PRINT #6;" ";
340 MY=MY-1
350 IF MY<0 THEN FIRE=0:RETURN 
355 IF C<>32 THEN S=S+10:FIRE=0
370 POSITION 0,0:PRINT #6;S
390 RETURN

There’s not all that much here. You can use the joystick to move the “S” ship left/right at the bottom. Press fire to shoot a “.” as the missile. If you hit an “A” alien then you get 10 points. The aliens don’t move. As I said, it’s rather simple.

As simple as this is, I’m really not sure how someone that doesn’t know Atari BASIC would be able to get it working at all doing just vibe coding with ChatGPT, which would constantly go back to writing incorrect code. Even when I knew something was wrong and corrected it, it didn’t always seem to help much. It feels like you’d hit an endless loop of back-and-forth prompts that won’t ever work properly.

As I mentioned at the beginning perhaps this is more useful with modern languages, but I’d say with an old-school BASIC, vibe coding was ultimately a bust.

联系我们 contact @ memedata.com