June 17, 2025
I stopped using numpy and thus fixed the error. I also created a demo and published to PyPI. The application does what it should do, maybe not beautifully, but it works. Maybe one day, I‘ll add the ability to view your loaded sprites before placing them, expand the commands and their parameters and add a bit of colour
is this enlightment
I was considering just excluding „None“ and „N“, maybe if I did that, I would‘ve never found out the truth.
Now the exit command works, and when you use it, you get a list of the commands you used.
what could those Ns possibly mean…
is what I was asking myself for a short while until I was sure it‘s None. I‘ll rewrite the canvas rendering.
I find it fascinating how with each new error, I can feel how I‘m making progress. First, it was errors with internal creation of sprite objects, then their addition to the session object, then the canvas object and now it‘s just that the terminal does strange things when displaying a canvas.
I started testing the application with a background sprite filled with dots and a boll with whitespace inside for demonstration purposes. I also made sure endwin() is always called, even if the world ends, so the terminal doesn‘t do weird things. In my tests, it still did weird things until today (see random characters at bottom of picture). Now you also don‘t have to CTRL + C to exit, you can just type „exit tool“.
Mypy‘s complaints about unicurses not having a type stub started to annoy me, so I began writing a .pyi file myself until I realised initscr() returns an integer, which doesn‘t fit into my brain as someone who writes web frontends with Python.
The README now has an installation and usage guide and some potentially useful information.
I finally implemented the canvas rendering, which is maybe the most important part. If there wasn‘t this error (see attachment) and I don‘t find any other bugs after fixing this one, you could use asciiasm. I think that‘s what you call an „off by one“ error?
I removed the Command class as I am not an OOP extremist. Now I think the application is close to be able to:
- load sprites out of text files
- allowing the user to place them on a canvas
- save the canvas in a text file
which is far from what I imagined, but sense of achievement comes first.
There‘s nothing to see because of a bug.
I realised I didn‘t know what I was doing, so I thought about myself and the universe and found out I don‘t have an idea what usage of the application should look like exactly. So I took a pen and a piece of paper and drew a flowchart I won‘t show here. Then I began attempting to partly translate that to Python code and wrote even more function/method stubs. I am still clueless but hopefully less than before.
Pokémon Go but coding instead of walking.
I kept the structure shown in the first devlog until now.
I wrote the „making that‘s outside of the main shape transparentby replacing it with None“ part. The code shown in the picture should/could find whitespace on each of the 4 borders, assuming the sprite is a rectangle, and goes inwards until it finds a non-whitespace character. It can‘t go around corners and will especially ignore whitespace enclosed by other characters. The solution I first thought of required repeating this process four times for each border, and for each border you have to do things differently (go up/down/right/left, start at top/bottom/right/left) so… dictionaries. Just read the code.
I also wrote the class representing the canvas and encountered some interesting questions, like does this class hold a list of the sprites and on which layer/at which position they are or is this information contained in the sprite objects themselves.
Now you could save your work if you were able to interact with the program. I also made more function/class stubs to make Ruff happy. Still nothing to show and copyright scares me, so no amoebas, just pure Python code.
I did awesome things that will inspire future generations, like starting to write some functions for reading and writing ascii (more like UTF-8) sprites from/to files. I‘ve got nothing to show, so here are some amoebas.
I started with creating some files and folders, I‘m sure it‘ll turn out this structure doesn’t make any sense, but it‘s not like it‘s carved in stone. Maybe I‘ll add fundtionality for creating animations or something like that.
A tool that helps with layering ascii art sprites and positioning, with control over what‘s in each layer. Made with curses and blazing-fast, pure Python.
Some more design fixes.
Better design, smarter usage of units for result display, input validation, usage guide in README
While desperately trying to get the app to work (the event listener added in python code executed by pyodide didn‘t want to work), I asked Copilot for swapping two lines, and it butchered the whole file, so I just gave up and fully committed to vibe coding. Aparently, Claude Sonnet is better at coding than me. It recognised that JS is racist against Python event handlers and made it so that the JS code creates the event listener and the handler, which calls my (Sonnet‘s) Python code. Now it works. If I ever get near that mess again, I‘ll try to enhance the design.
Now it looks something like the final thing. I also wrote the function that does the calculation. Input and output are next, then polishing the look.
I created the files and filled them with the bare minimum. This is the result. I’ll use Python and WASM because why not
A tool that calculates the total time spent on a recurring activity, based on its duration and frequency over a specified period. For personal agenda reasons, the JS code is held at the minimum while the main logic and calculation is done by Python code ran by Pyodide.
This was widely regarded as a great move by everyone.