Een WebGL en Wasm applicatie bouwen met Claude Code
De afgelopen maanden heb ik onderzocht hoe je effectiever software kunt ontwikkelen met generative AI. Het is een krachtige, fascinerende en snel evoluerende techniek. Development agents zoals Claude Code zijn enorm krachtig, mits je weet hoe je ze effectief moet gebruiken. Dat is echter niet eenvoudig; het blijft veel experimenteren.
Om Claude Code op een leuke manier te testen, besloot ik een nieuwe demo-applicatie te maken voor mijn RSMotion C++-library. Deze library berekent het optimale navigatiepad tussen twee autoposities op een 2D-vlak, wat nuttig is voor bijvoorbeeld game development en robotica-toepassingen.
De library, die ik zes jaar geleden heb ontwikkeld, werkt nog steeds uitstekend. De bijbehorende demo-applicatie was echter extreem moeilijk geworden om te bouwen en uit te voeren. Toen ik het recent zelf probeerde, kreeg ik het niet eens aan de praat!
Ik besloot de hele demo-app weg te gooien en een modernere benadering te kiezen: een webgebaseerde applicatie die de functionaliteit van de library visueel zou demonstreren. Dit zou cross-platform zijn en, nog beter, eenvoudig uit te proberen.
De technische stack had ik al bedacht. Het zou bestaan uit Emscripten om C++ naar WebAssembly (Wasm) te compileren, JavaScript voor de applicatielogica, WebGL voor visualisatie, en interop tussen de Wasm-module en JavaScript-applicatie. Het probleem was echter dat ik geen expert ben in Emscripten, WebGL en de communicatie daartussen. Een perfecte use case dus voor AI-assisted development!
Ontwikkelomgeving #
Ik begon met wat handmatig werk: directories aanmaken, CMake-buildscripts opzetten, en een minimale JavaScript-applicatie om het laden van Wasm-modules te testen. Deze minimalistische setup kon de C++-code voor de simulatie en navigatieberekeningen compileren naar een Wasm-module en het laden in de webapplicatie. Maar nog zonder enige visualisatie of interop! Daarna vroeg ik Claude Code om een CLAUDE.md
te genereren met het /init
-commando en verfijnde ik de instructies naar eigen inzicht.
Met alles op zijn plaats was ik klaar om de AI-agent het over te laten nemen. Mijn eerste prompt was eenvoudig:
Create the initial setup for a render system in WebGL 2. Clear the background, setup an initial camera (zoom out a bit), and draw the checkerboard at the origin.
Het werkte feilloos bij de eerste poging! Aanvankelijk probeerde Claude OpenGL-functies te gebruiken die niet ondersteund worden in WebGL, maar het detecteerde de fouten in de consolelog en paste het snel aan door enkel functies te gebruiken die compatibel zijn met WebGL. Deze stap alleen al bespaarde me uren werk.
Mijn volgende prompt was complexer:
The C++ example application currently has the simulation working but it requires visualization through the web application. Please think very hard about how to create the visualization for the example and create a plan. Take into consideration the interop between the JavaScript and the Wasm module. Think about querying the state of the simulation from the JavaScript web application. Also think about how to use WebGL to visualize the ground, car and path (line segments).
Het kwam tot ongeveer 80% van de oplossing! Aanvankelijk kon ik sommige elementen niet zien bewegen, maar dat bleek een probleem in de C++-code te zijn. Na nog twee prompts werkte alles perfect.
Wat dit erg indrukwekkend maakte, was dat de AI-agent, Claude Code, de resultaten niet daadwerkelijk kon zien! Het moest zelf afleiden wat er op het scherm zou verschijnen omdat het werkte met een WebGL-context die het niet kon verifiëren. Een agent met visuele feedbackmogelijkheden zou nog effectiever zijn. In dit geval diende ik als de human-in-the-loop, die feedback gaf op de visuele output.
Verfijnen #
Ik merkte dat het 3D-automodel (een simpele box) het pad niet correct volgde door uitlijningsproblemen:
Change the car model such that the rear axle is at the origin of the model. I.e., the whole box must be translated half of the length in the direction of the z-axis.
Perfect. Toen wilde ik iets visueel aantrekkelijkers:
Can you create the geometry of a simple car instead of a box? I.e., a box with a smaller box on top?
Ook dat ging direct goed. Interessant om op te merken dat Claude hierna zelf het woord ‘cabin’ ging gebruiken terwijl ik alleen maar uitlegde wat ik visueel wilde hebben.
Ik realiseerde me dat ik iets belangrijks was vergeten:
Ah yes, I can now see it. Can you have a different color for body and cabin?
Toen kreeg ik een idee om de bestemming duidelijker te tonen:
I want to render also the car as it would be at the finish. Change the example such that two cars are always visible: the driving car and the static car that is always located and oriented at the finish spot.
Ik pakte een kopje koffie, en toen ik terugkwam was het klaar. Een laatste detail:
Can you make the finished car rendering 50% transparent?
Mooi. Misschien niet de mooiste demo, maar goed genoeg voor nu. Afronden maar!
Resultaten #
Het hele project duurde slechts een paar uur, vergeleken met de dagen die het zou hebben gekost als ik het allemaal zelf had moeten doen. Maar eerlijk gezegd zou ik het waarschijnlijk helemaal niet hebben geprobeerd zonder AI-assistentie. Realistisch gezien heb ik niet de tijd om dagenlang aan zulke projecten te werken.
Dit experiment benadrukte voor mij iets belangrijks: AI-geassisteerde ontwikkeling maakt ontwikkelaars niet alleen efficiënter, maar het maakt het ook mogelijk die projecten op te pakken die je anders zou laten liggen. Het opent mogelijkheden voor creatieve side quests en dat maakt het ontwikkelen ook weer leuker!