Posts in Lua (14 found)
Kartik Agaram 1 weeks ago

Quickly make any LÖVE app programmable from within the app

It's a very common workflow. Type out a LÖVE app. Try running it. Get an error, go back to the source code. How can we do this from within the LÖVE app? So there's nothing to install? This is a story about a hundred lines of code that do it. I'm probably not the first to discover the trick, but I hadn't seen it before and it feels a bit magical. Read more

0 views
Weakty 4 months ago

Radio Silence - An Unfinished Playdate Game

About 8 months ago, I started building my second game for the Playdate. The working title was "Black Hole" (later to be renamed "Radio Silence") and the idea was simple: you are a crew member in a spaceship that needs to enter a black hole. And so you orbit around the black hole, collecting raw materials from space debris, which you then use to craft items to help you successfully enter and cross through a black hole without getting crushed (Yes, I know that it's physically impossible to go through a black hole, but this is also a fictional game). When I started this game, I was coming off the momentum of having finished my first game for the Playdate, which was a success beyond my expectations (people actually paid for it!). I was determined to keep up that momentum. This time around I wanted to build something different. Whereas my first game used the Pulp game engine on the web, I now wanted to use Lua and to build something that was conceptually simpler—less of a story, and more of an arcade game. In the end, I lost steam on this project and have decided to let it go. But first, let me walk you through how far I got and some of the things I learned. As I mentioned, it's an arcade-style game and conceptually has a pretty simple story. The core loop is to collect materials, craft upgrades, and then to descend safely into the black hole. There were a few areas that I could embellish to make it more than this simple game loop, but at the end of the day, there wasn't much more to it than that. I'll walk you through the few main core mechanics that I had to build, show you some screenshots, and share what I enjoyed and disliked about that process. I began by creating a very simple mechanic, the ability for the ship to orbit a black hole and slowly descend into it. I spent maybe a week and a half on this, and it wasn't too complicated. I had to learn a little bit of math and got some help from GPT. In the end, I had a sprite that rotated around another sprite, the first of which would slowly move towards the second. Again, it was a matter of adding collision detection between the two so that when the ship touched the black hole, it would disappear, and the game would be over. But this alone was kind of boring. I needed to introduce some kind of mechanic that would keep the player paying attention, and I also wanted to find some way of using the crank. And so I built a strange little UI that was meant to represent the navigation of the ship to stay in balance with the black hole's orbit. The idea was that as you would rotate the crank, you needed to keep a special nav point in between two closing-in meters. It would get progressively harder as the game moved on, and using the crank, you would have to gently navigate this balance. Eventually, I had something in place so that when you lost control of the nav point's balance, it would cause the ship's health to decrease to a point where if it reached zero, it would fall into the black hole. For a while, I was satisfied with this, and then for a time, I thought, "This isn't very good, let's remove it." And then a few months later, I brought it back again. So I was feeling a little fickle about this feature. Before I got to the next large mechanic, I spent a good amount of time on the atmosphere of the game - I made a title screen, intro music, game music, and a generative background with shooting stars. This part was relaxing and fun, but also a place where I could noodle indefinitely. Here was when I played around with adding 1-bit characters from an asset pack I found on itch.io. I figured this could be a fun way to introduce a way of guiding the player on what to do if necessary. From the outset, I knew that I wanted to have a crafting component to this game. What I didn't know was how much work that would take. There is a lot of business logic that's involved in building a crafting system, and this really slowed down the momentum of the game. In fact, it got to a point where I really didn't want to work on it because of this crafting system. Some of the work involved: It was around this time that I started to think to myself, "I don't really want to make a game like this." And I realized that I was losing interest. I did have fun creating the raw materials, the items, and their respective descriptions (which had to be created as PNGs): At the beginning of this project, I started documenting my weekly progress on the game. This literally meant sitting in front of a camera, talking about what I had built, and then combining that with footage of the Playdate, development, and adding some reflections on top of that. I think I had some hopes that this would both a) be interesting, b) provide a record of my progress that I could feel motivated by seeing, and c) maybe get people interested in the game. Pretty typical stuff. While I do enjoy video editing, and I don't actually mind being on camera, I did find that this was pretty tedious by the end. It was taking away from my energy that I could be spending on the game, or really, on other things as well. None of the videos really got many views, just about 100 or so views per video. I was surprised to see that some repeat people would show up and comment and provide feedback as well as encouragement. That in itself is a nice component, especially when you're building something on your own, bit by bit. More importantly, I have a complicated relationship with social media. Mostly, I find participation in it to be a net negative for my life, personally. I felt that if I wanted something to be "successful" by the standards of YouTube, I would have to compromise some of my values on how I would present the content. This would mean creating something that would be oriented around clickbait, and unrealistic catfishing in terms of thumbnails and titles, rather than truly representative of what I want to make. At one point I was asking myself, am I trying to build an audience as fast and as large as possible? Or do I just want to make a game and be able to say I finished a game and here's what I learned? Documenting projects on YouTube doesn't need to be mutually exclusive of those two things, but I think that if any part of me had an interest in reaching more and more people and having a "successful" video, that it really actually just took away from my original intent. It's a tough balance to be sure. I eventually did finish the crafting system. And while I would term it as the motivation killer of the project, it was what came after that made me realize I didn't want to do any more work on this thing. After finishing these mechanics, when I looked at the game, I saw something that was very robotic. There weren't any animations, there wasn't any fluidity or juice as some people refer to it in games. And that was where I started to feel the most defeated. In fact, it wouldn't be too much work to add a few animations to spruce up the game. But something about even just having to learn how the animation class worked in the Playdate just felt insurmountable. I no longer wanted to work on the project. For what the game was, in its simplicity of the game loop, I just didn't feel like the idea and the execution so far merited any more time. Simple as that. If it isn't already pretty clear from this retrospective, there are a few things I would change. I wouldn't make YouTube videos at all. I just don't think it's worth it. While I did enjoy some parts of it, I think that it took away from having the energy to finish the game, and I think that it distracted me and discouraged me. I would have also spent more time brainstorming on what I wanted to build for my next game. While I was proud of myself for not picking the first idea that came into my head (which is what I did for my last game) and while I did indeed brainstorm several possible options, I think I should have spent more time thinking about what I really wanted to build. It's hard to let go of projects, especially ones that you've spent a fair bit of time on (and even more especially, ones that you have publicly discussed). It's hard to let go - but life's a bit too short to spend working on projects that you are toiling through and don't find too much joy in anymore. Thankfully, I learned a lot as I went along. Speaking of life - things are about to change around here anyway — We're having a kid! It's nice to let go of projects to make way for this big change; and this way I have one less unfinished thing floating around in my brain during this period. Someday, when I feel a bit more like I've got my feet under me with parenting, I might scope out something small I can build in the few scraps of time I have after the long (but rewarding) days to come. Will it be a game? Maybe. But maybe it'll be some writing, or drawing. Maybe something with a little less staring at a screen. Building the crafting menu sprite itself Building a means of collecting raw materials (asteroids) Displaying items that you've picked up in a grid Making it so that items that have been acquired can be combined with other items, i.e. creating recipes Showing the recipe once it's been crafted in the right-hand side pane of the menu Implementing the actual effects of that item once it has been crafted

0 views
Playtank 6 months ago

My Game Engine Journey

There, but certainly not back again. It’s sometime around the late 1980s/early 1990s that some developers start talking about a “game engine” as a thing. Maybe not even using the term “engine” yet, but in the form of C/C++ libraries that can be linked or compiled into your project to provide you with ready-made solutions for problems. Color rendering for a particular screen, perhaps, or handling the input from a third-party joystick you want to support. The two Worlds of Ultima games are built on the Ultima VI: The False Prophet engine, as a decently early example. When you put a bundle of these ready-made solutions together, it becomes an engine . In those days, the beating heart would usually be a bespoke renderer. Software that transforms data into moving pictures and handles the instruction set of whichever hardware it’s expected to run on. What id Software perhaps revolutionised, if you are to believe John Romero in his autobiography Doom Guy: Life in First Person (an amazing book), was to make developer tools part of this process. To push for a more data-driven approach where the engine was simply the black box that you’d feed your levels and weapons and graphics into. This is how we usually look at engines today: as an editor that you put data into and that makes a game happen. To give some context for this, I thought I’d summarise my personal software journey. One stumbling step at a time, and not all of it strictly engines . When I grew up in the 80s/90s, I was often told that programming was simply too hard for Average Joe poor kids like myself. You had to be a maths genius and you had to have an IQ bordering on Einstein’s. At a minimum, you needed academic parents. If you had none of those, programming wasn’t for you. Sorry. This is the mindset I adopted and it affected my early days of dabbling profoundly. Where I lived, in rural Sweden, there were no programmer role models to look up to, and there was no Internet brimming with tutorials and motivation either. Not yet. We didn’t have a local store with game-stocked shelves or even ready access to computers at school. Again, not yet. But eventually, maybe around the age of 10 or so, I ran into QBASIC on the first home PC that was left over from my dad when he upgraded. Changing some values in the game Gorillas to see what happened was my introduction to programming in its most primitive form. Ultimately, I made some very simple goto-based text adventures and even an attempt at an action game or two, but I didn’t have enough context and no learning resources to speak of, so in many ways this first attempt at dabbling was a deadend. It’s clear to me today, looking back, that I always wanted to make games, and that I would probably have discovered programming earlier if I had been introduced to it properly. Even if I felt programming was too complicated, I did pull some games apart and attempt to change things under the hood. One way you could do this was by using a hex editor (hex for hexadecimal ) to manipulate local files. This is something you can still use for many fun things, but back then hexadecimal was part of how games were packaged on disk. (Maybe it still is and I’m letting my ignorance show.) The image below is from Ultima VII: The Black Gate seen through a modern (free) hex editor called HxD . As you can see, it shows how content is mapped in the game’s files. Back then, my friends and I would do things like replace “ghoul” in Ultima VIII with “zombi” (because it has to be the same number of letters), or even attempt to translate some things to Swedish for some reason. (To be fair, the Swedish translation of Dungeon Keeper 2 is in every way superior to the English simply because of how hilariously cheesy it is.) To grab this screenshot I could still find the file from memory, demonstrating just how spongy and powerful a kid’s brain really is… With Duke Nukem 3D , and to a lesser extent DOOM , I discovered level editors. The Build Engine, powering the former, was a place where I spent countless hours. Some of the levels I made, I played with friends. I particularly remember a church level I built that had sneaky pig cops around corners, and how satisfying it was to see my friends get killed when they turned those corners. How this engine mapped script messages to an unsigned byte, and memorising those tiny message codes and what they meant, were things I studied quite deeply at the time. I fondly remember a big level I downloaded at some point (via 28.8 modem I think) that was some kind of tribute level built to resemble Pompeii at the eruption of Vesuvius. It’s a powerful memory, and I’m quite actively not looking to find that level to get to keep the memory of it instead. The fact that walls couldn’t overlap because it wasn’t actually a 3D engine were some of the first stumbling steps I took towards seeing how the sausage gets made. Several years after playing around with the Build Editor, I discovered WorldCraft. I built a church here too for some reason, despite being a filthy secular Swede, and tried to work it into a level for the brilliant Wasteland Half-Life mod. This was much harder to do, since it was fully 3D, and you ran into the limitations of the day. The engine could only render about 30,000 polygons at a time, meaning that sightline optimisations and various types of load portals were necessary. Things I learned, but struggled with anyway. Mostly because Internet was still not that great as a resource. Had I been smarter, I would’ve started hanging around in level design forums. But level design never stuck with me the way programming eventually would. During this time, I also learned a little about tools like 3D Studio Max, but as with programming in the past I thought you had to be much better than I was to actually work on anything. My tip to anyone who is starting out in game development: don’t bring yourself down before you even get started. It can deal lasting damage to your confidence. During the late 90s and early 2000s, something came along that finally “allowed me” to make games, at least in my head. At first it was DarkBASIC , which is a BASIC version with added 3D rendering capabilities produced at the time by the British company The Game Creators. This discovery was amazing. Suddenly I was building little games and learning how to do things I had only dreamed of in the past. None of it was ever finished, and I always felt like I wasn’t as good as people from the online communities. It’s pretty cool, however, that Rami Ismail hung out in these forums and that I may even have competed against him in a text adventure competition once. Along the way, I did learn to finish projects however. I made two or three text adventures using the DarkBASIC sequel, DarkBASIC Professional, and even won a text adventure competition all the way back in 2006 with a little game I called The Melody Machine . In 2005 I enrolled in a game development education in the town of Falun, Sweden, called Playground Squad. It was the first year that they held their expanded two-year vocational education for aspiring game designers, programmers, and artists. My choice was game design, since I didn’t feel comfortable with art or code. This was a great learning experience, particularly meeting likeminded individuals, some who are still good friends today. It’s also when I started learning properly how the sausage gets made, and got to use things like RenderWare Studio. An early variant of an editor-focused game engine, where designers, programmers, and artists could cooperate more directly to build out and test games. It was never a hit the way Unity or the UDK would become, but I remember it as being quite intuitive and fun to play around with. We made one project in it, that was a horde shooter thing. I made the 3D models for it in Maya, which isn’t something I’ve done much since. I don’t remember what SimBin called their engine, but I got to work in two different iterations of it in my first real work at a game studio, as an intern starting in 2006. One engine was made for the older games, like RACE: The WTCC Game that became my first published credit . The other was deployed on consoles and was intended to be the next-generation version of SimBin technology. There I got to work on particle effects and other things, that were all scripted through Lua or XML if I recall correctly. Writing bugs in bug tools while performing light QA duties. To be honest, I’m not sure SimBin knew what they needed any designers for. But I was happy to get my foot in the door. My best lesson from SimBin was how focused it was on the types of experiences they wanted. They could track the heat on individual brakes, the effects of the slipstream behind a car in front of you, and much more. They also focused their polygon budget on the rear of cars, since that’s the part that you see the most. You typically only see the front of a game model car in the mirror, rendered much smaller than you see the rear of the car in front of you. This is an example I still use when talking about where to put your focus: consider what the player actually sees the most. I did work with the visual scripting tool Kismet (precursor to Blueprint) and Unreal’s then-intermediary scripting language UnrealScript in my spare time in 2006, for a year or so. It had so many strange quirks to it that I just never got into it properly. First of all, Unreal at the time used a subtractive approach to level editing unlike the additive approach that everyone else was using, which meant that level design took some getting used to. With BSP-based rendering engines, the additive norm meant that you had an infinite void where you added brushes (like cubes, stairs, cones, etc.) and that was your level. In the UDK, the subtractive approach meant that you instead had a filled space (like being underground) where you subtracted brushes to make your level. The results could be the same, and maybe hardcore level designers can tell me why one is better than the other, but for me it just felt inconvenient. Never got into UDK properly, because I always felt like you had to jump through hoops to get Unreal to do what you wanted it to. With Kismet strictly tied to levels (like a Level Blueprint today), making anything interesting was also quite messy, and you had to strictly adhere to Unreal’s structure. My longest stint at a single company, still to this day, was with Starbreeze. This is the pre- Payday 2 Starbreeze that made The Chronicles of Riddick: Escape from Butcher Bay and The Darkness . The reason I wanted to go there was the first game, the best movie tie-in I had ever played. A game that really blew my mind when I played it with its clever hybridisation of action, adventure, and story. Starbreeze was very good at making a particular kind of game. Highly cinematic elements mixed with first-person shooter. If this makes you think of the more recent Indiana Jones and The Great Circle , that’s because Machinegames was founded by some of the same people. Starbreeze Engine was interesting to work with, with one foot firmly in the brushy BSP shenanigans of the 90s (additive, thankfully), and the other trying to push forward into the future. Its philosophies, including how to render a fully animated character for the player in a first-person game, and how scripting was primarily “target-based” in the words of the original Ogier programmer, Jens Andersson, are things I still carry with me. But as far as the work goes, I’m happy that we don’t have to recompile our games for 20 minutes after moving a spawnpoint in a level anymore. (Or for 10-24 hours to bake production lighting…) During my time at Starbreeze, I finally discovered programming and C++ and learned how to start debugging the Starbreeze Engine. Something that made my job (gameplay scripting) a lot easier and finally introduced me to programming in a more concrete way at the ripe age of 26. At first, I tried to use the DarkBASIC-derived DarkGDK to build games in my spare time, since I understood the terminology and conventions, but soon enough I found another engine to use that felt more full-featured. It was called Nuclear Fusion. It was made by the American one-man company Nuclear Glory Entertainment Arts, and I spent some money supporting them during that time. Now they seem to be gone off the face of the Earth unfortunately, but I did recently discover some of the older versions of the software on a private laptop from those years. As far as projects go, I never finished anything in this engine, but I ended up writing the official XInput plugin for some reason. Probably the only thing I ever wrote in plain C++ to be published in any form. Having built many throwaway prototypes by this time, but never quite finished anything, I was still looking for that piece of technology that could bridge the gap between my lower understanding of programming and that coveted finished game project I wanted to make. At this point, I’m almost six years into my career as a game developer and my title is Gameplay Designer. It’s in 2011-2012 that I discover Unity. On my lunch break and on weekends, I played around with it, and it’s probably the fastest results I’ve ever had in any game engine. The GameObject/Component relationship was the most intuitive thing I had ever seen, and my limited programming experience was an almost perfect match for what Unity required me to know. Unity became my first introduction to teaching, as well, with some opportunities at game schools in Stockholm that came about because a school founder happened to be at the Starbreeze office on the lunch break one day and saw Unity over my shoulder. “Hey, could you teach that to students?” All of two weeks into using it, my gut response was “yes,” before my rational brain could catch up. But it turned out I just needed to know more than the students, and I had a few more weekends to prepare before course start. Teaching is something I’ve done off and on ever since—not just Unity—and something I love doing. Some of my students have gone on to have brilliant careers all across the globe, despite having the misfortune of getting me as their teacher at some point. Since 2011, I’ve worked at four different companies using Unity professionally, and I have been both designer and programmer at different points in time, sometimes simultaneously. It’s probably the engine I’m most comfortable using, still to this day, after having been part of everything from gameplay through cross-platform deployment to hardware integration and tools development in it. You can refer to Unity as a “frontier engine,” meaning that it’s early to adopt new technologies and its structure lends itself very well to adaptation. You set it up to build a “player” for the new target platform, and you’re set. Today it’s more fragmented than it used to be, with multiple different solutions to the same problems, some of which are mutually exclusive. If you ask me if I think it’s the best engine, my answer would be no, but I’ll be revisiting its strengths and weaknesses in a different post. The same person who pulled me in to teach Unity also introduced me to Unreal Engine 4 in the runup to its launch. I was offered an opportunity to help out on some projects, and though I accepted, I didn’t end up doing much work. It coincided with the birth of my first child (in 2013) and therefore didn’t work out as intended. I’ve still used Unreal Engine 4 quite a bit, including working on prototypes at a startup and teaching it to students. It’s a huge leap forward compared to the UDK, maybe primarily in the form of Blueprint. Blueprint is the UE4 generation of Kismet and introduced the object form of Blueprints that you’d be used to today. Rather than locking the visual scripting to a level, Blueprints can be objects with inheritance. They are C++ behind the scenes and the engine can handle them easily and efficiently using all the performance tricks Unreal is known for. Funnily enough, if you came from UDK, you can still find many of the Kismet helper classes and various UnrealScript template shenanigans are still there in Blueprint and Unreal C++ but wrapped into helper libraries. It’s clearly an engine with a lot of legacy, and the more of it you know before starting the better. Autodesk Stingray is an engine that was developed from the Swedish BitSquid engine after Autodesk purchased it and repurposed it for their own grand game engine schemes. BitSquid was a company founded by some of the developers that once made the Diesel engine, that was used at the long-since defunct Grin and later Starbreeze-merged Overkill game studios. When I worked with it, Autodesk had discontinued the engine, but three studios were still using it and supporting it with internal engine teams. Those three were Arrowhead, Fatshark, and Toadman. I worked at Toadman, as Design Director. As far as engines go, Stingray has some really interesting ideas. Two things struck me, specifically. The first is that everything in the engine is treated essentially as a plugin, making it incredibly modular. Animation tool? Plugin. Scripting VM? Plugin. The idea of a lightweight engine with high extensibility is solid. Not sure it was ever used that much in practice, but the intention is good. Another thing I bring with me from those days isn’t strictly about Stingray, but about a fantastic data management tool called Hercules that Toadman used. It allowed you to make bulk changes to data, say doubling the damage of all weapons with a single command, and was an amazing tool for a system designer. It decoupled the data from the game client in ways that are still inspiring me to this day. Sadly, since earlier this year (2025), Toadman is no longer around. The jump between Unreal Engine 4 and Unreal Engine 5 is not huge in terms of what the engine is capable of, even if Epic certainly wants you to think so (Lumen and Nanite come to mind). But there is one big difference and that’s the editor itself. The UE5 editor is much more extensible and powerful than its older sibling, and is both visually and functionally a complete overhaul. There’s also a distribution of Unreal Engine 5 called Unreal Editor for Fortnite that uses its own custom scripting language called Verse, that is said to eventually be merged into the bigger engine. But I simply have no experience with that side of things. My amateur level designing days are long-since over. Probably the biggest change between UDK and UE5 is that the latter wants to be a more generic engine. Something that can power any game you want to make. But in reality, the engine’s high end nature means that it’s tricky to use it for more lightweight projects on weaker hardware, and the legacy of Unreal Tournament still lives on in the engine’s core architecture and workflows. As with Unity, I don’t think it’s the best engine. But I’ll get into what I consider its strengths and weaknesses in a future post. I’ve spent years working with UDK, UE4, and UE5, in large teams and small, but haven’t released any games with them thus far. Projects have been defunded, cancelled, or otherwise simply didn’t release for whatever reason. Imagine that you release a new update for your game every week , and you’ve been doing so consistently since 2013. This is Star Stable Online—a technical marvel simply for the absolutely insane amounts of data it handles. Not to mention the constant strain on pipelines when they’re always in motion. My biggest takeaway from working alongside this engine last year (2024) is its brilliant snapshot feature that allows you to to save the game’s state at any moment and replay from that moment whenever you like. Even shared with other developers. This approach saves a ton of time and provides good grounds for testing the tens of thousands of quests that the game has in store for you after its 14 years (and counting) life span. You may look at its graphics and think, “why don’t they build this in Unreal?”, but let’s just say that Unreal isn’t an engine built to handle such amounts of data. The visuals may improve, but porting it over would be a much larger undertaking than merely switching out the rendering. Can’t really talk about it. It’s Stingray, but at Arrowhead, and it powers Helldivers 2 . Like the engine’s Fatshark and Toadman variants, it has some features and pipelines that are unique to Arrowhead. I hope I get to play around with even more engines than I already have. They all teach you something and expand your mind around how game development can be done. At the end of the day, it doesn’t matter which engine you use, and it’s not often that you can make that decision yourself anyway if you’re not footing the bill. Like an old colleague phrased it, “there’s no engine worse than the one you’re using right now.” Fortunately, there’s also no better engine for getting the work done. QBASIC (around ’89 or ’90?) Hex Editing (early 90s) Build Engine (early-mid 90s) WorldCraft/Hammer (late 90s, early 00s) DarkBASIC/DarkBASIC Pro (late 90s, early 00s) RenderWare Studio (’05 or ’06) SimBin Engine (’06) First professional work. UDK (’05-’07) Starbreeze Engine (’07-’12) DarkGDK/Nuclear Fusion (’09-’12) Unity (’12-today) Toadman Stingray (’17-’20) UE4 (’14-’21, sporadically) UE5 (’21-today) Star Stable Engine (2024) Arrowhead Stingray (2025-?)

0 views
Kartik Agaram 6 months ago

A markup language and hypertext browser in 600 lines of code

Here's a document containing a line of text: I'm building in Lua, so I'm reusing Lua syntax. Here's how it looks: Such boxes are the workhorse of this markup language. There are 3 other kinds of boxes: , and . Rows and cols can nest other boxes. But let's focus on text boxes for a bit. Here's a text box containing two lines of text: Since it's hypertext, you get a few attributes. You can set , (background color) and (also color). Each of these is a Lua array of 3 or 4 elements for red, green, blue and transparency. Notice that the text is not centered vertically. The browser doesn't know details about the font like how far down the baseline is. You have to center manually using . I imagine this sort of thing will get old fast. Probably best to use and sparingly. Since this is a hypertext browser, the main attribute of course is hyperlinks. To turn a text box into a link you can click on, use the target attribute. Links get some default colors if you don't override them. The target is a file path that will open when you click on it; there's no networking here. Press alt+left to go back. What else. The one remaining attribute text boxes support is . You can use any font as long as it's Vera Sans (or you're welcome to open up my program and put more fonts in). But you can adjust the font size and select bold and italic faces. However, before we can see them in action I should discuss inline styles. A text box contains lines. Each line so far has been a string. But it can also be a string augmented with attributes. Here's a line with an inline 'tag': (So many irritating silly curly brackets! But I hope you'll stick with me here. The goal is a simple markup language that is easy to implement while still providing some basic graphical niceties.) Inline segments of text are surrounded in and prefixed with an alphanumeric name. (So they have to begin at the start of a word, after whitespace or punctuation.) The name gets connected up with attributes inside a block called . To stretch our legs, here's a text box with two lines, each containing inline markup for font and color. Each line's attributes are independent. So far you can't change font size or add borders inline, because it complicates matters to change line height within a line, and also seldom looks nice. Inline should arguably be used sparingly. The pattern I've been using more is to give each text block a uniform font and mix and match combinations of text boxes. There are 2 ways to combine text boxes: and . Here's a vertical array of text boxes: And here's a horizontal array: It's hard to see, so let's make the border more obvious. You can add attributes to and just like to . All children of share a width, and all children of share a height. Children can also share other attributes when specified in a attribute: Widths and heights will grow and shrink depending on what you put in them, but you can also fix a width in and boxes, and lines will wrap as needed. Notice that it'll try to wrap at word boundaries if it can. But it'll chop mid-word if a line would be too empty without the entire word. For completeness, here's a box. All it does is add padding within and . Within , needs to specify a , and within , a . The other dimension will resize as needed. Putting it all together, here's a table: No wait, that's not right: That's annoying! You have to specify columns before rows, or you're stuck manually sizing widths. But, 600 lines of code! Here it is. You'll need LÖVE, but the code should be easy to port to other graphics toolkits, the markup to JSON literals, etc. The program is a zip file containing the source code.

0 views
Andre Garzia 7 months ago

The Web Should Be A Conversation

For a very long time, I've defended that the Web should be a conversation, a two-way street instead of a chute just pushing content into us. The Web is the only mass media we currently have where most people can have a voice. I'm not saying all these voices have the same loudness nor that every single person in our beautiful planet and space stations can actually post to the Web, just that it is the one place where everyone has the potential to be a part of it. Contrast it with streaming services, radio, or even the traditional publishing industry and you'll see that a person alone with an idea has a lot more obstacles in their way, than when considering just starting a blog. For the last couple of years, there has been a colossal push by Silicon Valley companies towards generative AI. Not only bots are going crazy gobbling all the content they can see regardless if they have the rights to do so or not, but content farms have been pushing drivel generated by such machines into the wider Web. I have seen a horrible decline in the quality of my search results and the social platforms that I'm a part of — the ones with algorithmic timelines such as Instagram and YouTube — have been pushing terrible content towards me, the kind that tries to get a rise out of you. They do this to "toxically foster" engagement. Trying to get you to be so mad that you dive deeper into either an echo champer or a flame war. The enshitfication of the Web is real, but it is happening at a surface level. All the content you love and want is still there. They are just harder to discover cause FAANG companies got a nuclear powered shit firehose spraying bullshit all over the place. There are many ways to fight this and in this blog post, I'll outline what I am doing and try to convince you to do the same. Yes, this post has an agenda, a biased human wrote it. TL;DR: We need to get back into blogging. We need to put care and effort into the Blogosphere. A human-centric Web, in my own opinion, is one that is made by people to be browsed by people. The fine folks at the IndieWeb been hammering at this for a very long time: On Social Networks such as Facebook or YouTube, you don't own your platform. You're just feeding a machine that will decide to show your content or not to people, depending on how much their shareholders can make out of your work and passion. Your content is yours When you post something on the web, it should belong to you, not a corporation. Too many companies have gone out of business and lost all of their users’ data. By joining the IndieWeb, your content stays yours and in your control. You are better connected Your articles and status messages can be distributed to any platform, not just one, allowing you to engage with everyone. Replies and likes on other services can come back to your site so they’re all in one place. You are in control You can post anything you want, in any format you want, with no one monitoring you. In addition, you share simple readable links such as example.com/ideas. These links are permanent and will always work. — Source: IndieWeb I'm not advocating for you to stop using these bad social networks. You do whatever you want to do. I'm urging you to also own your own little corner on the Web by making a little blog. What will you post into it? Well, whatever you want. The same stuff you post elsewhere. A blog doesn't need to be anything more complicated than your random scribblings and things you want to share with the world. I know there are many people that treat it as a portfolio to highlight their best self and promote themselves, if that is you too, go forward and do it! If that is not you, you can still have a blog and have fun. There are thousands of ways to start a blog, let me list some that I think are a good way to go: These are just some ways to do it. There are many more. When you start your own blog, you're joining the conversation. You don't need the blessing of a social network to post your own content online. You certainly don't need to play their algorithm game. Join the conversation as you are and not as these companies want you to be. The Web becomes better when you are your authentic self online. Post about all the things that interest you. It doesn't matter if you're mixing food recipes with development tips. You contain multitudes. Share the blog posts and content creators that you like. Talk about your shared passions on your blog. Create connections. The way to avoid doomscrolling and horrible algorithmic timelines is to curate your own feed subscriptions. Instead of relying on social networks and search engines to surface content for you, you can subscribe to the websites you want to check often. Many websites offer feeds in RSS or Atom formats and you can use a feed reader to keep track of them. There are many feed readers out there (heck, even I made one, more about it later). Let me show you some cool ones: Once you're in control of your own feed, you step away from algorithmic timelines. You can use feed readers to subscribe not only to blogs, but your favourite creators on YouTube and other platforms too. If the website you want to subscribe to does not offer a feed, check out services like rss.app and others to try to convert it into a feed you can use on your feed reader of choice. With time, you'll collect many subscriptions and your Web experience will be filled with people instead of bots. Use opml exporting and importing from your feed reader to share interesting blogs with your friends and readers. Word of mouth and grassroot connections between people in the blogosphere is how we step out of this shit. Learn a bit of HTML to add a blogroll link to your template. Sharing is caring. As I mentioned before, I have been thinking about this for a long time. I suspect I might have created one of the first blogging clients on MacOS 8 (yeah the screenshot is from MacOS 9). I have no idea how many times I implemented a feed reader, a blogging client, or a little blogging CMS. Even this blog you're reading right now is a home grown Lua -based blogging CMS I made in an afternoon. BlogCat is my latest experiment. It is an add-on for Firefox that adds blogging features to the browser. It aims to reduce the friction between blogging and Web Browsing by making weblogs a first-class citizen inside your user agent. You can subscribe to websites, import and export OPML, all from inside the browser. You can have a calm experience checking the latest posts from the websites you follow. Being a part of the conversation is also easy cause BlogCat supports posting to Micropub-enabled sites and also microblogging to Bluesky and Mastodon. It uses a handy sidebar so you can compose your post while browsing the web. I been using it for a couple weeks now and am enjoying it a lot. Maybe you will enjoy it too. Anyway, this is not a post about BlogCat, but this post is what originally inspired BlogCat. As I drafted this post weeks ago and mused about the Web I want and the features I want on Web Browsers, I realised I knew how to make them. Instead of simply shouting about it, I decided to build it myself. You too can be a part of the conversation. You too can help build the Web you want. Let's walk away from the enshitfication of the Web by linking hands across the blogosphere. Micro.Blog : A simple and powerful blogging platform by people who actually love blogs. You need a subscription for it, but it can be as cheap as 1 buck per-month. Jekyll using Github Pages : If you're a developer and already know a bit about Git, you can quickly spin a blog using Jekyll and Github Pages. That allows you to start a blog for free. Wordpress : It pains me to write this one. I don't like Wordpress but I understand it is an easy way to start blogging for free. Blogger : Blogger still exists! A simple way to create a blog. Feedly : A SaaS that is liked by many. Create an account and subscribe to your blogs from any Web device you got. NetNewsWire : Polished macOS app that has been the gold standard for feed readers for more than a decade. It is FOSS. Akregator : From our friends at KDE, a FOSS Desktop feed reader for Linux and Windows. Miniflux : a minimalist feed reader. You can join their SaaS or self-host it. Rad Reader : A minimalist desktop reader for macOS, Linux, and Windows. BlogCat : Yep, I made this. More about this later. It is an add-on for Firefox that adds blogging features to the browser.

0 views
Andre Garzia 8 months ago

Creating a gamebook engine

I made this some time ago but never blogged about it. Unfortunately, I lost some of the source code, but that would be easy to rebuild. I decided to check what were the development options for the Playdate handheld console by Panic after receiving an email from them (I’m on the mailing list for the device). The offering is just too damn polished. Check out Develop for Playdate page. Like everything Panic does, it is damn well done. You can use the SDK to develop using C or Lua or a combination of both. They also offer an web IDE called Pulp that is similar to a pico-8 development workflow with tools for crafting fonts, screens, sprites, audio, and scripting. I went ahead and downloaded the SDK. I already had a license for Nova — which is the fancy development editor they make — and they ship lots of integrations for that editor with the SDK. Everything works out of the box. This is an example source loaded in Nova (using the Playdate theme and the extension). I’m using the editor task system to run the sample in the included emulator. It just works… I might be coding a gamebook engine for the Playdate… that was not in my strategy post, but the muse calls me and it is rude not to answer her call. And this is what my gamebook editor looks like:

0 views
Andre Garzia 8 months ago

Creating a simple posting interface

I recently noticed that I haven't been posting much on my blog which surprised me because blogging has always been among my favourite activities. The main obstacle that has prevented me from posting more often is that I didn't had an easy to use interface or app for doing so. When this blog was done with Racket + NodeJS, I implemented a MetaWeblog API server and thus could use apps such as MarsEdit to post to my blog. Once I rebuilt using Lua, I didn't finish implementing that API — I got it halfway done — and thus couldn't use that app anymore. I implemented Micropub API in Lua but am yet to find an app I like to use that supports that spec. Thankfully, Micropub is such an easy spec to implement that creating a little client for it can be done in hours if not minutes. Today, in about two hours, I made a small single-file HTML editor for my blog. It allows me to create new posts with ease including file uploads. It is actually the interface I'm using to write this post right now. It is a simple HTML form with 137 lines of vanilla JavaScript. All the JS does is simple cosmetics such as disabling buttons when posting or uploading is happening (so I don't press them twice) and using the fetch API to send data to the server. Of course this editor is super simple. There's barelly any error checking and most of the errors will just be console messages, but it is enough for my day to day usage. It serves its purpose which is to provide an easy way for me to make posts. I wonder what new features I'll implement as the week moves on.

0 views
Kartik Agaram 1 years ago

Sokoban

The kids have been enjoying Baba is You, and watching them brought back pleasant memories for me of playing the classic crate-pushing game Sokoban. So I went looking and found a very nice project that has collected 300 classic publicly available Sokoban puzzles. Then of course I had to get it on my phone so I could play it anywhere. The result is the sokoban.love client. video; 1 minute On a technical level, with sokoban.love I've finally managed to figure out how to scale modifying programs on my phone beyond the tiny scripts Lua Carousel supports. Carousel treats each 'page' of the carousel as a separate script, and shares the screen between the code for the page and the drawings the page makes. When you switch between pages, Carousel saves and restores code for you so the script currently on screen is always the one currently drawing. sokoban.love comes bundled with multiple pages of code (including 7000 lines for all the levels; those would be a pain to copy paste into Carousel). The pages all collaborate to create the app; switching pages changes nothing about the code that is running. The screen is also no longer shared between the app and its code editing environment. When you run the app the Carousel menu disappears, replaced by a single button to exit the app and edit its code. This approach works well for editing on a phone. The trade-off I made is to jettison the live-editing experience. You can still get that with sokoban.love, but you'll need to get on a computer and connect driver.love to it like all my Freewheeling Apps. As a bonus, sokoban.love includes a simple solver to eliminate some gruntwork for moving the player on touchscreens that you can see in action in this video. Tapping on the buttons along the edges moves the player a single square. Tapping on an empty square moves the player there if that is possible without moving any crates. Tapping on a crate and then an empty square will try to get the crate there if that is possible without moving any other crates.

0 views
Ginger Bill 1 years ago

Why I Hate Language Benchmarks

[Originally from a Twitter Thread] Original Twitter Post I don’t know if I have “ranted” about this here before but: I absolutely HATE comparing programming languages with “benchmarks”. Language benchmarks rarely ever actually test for anything useful when comparing one language against another. This goes for ANY language. Even in the best case scenario: you are comparing different compilers for the same language (and the same input). This means that you are just comparing how well the optimizing backends work for those compilers. Comparing different languages is not even in the same category. When comparing languages, you are not just comparing the optimizing backend of the compiler (assuming it even is compiled), but a completely different input. And most benchmarks rarely use the semantically equivalent code to test against. The implementations vary widely. And even in the case where the input is semantically equivalent AND the compiler backends for each language use the same “library” (e.g. LLVM), even then the semantics of each language may not allow for certain passes. LLVM is a good example which assumes C and C++ semantics. If your language does not adhere to C and C++ semantics, then most of the passes in LLVM cannot be used. And some compilers may have different default “flags” too, which makes dumb comparisons rarely equal (e.g. native vs portable microarchitectures). Clarifying the semantically equivalent aspect: a printing procedure in one language may be drastically different too. Runtime vs compile-time type information or none at all, flushing after each call or not, richer formatting or not, etc. Are you even comparing the same thing? There is also the “idiomatic” aspect which I hate too. “Idiomatic” in one language is a subjective and personal construct, and may produce very different results compared to “non-idiomatic” code. “Idiomatic” styles might produce slower code in general; the tests won’t show this. One of the most egregious websites for this is: https://programming-language-benchmarks.vercel.app . I recommend anyone to compare two languages of the same ilk and actually read the differences between the code in the tests; note how they are nothing alike most of the time. Different implementations & logic. n.b. I do personally try to make distinctions between the language, the compiler, the core library, and the ecosystem, as much as I can. I know most people do not and just lump everything together as a single package. This is due to most languages having a single implementation. But if you come from a C or C++ background, like my own, then you are/were confronted with the selection of different toolchains from the start (MSVC, Clang, GCC, Intel, tcc, 8cc, etc). And you are usually forced to write/import your own core library too (e.g. C’s is awful). For a language like Lua, there are different implementations, but they pretty much offer the same “ecosystem”, but just differ in how they are ran (i.e. VM vs JIT). And for many people, the choice of which to use is dictated by the use case. In summation, metrology is hard. You actually need to know what you are comparing against; if that thing is even measurable (quantitatively or qualitatively) in the first place; that the things you are comparing are actually useful or valid for what you want to know. Comparing multivariate things against each other and going “yep, that entire ’language’ is faster than this one” is misguided at best, and idiotic at worse. Please don’t treat “benchmarks” such as these as mostly pseudo-science, not science. Just because it has loads of numbers and “measurements”, does not make it “scientific”.

0 views
Kartik Agaram 1 years ago

Lua Carousel

I finally decided to hang up a shingle on itch.io. My first app there is not a game. Lua Carousel is a lightweight environment for writing small, throwaway Lua and LÖVE programs. With many thanks to Mike Stein who helped me figure out how to get it working on iOS, this is my first truly cross-platform app, working on Windows, Mac, Linux, iOS and Android. repo Carousel has its own devlog/notebook. I try to post little scripts that are easy for someone to copy to their clipboard, paste into Carousel and run. Some examples: Hilbert curve and Lindenmayer tree fractal (70 lines each) rectangle art (40 lines) simple example using the physics engine. (100 lines) Chromacline: a war between colors in Game of Life world (100 lines) simple UI examples; simple voice recorder ( sprite editor (100 lines) Pong wars (70 lines) equation plotting over an infinite surface with pan and pinch-zoom (150 lines) Lots of different kinds of charts (200 lines)

0 views
Gabriel Garrido 1 years ago

Redbean web server and the Fullmoon framework

I recently learned about Redbean , a single-file distributable web server authored by Justine Tunney . redbean is an open source webserver in a zip executable that runs on six operating systems. The basic idea is if you want to build a web app that runs anywhere, then you download the redbean.com file, put your .html and .lua files inside it using the zip command, and then you’ve got a hermetic app you can deploy and share. If the above sounds like magic that’s because it kind of is. Zip a directory of files, execute it, and you get the following running out of the box, across six operating systems: It doesn’t get any easier than this if you’re hosting a static website on a server. Generate some SSL certificates using cerbot, bind Redbean to port 80/443 and off you go! Paul Kulchenko authored Fullmoon , a zero depedency web framework based on Redbean. With it, you get: This is quite incredible. You can use this to build full-fledged web application. A typical webapp using PHP, Python, or Node.js requires you to put a webserver like NGINX in front of it. This separation of concerns makes sense for many reasons, but it still represents extra complexity and overhead. A seasoned engineer might not fret, but less experienced developers tend to struggle here. A web server like Caddy bridges this gap for certain use cases. Its built-in support for templated responses and custom plugins may allow you to forego a backend for dynamic responses. Yet, you’ll quickly hit the limits of what you can do as it is still first and foremost a web server. What excites me about Redbean and Fullmoon is that you get a vertically integrated web server and web application. Of course, there are many other considerations to account for a serious project but this makes sense for a lot of projects out there. Throw in htmx to the mix and you get an accessible, minimal yet capable stack that is easy to deploy. A fast static-file server Support for Lua scripts Embedded SQLite Integrated SSL support HTTP/HTTPS client Crypto and password hashing DDOS protection Routing, redirects Streamed responses Cookies/Sessions Form validation Cron syntax DB management with migrations

0 views
Ginger Bill 3 years ago

Multiple Return Values Research

I have recently been thinking about multiple return values as a concept, and wondering if there has been any kind of literature into the topic of “true” multiple return values which are not emulated through tuples . My current working hypothesis is that I think I have come to the conclusion (unless there is evidence to the contrary) Odin has invented a new kind of type system, something to the akin of polyadic expressions . It appears that Go and Odin are the only ones with what I call “true” multiple return values, but Odin’s approach is a lot more sophisticated than Go’s and extends the concept further. Odin’s idea is pretty simple: an expression may have n -values, where n is a natural number ≥0 . Meaning an expression may have 0, 1, 2, 3, 4, etc values, of which each value has a type, not that each expression has a type. An expression with 0-values has no (final) type to it (not even like in some languages). A way of thinking about this is that Odin is fundamentally a polyadic language rather than a monadic language, like pretty much everything else. However most languages seem to be polyadic in one aspect: input parameters to procedures/functions. In most languages, you have multiple (monadic) inputs but only one (monadic) output, e.g. ( ). Odin’s approach is to just extend this to the rest of the language’s type system, not just procedure inputs. In languages with tuples , they can emulate the ability to have multiple return values, especially if the language has sugar encouraging it. Let’s take Python as this basic example where tuples can be used to emulate multiple return values: Other languages may not use tuples to achieve multiple return values; languages such as Common Lisp and Lua do things slightly differently by pushing multiple values BUT the handling of the number of values is handled dynamically rather than statically: This is similar to in Common Lisp, Scheme, etc, of which it can suffer from exactly the same issues in terms of dropping of value bugs etc, especially due to its dynamic typing approach. A good example of this is to show that is the same as in Common Lisp. However, dynamically typed languages are not my area of research for this specific question, statically and strongly typed ones are. And in that case, all of the languages that allow for something like multiple return values (except for Odin and Go) use tuples. However tuples can still be passed around as a singular/monadic intermediary value. Tuples are effectively a form of monad which wrap values of (possibly) different types (essentially an ad-hoc record/struct type), which some languages may allow for explicit or implicit tuple destruction. Odin does differ from Go on multiple return values in one important aspect: Go’s approach is a bit of hack which only applies in the context of variable assignments. The following is valid in Odin but not valid in Go: The reason being is that Go’s approach for multiple returns only works in the context of assignment, and the assignment assumes that there is either N-expressions on the RHS or 1-expression on the RHS to match the N-variables on the LHS. Odin’s approach is a little more sophisticated here, the assignment assumes that there are N-values on the RHS for each of the N-variables on the LHS; where the N-values may be made from M-expressions (N ≥ M). Another fun thing about Odin because of this fact is that you can do the following (which is also not possible in Go): It also means something like this is possible in Odin: Internally, Odin’s approach could be implemented identically to as if a procedure was an input tuple + an output tuple and then automatically destructed, but semantically Odin does not support first-class tuples. n.b. For this research, implementation details are not of concern, only usage/grammar. Polyadic expressions are also used in another areas of the Odin programming language. One of the most common is the optional-ok idiom 1 : I am wondering if this approach to multiple return values is all Rob Pike ’s fault. Since the only languages I can find that are like what I speak of are: Alef and Limbo had multiple return values through tuples, but tuples were still not really first-class data types in those languages. In many ways, Alef and Limbo were the main precursors to Go (not just Oberon and Modula ). Limbo’s declaration syntax comes from Newsqueak which is also the precursor to Odin’s very own declaration syntax 2 . So maybe the reason there is little literature (that I can fine) into this topic is purely because it is limited to languages related-to/influenced-by Rob Pike. It might be the approach taken by Odin may be extremely unique to Odin, however it is also one of the my favourite things about Odin too. And I am really glad I added it so early on, since it has shown its utility really quickly. Coupled with named return values , bare statements, and , it is an absolute pleasure to work with. If anyone has any more information about this topic, please feel free to contact me with it! P.S. If there is no research done into this area, it is a good sign since there is so much left to discover in Programming Language Theory. This is technically 3 different addressing modes depending on the context ( map-index, optional-ok, or optional-ok-ptr )  ↩︎ https://www.gingerbill.org/article/2018/03/12/on-the-aesthetics-of-the-syntax-of-declarations/   ↩︎ Alef , Limbo , Go (Rob Pike related, the first two being non-destructing tuples) Odin ( me , who has been influenced by many of Pike’s languages) This is technically 3 different addressing modes depending on the context ( map-index, optional-ok, or optional-ok-ptr )  ↩︎ https://www.gingerbill.org/article/2018/03/12/on-the-aesthetics-of-the-syntax-of-declarations/   ↩︎

0 views