In the last article, I wrote about the new IDE and programming language. It's just a prototype(not easy to read C code and many important features are missing), so the next logical move is to re-write it to the production-ready product. Can I build IDE in 4 weeks? Hell no, but maybe 8. Let's find out.

I will program in different fields. From rendering/UI, over network/cryptography, to parser/interpreter. Let the hacking begin!

Week 1

The first thing I wanna build is the ability to run SkyAlt on the server(run apps) and connect from a remote client(rendering, keyboard, mouse). For rendering, I chose SDL, mainly because it supports many operation systems. Network connections are TCP/IP handled by SDL_Net with simple custom protocol. Connections are encrypted. For that, I'm using functions from the OpenSSL library. The client needs a valid key to log-in.

The Protocol synchronize communication so the Client tells the server when it's ready for the next frame data. Also If the frame takes more time to finish, then Server tells the Client how much work on the frame was done and the Client shows the progress. The bottom-left conner shows FPS(frames per seconds) and bandwidth.

Rendering is bases on SDL2, SDL_image, SDL_ttf(fonts). It can draw rectangles, images, texts. The server sends only UTF-8 text, so fonts are on Client only. Every letter of the text is handled by my code(left, right, center align, ...). If apps include images(icons, ...), they are on the server, which sends (as files) them to the client's cache, where they are decompressed and converted into texture.

Also, I have one source code, but thanks to #define I can compile it like a Server(run apps) or a Client(remote, only rendering, mouse, keys) or a ClientServer(all inside).

By end of the week, I optimize the protocol cache for images and texts. Also, I clean up the code a little bit.

The video shows Client-Server where Server is sending commands(there are no apps, yet) what to draw to Client(window). Looks awful, but there is a lot of engineering behind it.

Week 2

The week starts with working on the dictionary. SkyAlt is dynamically-typed(static typing will be optional later, something like Javascript -> Typescript) and the memory model is an associative array(dictionary data structure, every record has value and sub-records and so on). I chose this model because I care a lot about developer's experience and If you think about it, in statically typed language you have to start with designing data structures and if you run the program it does nothing because there are no algorithms and that's frustrating. I want SkyAlt users to start with algorithms right away and thanks to REPL and preview they can see what they are making from the beginning. Overall time to build an app is the same, but the experience is different.

The next day, I write and run a few extra tests for the dictionary and slowly pivot my focus into integrating the dictionary to the SkyAlt memory model(record - sub-records). I constantly think about performance vs memory footprint for the dictionary.

Then I write .json importer and exporter.

I start working on Parser for the SkyAlt language. I try to parse some simple source codes, fixing a few bugs and it seems to work. So for the next few days, I work on the Interpreter and improving parser as well. I run more and more advanced tests.

There was a problem with the order of parsing assets(files), when one app uses multiple assets and that assets use other assets and there can be cycles, but around an hour later I solve it.

The video shows allocating 10M records and creating 5 sub-records for everyone. Then it's computing summary of one sub-record: The first 'sum' is for pure implementation in C, the second 'sum' is for search sub-record through the dictionary. Then It's just deallocating memory.

Week 3

I start the week with implementing catching pressed keys, mouse buttons & position on Client and sending them on Server. The great thing about SDL is that everything is UTF-8(across different OSs).

Then I try to compile code on Linux. I fixed a lot of bugs and many warnings(GCC is more aggressive than MSVC). I also optimized a few places in code so there is less (de)alloc every frame. FPS goes up. This is probably the worst day working on this project so far. So many things were broken.

The next day I focus on the UI layout system. Early on working on project I set that content is more important than design(layout, shapes, colors). So when you work with SkyAlt language, It's super easy to create GUI and define layouts under them, but of course there are tradeoffs. There is only one layout(grid layout), but it can expand/stretch(different screen sizes). I end up the day with a system where you can set column/row size and optional maximum size. Also, It's super easy for developers to change column/row size.

Implementing scrolling(mouse wheel, arrows, home/end/pageUp/pageDown) was quick since most of the parts already exist, so I only connect them together.

I start working on a Single-line editbox - text selection, copy/paste.

I finish the week by fixing bugs, few performance issues and cleaning the code. I'm not really making aggressive optimizations, because I need to see the big picture first. I also avoid multi-threading.

Sorry, I didn't make a video.

Week 4

Ok, 4th week, here we come.

I had to rewrite code that handling layouts. It's using less memory, hopefully, bug-free and cleaner code.

I fixed text-align, working with keys and implemented dialogs(center screen or like a context menu). Also, You can change GUI theme colors.

The Info panel on the client shows server FPS. This is not the real number of frames computed, because it computes only frames which the client needs(max. 60), but it's a number of frames which the server is possible to compute.

I start working on the Multi-line editbox - text selection, copy/paste. You can also scroll text! Uff;)

The video shows work in progress Settings app, where you will be able to change language, theme, etc. You can also change the row size. That was just for testing purposes, I've removed it after capturing video.

Week 5

When you work hard for a few weeks, why not work harder?

When you change language, all assets are automatically re-parse. Also, You can put an image(file) into an asset folder and App can render it.

I've finished the Settings app from the previous week and make the Menu app(New/Open project, Settings, About, etc.). You can switch between Windowed / Fullscreen mode and save app(code, data, translations). Also I make the Translation app, where you can translate apps to different languages.

I rewrite how URL works: checking for cycles, safely removing records and better language syntax. I hope, I will not have to touch it again.

I implement Context help - when you move the mouse over the button, edit-box, etc. the description shows up with little delay.

I try making a more advanced version of multi-line edit-box to use it as a code editor. So I add line numbers, syntax highlighting, showing warnings/errors in code. I add auto-break lines that are longer than a view into Multi-line. Also work on selections: 2 clicks for selecting a word and 3 clicks for the line.

The next day I start implementing Folding. When you call a function in source-code, you can "expand" it and It will show you the body of the function.

I spend some time putting down CPU usage when the user is not active. When the user stops moving the mouse and pressing keys, it will go to 0%(no drawing) and every 5seconds it will go 0.2%(drawing one frame, so the user can see possible new/changed data) => minimum CPU clock speed. On another side, When the user is active, then it renders 60 frames per second and has a maximum CPU clock speed. That's how ImGui works. I will try to deal with that later.

I finally trace one stupid memory-leak which I knew of for over a week. I fixed save() when record(text) has quote character inside.

For the first time, my TODO list starts to become shorter.

The video shows basic code editor with (un)folding capability. There is a small bug which I fixed after making this video: when I unfold function, it unfolds all function with the same name.

Week 6

Still motivated, I'm not slowing down!

I start with the cleaning code from the previous week. I compile it for Linux and discover some new warnings in code and few bugs.

I implement accounts. You can log-in with a username and 128bits key. Also, the Client window remembers position and size when it's closed and opened again.

I work on REPL. You can Alt+click into code and it will execute code up to that line and show you in preview. You can also Alt+click into app preview and it will unfold code to the line which draws the part of the app. It works well and it's quick. Although it doesn't work very well when an app has more than one layer(context menu, dialogs). I'll back into that later.

I also fix not-precise syntax/error highlights and change syntax highlight colors. Also, I fix the saving/reading json file. This is quite normal, I change code in one part and in some cases, I will have to change some other parts of the code as well. That's why I optimize code only when it hurts because optimize code is harder to rewrite.

The video shows simple IDE, where you can edit code(left) and see a preview of the app(right). You can also see folding and REPL in action.

Week 7

On Monday, I noticed that If the code in SkyAlt language had errors, the Interpreter would still execute it. So I quickly fix that. I also implement key shortcuts(copy, cut, paste, etc.) and text selection with arrows. Also, the parser will not run when you are typing(it will start with 2 seconds delay).

Originally I implemented Apps(code & data) and Assets(only code, something like libraries). I simplify it, so everything is Asset, but If the folder includes 'data.json' it can be run(like a app). Also, I think a lot If I should let developers rename records(after it's created) or only change the value of the record. Right now it's both, but I already know about a few cases where it can produce problems.

I add a new panel under code editor which shows: #Errors, #Warnings, "Line Preview" checkbox. You can also use arrowUp/Down to go into/out the fold. Selection is possible only inside the fold.

I create the Record inspector app. It's part of IDE and it shows Temporary and Permanent records if you use REPL.

Also, I create the Resources app. Which is used for adding/removing files(icons, background images, etc.) into assets. You can simply drag & drop files on the window and will copy files into the asset folder. This is supported with the client-server in mind, so when you have two computers it will send files between them.

The last app I create is the Base app, which unites all other assets together(Menu, IDE, etc.). It includes tabs, so you can open multiple apps.

I finish the week with C code refactoring. Better texture filtering(I didn't turn on blend antialiasing to this moment, don't ask why). I fix when the frame rate is low, some clicks, key presses are missed. I compile and test the Linux version(0 errors, 0 warnings). AddressSanitizer reports few indirect memory leaks, that's normal.

1st video shows the application for making translations for other apps. It will be part of IDE.
2nd video shows the Resources app. With drag & drop, you can import the file into the asset and then remove it.

Week 8

7 weeks in, let's add one more.

I add Code history(back/forward buttons/shortcuts) to the code editor. I colored the left panel for lines that were executed. And If you move the cursor over the variable, the context help will show you value. Press F8 to take a screenshot.

I decide to change syntax for SkyAlt language. When I called the function it used '+', '++', '-', which are now 'draw', 'dialog', 'call'. Also I change some API names, for example drawRect(), drawLine() is now paintRect(), paintLine() and so on. For widget setting I don't use '_attrs', but 'props'. I also change URLs, so for every record which is URL, the name must start with '_'. So for users, it's super quick to realize what is behind the record name.

I add a few new errors and tons of warnings messages into the parser. It checks similar variable names as '_value' vs 'value'. It checks if function parameters exist(as well for 'paint...()' APIs). When you create a new record the default value is empty text, not number 0.

I fix the layout Resizer(visually it has more space around and user doesn't have to be so precise. I fix open/save() json for a sub-records without a name and when a record's name starts with '_', it knows that value is URL path. Alt+click activate "Line preview" and I fix few REPL bugs as well.

SkyAlt became slower, so I make a few optimizations aka faster dictionary, creating/removing sub-records and lower bandwidth between client-server. I also implement many TODOs in SkyAlt apps.

The video shows the product where everything is put together: tabs, opening apps, browser/IDE/translations/resources modes.


What a ride!

As you can read, the week's descriptions are written more like a personal diary than a tutorial. I wanted to focus on building the product more than documenting it. I publish it because there are so many startup articles about pitching, marketing, sales, picking the right problem to solve ... and valuations, but I don't see many articles about building products.

I worked mostly between 8 am and 5 pm. A lot has been done over the weekends. There were a few days when I didn't work the whole day and then around 8 pm I started and kept working until 2 am.

The videos weren't taken at the end of the week, but on "random" day in a week. I also regret that I didn't apply git and committed it every day/week. I don't have any data about the number of lines added/removed. Right now C code has around 14K LOC.

Did I finish in 4 weeks? No. Was it fun? Yes, no, yes, no, yes, no, yes. I feel good, I can keep rolling for another 60days. I wanted to build IDE, but it looks like I'm building the whole platform(IDE, language, app's deployment, asset sharing and more).

Milan Suk
18th December, 2020

Thanks for reading, feel free to try SkyAlt, send me an email or follow me on Twitter(@milansuk).

Blog GitHub Twitter E-mail