The Ramp Was Already in the Text

The Ramp Was Already in the Text

This essay was developed and edited with AI assistance. The argument, factual review, and final editorial judgment are the author's.
Answering a question asked on HN

Key Takeaways

  • Someone on Hacker News asked why AI can produce a convincing Super Mario but not a wedge ramp so their robot vacuum can climb a kitchen step, and whether the cause is data, representation, or evaluation. All three are real. Underneath them is a sharper line.
  • I gave a fresh Claude instance the asker’s job, with no tools and no context beyond one sentence of system prompt. It produced a parametric OpenSCAD wedge on the first request. Given the vacuum’s numbers, it found a belly-clearance problem at the crest I had not mentioned, and fixed it. The fix checks out to a tenth of a millimetre.
  • It got the crest right because the crest has a name. Off-road drivers call it the breakover angle, and the formula is on Wikipedia. Its two slips, a rotation with the wrong sign and a prose angle that disagrees with its own code, are the kind of geometry nobody writes down.
  • The research fits: transformers trained on Manhattan taxi directions produced valid routes 96 to 99 percent of the time while holding a map full of impossible streets, and collapsed to 0 to 8 percent under detours. Frontier models score near chance on classic spatial tests that humans pass at 80 to 100 percent.
  • A language model reaches a surprising distance into the physical world wherever people have already written that world down. What was never written down is your kitchen. The asker’s own fix, a harness that measures, previews, and verifies, is the answer to their question.

Someone bought a 3D printer and could not model. Their robot vacuum could not climb the step into the kitchen, and a wedge ramp is about the simplest functional object there is, so they asked the AI tools to make one. The “describe it and get a model” services returned shapes that could not be adjusted and were never quite what they meant. An agent writing Python to build the geometry directly topped out at simple primitives. What finally worked was decomposition: break the part into ordered steps, describe each as a small spec, and let an agent execute the steps in Blender. They wrote up the method and asked Hacker News the question that had been bothering them. Why is generating a functional part so much weaker than generating a figurine or a cartoon character? Is it data, because there is no large corpus of parametric CAD? Representation, because meshes are not the boundary representations engineers use? Or evaluation, because nobody benchmarks whether the thing prints and works?

The handful of replies split three ways, and each was partly right. One person had good results asking a model for OpenSCAD, because parametric design is code rather than sculpture. Another said you need a geometric modelling kernel to produce real CAD and no training set fixes that. A third said modelling was never the hard part; decomposing the object into usable chunks is.

Here is the answer the thread was circling. All three of the asker’s explanations are true, and they share a root. A language model is strong on physical problems exactly where people have already put the physics into words, and weak where the geometry has never been written down. The ramp had been written down. So had the trap at the top of it. The asker’s particular step, bin, and “what I meant” had not, and no amount of text-to-mesh will find them. I know the first half of this because I ran the asker’s job on a fresh model and hid one flaw in the numbers to see whether it would notice.


What Happened When I Asked a Fresh Model for the Ramp?

The setup was as bare as I could make it. One Claude Fable 5.1 instance, run headless, with a one-sentence system prompt (“You are Claude, a helpful assistant”), every tool switched off, and no hooks, plugins, or project files loaded. I logged the event stream to confirm that nothing fired and nothing was called. One session, two turns.

The first turn was the asker’s situation, phrased the way a person would phrase it:

I bought a 3D printer (a Bambu) but I can’t do CAD at all. My robot vacuum can’t get over the step into the kitchen. Can you make me a wedge ramp for it? Just give me OpenSCAD code I can paste in and print.

It did not ask me a single question. It made every unknown a named parameter, put a placeholder step height of 18 mm under a comment reading “MEASURE THESE,” and produced a wedge: a four-point polygon extruded sideways into a 120 mm segment, with a 1.5 mm nose so the thin edge would print, traction grooves cut into the slope, and a console line that prints the resulting angle. The core of it fits in four lines.

polygon([
    [0, 0],
    [ramp_length, 0],
    [ramp_length, step_height],
    [0, nose_thickness]
]);

Around the code came the advice you would get from a good forum post. Set the run to at least five times the step height, which keeps the slope under about 11 degrees. Print flat side down with no supports. Tape it to the floor or the vacuum will shove it around. If the vacuum stalls at the top edge, it may be reading the step as a cliff; a strip of white tape often fixes that.

Then the second turn. I gave it the real numbers, including two that I chose because they interact in a way nothing in the request hints at.

Thanks. Here are the actual numbers. The step is 30 mm high. The vacuum is 350 mm wide, 350 mm long and 96 mm tall. There is about 8 mm of clearance between the floor and the flat underside of the vacuum. The front caster wheel is about 220 mm ahead of the main drive wheel axle, and the drive wheels are 70 mm in diameter. The manual says it can climb thresholds up to 20 mm. My printer bed is 256 x 256 mm. Will your ramp work with these numbers? If not, change the code so it does.

The trap is the crest. Where a ramp meets a flat step, the vacuum has to drive over a ridge. With the caster on the kitchen floor and the drive wheels still on the slope, its flat underside spans the edge of the step like a bridge, and the edge pokes up into the middle of the bridge. Whether it clears depends on the ridge angle, the wheelbase, and the ground clearance, and nothing else. An 8 mm belly on a 220 mm wheelbase cannot take the slope the first answer recommended.

The model opened with “Short answer: no, not as written.” It described the bridge, wrote down a formula for how far the step edge intrudes, computed 10.8 mm for the ramp it had just proposed against my 8 mm of clearance, and concluded: “It would beach on the edge of the step.” It worked out that the slope had to stay under about 7.3 degrees, which for a 30 mm step means a run of at least 235 mm, chose 240 mm because that still fits a 256 mm bed, and reported that the crest intrusion was now 6.8 mm. Then it said the thing I was waiting to see whether it would say: “The 20 mm threshold rating isn’t the limit here; the 8 mm clearance is.”

It also added a check to the code itself, so that anyone changing the numbers gets a pass or fail in the console:

angle     = atan((step_height - nose_thickness) / ramp_length);
crest_sag = (wheelbase / 2) * sin(angle / 2);
max_angle = 2 * asin((belly_clear - safety_margin) / (wheelbase / 2));

And it flagged a second problem I had not thought of: while climbing, the body tilts nose-up by 7 degrees, so the rear edge of the shell dips and may drag at the bottom of the ramp.


Did It Get the Geometry Right?

I do not own the printer, so I checked the code rather than the part. The exact intrusion of a ridge into a flat underside spanning it, with the contact points a wheelbase apart, is half the wheelbase times the tangent of half the ridge angle. The model used the sine instead of the tangent, which for these angles differs by a hundredth of a millimetre. Its 240 mm ramp puts the crest 6.5 mm into an 8 mm clearance, a pass. The ramp its own five-times rule would have produced, 150 mm long and 10.8 degrees, puts it 10.4 mm in, a fail by more than 2 mm. Three 130 mm segments cover a 350 mm vacuum with margin, the run fits the bed, and the top edge is flush with the step by construction, because the polygon’s last vertex sits at exactly step height.

The formula it rediscovered is not new. Off-road drivers call it the breakover angle: the sharpest ridge a vehicle can drive over without its underside touching the apex, a function of wheelbase and ground clearance. Wikipedia’s approximation, twice the arctangent of twice the clearance over the wheelbase, gives 8.3 degrees for this vacuum, and 7.3 degrees once the model’s one-millimetre safety margin is applied. That is the number it arrived at.

Two things were wrong, and both are instructive. First, the prose and the code disagree about the angle of the same ramp. The prose says 7.1 degrees, computed from a 30 mm rise. The code computes the rise as step height minus nose thickness, 28.5 mm, and will print 6.8 degrees. Both are under the limit, so nothing breaks, but they are two descriptions of one object that were never reconciled. Second, the traction grooves are rotated the wrong way. The slope rises toward positive x, and the code rotates each groove by a positive angle about the y axis. In OpenSCAD’s convention, documented in the manual, a positive rotation about y carries the z axis toward x, which tilts the groove downhill while the surface climbs. Each groove ends up 13.5 degrees off the surface it is cut into, so across its 2.5 mm width it is 0.5 mm deep on one edge and 1.1 mm on the other instead of 0.8 mm throughout. Cosmetic, on a ramp that still works.

So on the asker’s literal question the model did the ramp, and did the part that needed a world. That makes the asker’s failure the more interesting fact, not the less.


Why Did the Ramp Work? Because Someone Had Already Written It Down

Look at what the model got right and where the knowledge lives. The breakover angle has a Wikipedia page with a formula. Nose thickness, taping the ramp down, printing flat side down with no supports, light filament because dark surfaces trip infrared cliff sensors: all of this is on 3D-printing and robot-vacuum forums, written by people who beached a vacuum or watched a thin edge curl. The model’s world model of ramps is a word model of ramps, and for ramps that is nearly enough, because the world was verbalized first by off-roaders and then by hobbyists, in detail, with numbers.

Mario is the extreme case of the same thing. He is among the most described objects in existence: sprites, fan art, wikis, style guides, millions of captions. A figurine of him has to satisfy one judge, a viewer, who is also the source of every description the model learned from. The judge and the training data are the same people.

The asker’s parts sit at the other end. Their step has a particular nosing. Their bin had to hold particular things. “Never quite what I meant” is the sound of geometry that exists in one kitchen and in no text. The text-to-mesh tools they tried had not read about that step because nobody has written about it, and the agent writing Python geometry stalled at primitives because a primitive is where the written descriptions stop.

Yossi Kreinin made the same observation about chess in an essay that front-paged Hacker News last year. A language model plays plausibly until the game leaves familiar territory, then within about ten moves starts moving pieces illegally. His diagnosis: “LLMs, specifically, have not learned that to make legal moves, you need to know where the pieces are on the board.” Ankit Maloo’s companion piece on Latent.Space put the general form in a sentence: “LLMs produce artifacts that look expert. They don’t yet produce moves that survive experts.” A ramp is an artifact. The crest is the move that has to survive the vacuum.


What Does the Research Say the Model Actually Holds?

The cleanest test of this I know is the Manhattan taxi experiment by Keyon Vafa, Justin Chen, Ashesh Rambachan, Jon Kleinberg, and Sendhil Mullainathan. They trained transformers on millions of turn-by-turn direction sequences from New York taxi rides, then asked what map the models had learned. By the usual measures, a very good one: valid routes 96 to 99 percent of the time, the true shortest path 97 percent of the time, and a next turn that was legal nearly always. Then they reconstructed the map implied by the model’s predictions. It contained streets with impossible physical orientations and flyovers passing over other streets. And when the researchers introduced random detours on 10 percent of routes, the share of valid traversals fell from 99 percent to somewhere between 0 and 8 percent. A model given the real map stayed at 100.

Directions are text. The map is the world. The detour is the crest: the moment a fluent sequence has to be right about something the sequence itself never said.

The SPACE benchmark from Apple, published at ICLR 2025, asks the question in the paper’s title, “Does spatial cognition emerge in frontier models?”, and answers it in the first two words of the abstract: “Not yet.” On the large-scale tests, the ones animals pass, such as estimating direction and distance after moving through a space or retracing a route, GPT-4o, Claude 3.5 Sonnet, and the open models averaged 17 to 23 percent against a chance level of 25. On mental rotation and perspective taking they scored 22 to 33 percent, chance again, where humans score 80 to 100. But the pattern inside the numbers is the point. On selective attention, which can be done in words, several models exceeded 95 percent. The best model’s score on the small-scale tests rose from 44 percent when the puzzle was an image to 65 percent when the same puzzle was text. The closer a spatial task sits to something that has been written down, the better the word model does.

None of this means models cannot form world models. Kenneth Li and colleagues trained a GPT on nothing but Othello move sequences and found an internal representation of the board state, one that interventions could edit to change the model’s next move. A world model emerged because predicting the next legal move without one is nearly impossible. The difference with ramps is that predicting the next sentence about a ramp is entirely possible without one, because the sentences already contain the geometry. The rotation sign is the tell. Which way rotate() turns is not something people argue about in forum posts; it is a convention you hold as a picture or get wrong. The model wrote a fluent groove and tilted it into the hill.


So Is It Data, Representation, or Evaluation?

Each of the asker’s three candidates is right, once you see what it is actually pointing at.

Data, but not the way the question assumes. The parametric CAD corpora exist. DeepCAD released 178,238 models with their construction sequences in 2021, and Text2CAD attached about 660,000 text prompts to roughly 170,000 of them in 2024. Against that, The Stack v2, one public code corpus, holds over three billion files and 67.5 terabytes. Four orders of magnitude, in files, is a real gap. But the gap that bit the asker is narrower and deeper: functional geometry is mostly never verbalized at all, and the exceptions, like the breakover angle, are exactly where the model shines.

Representation, and the commenter who said you need a kernel was right. So was the one who said OpenSCAD works, for the same reason. Parametric CAD is code, and a geometry kernel does the geometry. The model holds numbers and relations, which it can do, and the kernel holds the shape, which it cannot. Text-to-mesh asks the model to be the kernel. Mesh versus boundary representation is really the question of who holds the geometry, the model or a program, and the answer that works is the one that keeps the intelligence in the harness rather than the weights.

Evaluation, and this is the one that explains Mario. A figurine is graded by a viewer. A ramp is graded by a vacuum. Vafa’s detours and SPACE’s mazes are ramp tests for maps and for spatial memory, and the models fail them while passing every test a viewer would set. Nobody benchmarks whether a generated part prints and works, and when graders can be satisfied without solving the task, that is what gets optimized. The asker’s own pipeline contains a watertightness check, zero boundary edges or it does not export, which is the first honest grader in the whole story.


What the Asker Built Is the Answer to Their Own Question

Read the workflow they published as a diagram of where a word model ends. Step one is a discovery conversation that collects dimensions, materials, and intended use. Step two is a to-scale three-view drawing the human approves before anything is modelled. Step three turns the approved design into a specification that an agent executes in Blender, followed by a mechanical test that the result is watertight. Step four splits anything larger than the bed into pieces with connectors. Their own summary of the idea is that decomposition converts the spatial reasoning models are bad at into the structured code they are good at.

That is true, and it is half of what the pipeline does. The other half is that every step writes the world down or checks against it. The discovery conversation puts the kitchen into words, which is the one thing no training set can do in advance. The three-view drawing lets the human’s eyes grade the shape before a printer spends four hours on it. The watertightness test lets a program grade what a viewer cannot see. The harness is a machine for putting the world into the text on demand, and for refusing to trust the text until something outside it agrees.

My second turn was the same machine, operated by hand. I wrote down the vacuum, eight millimetres of belly and 220 of wheelbase, and the model found the crest, because once those numbers were in the conversation the crest was a problem off-roaders had already solved in words. What the model could not have done is measure my step. It made the step height a parameter and told me to measure, which was the correct thing to do and also the whole limit in one line.

The asker’s question was why AI can generate Super Mario but not a wedge ramp. The precise answer is that it can generate the ramp, and even the trap at the top of it, because the ramp was already in the text. Mario has been in the text for forty years. The thing that was never in the text is your kitchen. Put it there, in numbers, with a grader that is not a viewer, and a word model reaches a surprising distance into the world. Leave it out, and what comes back is a figurine.

Frequently Asked Questions

Why can AI generate Super Mario but not a functional 3D part?

Because the two jobs are graded by different judges. A figurine only has to look right to a viewer, and Mario is among the most thoroughly described objects in the training data. A functional part has to be right relative to things outside the text: a step height, a wheel, a printer bed. A language model does well on physical problems exactly where people have already written the physics down, which is why a fresh model produced a working ramp and caught a belly-clearance problem at the crest: off-road drivers named that problem decades ago. It does worse on the parts of your object that nobody has described, which is where the asker's text-to-model tools failed.

Can ChatGPT or Claude write OpenSCAD for a 3D-printable part?

For simple functional parts, yes, and it works better than asking for a mesh directly. In this experiment a fresh Claude instance, with no tools, produced a parametric OpenSCAD wedge on the first request, then revised it correctly when given the vacuum's ground clearance and wheelbase. Parametric CAD is code, and a geometry kernel does the actual geometry, so the model only has to hold numbers and relations. The two slips it made, a rotation with the wrong sign and a prose angle that disagreed with its own code by a third of a degree, were cosmetic here but show where fluency ends.

Do large language models have a world model?

Partly, and not the part that survives contact. Vafa and colleagues trained transformers on turn-by-turn taxi directions in Manhattan; the models produced valid routes 96 to 99 percent of the time, but the map recovered from them contained streets with impossible orientations and flyovers, and when 10 percent of routes had random detours, valid traversals fell from 99 percent to between 0 and 8 percent. The SPACE benchmark found frontier models near chance on classic spatial tests where humans score 80 to 100 percent. Models do form internal representations when a task forces it, as Othello-GPT showed, but text about the world can usually be predicted without one.

What is the breakover angle, and why did it matter for the ramp?

Breakover angle is the sharpest ridge a vehicle can drive over without its underside touching the apex, and it depends on wheelbase and ground clearance. A ramp meeting a flat step is exactly such a ridge. For a vacuum with 220 mm between its caster and drive axle and 8 mm of clearance, the ridge must be shallower than about 8.3 degrees, and shallower than 7.3 degrees with a millimetre of margin. The model's first ramp was 10.8 degrees and would have beached the vacuum by about 2 mm. Its revision, 240 mm long for a 30 mm step, clears by 1.5 mm.

What is the best way to get an AI to design a printable part?

Put your world into the conversation, then let a program grade the result. The asker's own workflow, published on GitHub, does both: a discovery conversation that collects dimensions and constraints, a to-scale three-view preview the human checks before modelling, a specification executed in Blender with a watertightness test, and automatic splitting for the printer bed. That is a harness that writes the world down on the fly and verifies against it. The same move worked by hand in this experiment: once the vacuum's clearance and wheelbase were in the prompt, the model found the crest problem on its own.