Exigy Dev Journal
sort: old
Date: Wednesday December 04th, 2024
Time: 08:55:53 PM MST
From: @vga256
Keywords: programming, history
Subject: Where Exigy began

Way back in the mid-90s when I was a teenager, I worked a couple of summers at a new regional ISP that served the sub-arctic and arctic regions of northern Canada. The ISP, Snowshoe Inn Micro, was located in the village of Fort Providence - a place of around 500 people. Aside from going fishing along the Mackenzie River shoreline, or wandering around its dusty dirt roads while the midnight sun rounded the horizon, there wasn't much to do in the evenings after work.

Instead, I spent almost all of my hours back in the office playing Quake deathmatch and chatting with friends on IRC. Seeing me while away my time with games, my boss made an offer: he'd teach me how object-oriented programming using Microsoft Visual Basic 3.0, or just 'VeeBee'.

He taught me the IDE using a Pair Programming style - I sat left-seat, typing in variable names while he sat in the co-pilot's seat, quietly offering suggestions and asking questions. For one month, every single night, he guided me through building a VB application - an image viewer/photo gallery - and taught me OOP concepts like classes and encapsulation. After I got the hang of it, I began programming my own applications and games after work, and into the new school year. I can safely say that without his mentorship, I would have never become a programmer and game developer later in life.

Visual Basic led me to Borland Delphi (Object Pascal); Delphi led me to Macromedia Director (Lingo); and Director led me to Macromedia Flash (ActionScript). With all of these IDEs and languages, working via drag-and-drop components and objects was the central metaphor. The "command line" attitude that was typical of MS-DOS and UNIX programmers was hung up at the door, and thinking user-experience first was the core value.

Fast-forward 25 years ...January 2024... and I once again found myself hungry for an all-in-one IDE and game development toolkit. I spent two years with Unity, and found cold comfort with its 3D-only and poor UX philosophy. Godot, though more thoughtful towards beginners, suffered greatly from its 3D metaphor. web.archive.org/web/20180620234954/http:polycode.org/>A very unique IDE called Polycode was incredibly promising, but was abandoned by its master after a few years of development. IDEs like Tumult Hype were so deeply reliant upon Javascript that they proved useless for game development. Adventure Game Studio - though very amenable to visual development - was so deeply tied to making Sierra and LucasArts adventure games that it was almost useless for something as simple as Tetris.

In short, there were no visual development environments out there to make the kinds of simple, 2D games that I grew up playing in the 90s. Games modelled on Maxis's Sim Farm, Sim Earth and Sim Life, were incredibly frustrating to build with modern tools. Something that might have taken a week to build in Visual Basic would now take two months in Unity. That kind of development cycle is death for small development studios.

It was now April 2024; three months into the launch of Studio Tomodashi, and I had no way forward for making the kinds of simple shareware games I wanted to make. I needed an IDE and toolkit that didn't exist anymore.

So I decided to start making it, with only a vague idea of what I wanted, and no idea how to build any of it.

First commit: Point and click for tile type change is working. by vga256 Apr 3, 2024 at 3:27 PM

A screenshot of a tile-based engine.
And here it is: the first build of what would eventually become Exigy. Green grass, white snow, and brown dirt tiles rendering randomly.

Date: Saturday December 07th, 2024
Time: 08:55:53 PM MST
From: @vga256
Keywords: programming, history
Subject: Week 1 - it's okay to be ugly when you're young

My #1 beef with almost any piece of game development software - from Unity to Godot to GameMaker - is always the user interface. Right from the outset, you're presented with an overwhelming number of menus, options, buttons and hotkeys, and a massive blank canvas with a bunch of gridlines on it. If you're new to the IDE, you're instantly lost. The UI is built for the person who has already spent 100+ hours in the IDE, already knows their way around, and just wants to get stuff done as efficiently as possible.

I call this (probably unfairly) Programmer-Centered Design or just "Programmer Thinking". It's how people end up raving about why Vim or Emacs are the One True Text Editor, and why many artists say Blender "Is Just Fine (once you get used to it)". I have to be honest - when I get some dumb game idea, I don't want to play it in a week or a month or a year. I want to play it tonight.

In response, I began building Exigy around the idea that Rapid Application Development is the right thing to do when it comes to small, indie-sized games that should take hours (not years) to build. Should prototyping a game take 6 months? No. That's a crazy waste of resources and your human finitude.

If I now know what I don't want to make, what are examples of great game development IDEs? Fortunately, there are a few that I consider to this day, exceptional. Very few people know about them, and almost no one has designed game development IDEs around them.

Eric Chahi's Another World Editor

Another World's editor does everything involved in the production of the game: creating and modifying polygons, animating them frame-by-frame, editing scripts for character behaviour and events, and controlling music and sound playback.
The another world editor, showing the protagonist reaching for his laser gun.
The another world editor, showing several characters as polygons.
Almost everything happens on the polygon editor screen, shown above. You can see how two characters have been placed on the screen, and then pulled apart into their constituent polygons and polygon groups. Note the toolbar full of buttons at the bottom: everything involved in the creation and modification of a polygon is here, and there are no menus to dig through. Every colour of the 16-colour palette is present. Each button is displayed as an icon. It is very likely modeled on Deluxe Paint - an incredibly popular paint program for game developers and artists at the time.

Now, the icon drawings themselves aren't entirely intuitive. It's likely that Chahi mostly made this for himself, so he didn't put tremendous effort into drawing self-evident iconography - you and I would have to guess at their meanings at first.

Each icon on the editor is described by the author. Mercifully, Chahi provides a quick reference for the editor. Here we can see just how completely functional the interface is: you can do everything on the main screen.

The another world editor, showing several characters as polygons.
Clicking on the "Ed" button launches the code editor. This is no windowing system here - it just replaces the main interface with his handcoded text editor. Here, all behaviours and events in game can be modified for the particular scene or character that we're working with. I won't go into Chahi's scripting language - which Fabien Sanglard has already done in an extremely elegant manner. (We will get to this topic another day - but, the idea of having an interactive scripting language is an extremely importance influence on how Exigy is built.)

For over ten years I've thought about Chahi's editor, and how it might be modernized, and improved upon for a more general purpose game engine. A few thoughts that have went into Exigy's GUI design:
* A windowing system is critical. Having toolbars that can be dragged around and re-arranged to the developer's taste are vital.
* Buttons and icons can communicate a lot more to a user than reams of text labels. Chahi's editor is missing Tooltips, so let's make those a core part of the IDE.
* Hiding everything in menus is a mistake; so is exposing the entire engine's options on a single screen. Chahi's editor is purpose-built as a polygon editor, so he can get away with having it all on one screen. Exigy will require some creativity to both expose enough to the beginner, but hide "advanced" options that aren't immediately important.
* Creating and modifying sprites in the IDE with a mini paint program is an important addition. Aseprite is a wonderful tool, but constantly switching between the IDE and an external tool can be very annoying and tiresome.
* The colour and/or tile palette needs to be immediately accessible at all times.
* Single-clicking on any object in a window should reveal its object "inspector" or mini-window that lets you tweak any relevant settings.
* Double-clicking on any object in a window should reveal the code editor.

It was with those design considerations in mind that I began, in earnest, building Exigy's windowing system. April 11's commit reveals my first attempt at having separate windows for separate programs.

It's rough, but squint hard enough and you can see the beginnings of a windowing system. There's a Colour Palette toolbar, a Sprite Editor window, Tile Picker window, and the Terrain Map window. Clicking on a tile in the tile picker selects it, and lets me paint tiles to the terrain. Offscreen, I'm scrolling left-and-right with the arrow keys as I paint. Did you notice how after a certain point, the tiles stop painting, or paint in the wrong areas away from the mouse cursor? That's because I hadn't figured out "map offsets" yet - meaning: scrolling the map needs to be meaningfully linked to the mouse position. Every single interaction on screen must be handled conceptually.

The Sprite Editor is full of random pixel colours, because I hadn't figured out how to transform PNG bitmap data into editable sprites yet. But you're beginning to see things coalesce: windows can be created with a single Exigy API call... Window:new(x, y, width, height) and the mouse can drag around any window element that has .draggable = true set. The window titlebar is a window element.

That's been a week of progress and learning how Windowing GUIs work. Figuring out the math for translating on-screen coordinates (the mouse cursor) to tile map coordinates turns out to be difficult problem for me, and it's something I'll figure out in the coming weeks.

At this point, Exigy's little tile editor and related toolbars are a whopping 150 lines of Lua code in a single main.lua file. I'm amazed at just how functional Löve2D is right out of the box. I didn't write any hardcore drawing functions - I just got it to paint some graphics to the screen at specific x/y coordinates. I notably have not figured out "Classes" yet - an Object-Oriented Programming term - but that will come in time. I do know that Lua does not offer Classes, and they are something that must be created using its Metatables concept. Once I have that figured out, I can begin splitted out functions from main.lua into separate files, and making Windows and Buttons their own separate classes.

Date: Saturday December 14th, 2024
Time: 08:55:53 PM MST
From: @vga256
Keywords: programming, UX
Subject: Week 2 - Point-and-click Adventures

When I started writing Exigy, I had a few aborted attempts at a point'n'click-driven windowing system behind me. The first, built in Adventure Game Studio, was more or less faked with a clever use of the built-in static GUIs, and a bunch of custom windowing code that I wrote to handle things like determining windowing order, and a drag-and-drop system. All of this was very kludgy, and a lot of it involved hardcoded values. This purpose-built windowing system was fine for the kinds of one-shot games I was working on at that point, but it was impossible to generalize into a module or plug-in that would allow me to use it as a game building tool, which is what I really wanted. I had the same experience a few months later trying to do the same kind of system in Unity and C#.

The outcome for me in both situations were the same: both AGS and Unity were not really usable as IDEs for building a 2D tile-based game quickly. I was frustrated beyond belief - I had worked for two years on various game projects using my custom coded windowing system, and didn't have a single publishable game out of them. Including the eight years I spent working as a contractor for various game studios, I had now worked for ten years as a developer, and didn't have a single game of my own. But my experiences trying to bend/twist/break AGS and Unity into useful IDEs had one important outcome: I now knew how to write really solid GUI/Windowing/Mouse code, because I had nailed down the fundamentals of how those systems typically work. It wasn't wasted time, after all.

The rest of April (2024) saw a few critical design decisions made about how Exigy works:
* All IDE or game objects (characters, buttons, images, sounds, tiles, monsters, you name it!) can be grabbed with the mouse, and dragged around the IDE.

Every game object should be manipulated with the click-and-drag interface. Direct manipulation makes things feel tactile and interactive. This is a lesson I learned from Bill Budge's Pinball Construction Set.

* Dropping the object/character/button/image/sound/tile/monster - whatever it is - on an IDE window constitutes a object+verb action!

For example: If I pick up and drag a Terrain Tile onto the Sprite Editor, that loads the Terrain Tile's image data into the editor. I can use the mini pixel editor to recolour the sprite the way I want it to look.

* If you drop something on a window that can't use that particular kind of object, the IDE should search inside of the object for any kind of data that could be used with the window.

For instance, imagine I drop a Sound Effect icon on the Sprite Editor window. Normally, we'd expect nothing to happen. But the Sound Effect's icon is compatible with the sprite editor. The sprite editor extracts that icon data out of the sound effect, and lets you edit it.

* Dragging from an editor window should generate data that can be dropped elsewhere.

How this works: Say I've been painting up a storm in the sprite editor. How do I save what I've been working on? Usually this involves clicking a Save File... menu option, and then going through a series of dialog boxes to find a place on the hard drive to save it. But there's a far more visual way of doing the same thing: what if I grabbed the painting, and dragged it over to the object that's supposed to use it? I drag the sprite editor's window contents on top of the terrain tile to copy the image back over it. Voila. Terrain tile with a new paint job.

If you're thinking along the same lines as me, you might be already familiar with this kind of interface thinking: it's how point-and-click adventure games work! Think about it: 90% of classic adventure game puzzles involve either dragging one inventory item over another one to "combine" them, or involve dragging an inventory item into the scene to "use" the item on a character or thing in the scene. We already intuitively know how these actions work, without much explanation. So why don't our game development IDEs work that way too?


This is the editor's behaviour as of April 30th, 2024. There have been some improvements to the windowing system - you're now able to see "window skins" applied. The blue one in the video is the default Windows 3.1-style skin.
Now, watch me drag a terrain tile from the Tile Picker (the narrow window in the middle) to the Sprite Editor. See how the cursor turns into a Myst-like hand icon? That's a "drag object" event. When I let go of the tile object on top of the Sprite Editor, it loads the sprite from the tile and lets me repaint it. Now - here's the critical part - when I'm done painting, I **grab the repainted Editor sprite* and drag that back over top of the old ugly tile. When it drops, not only does it repaint the terrain tile, but it automatically repaints *all of the terrain tiles in the terrain editor* that use the same terrain tile type.

Finally, notice how I grab the dude with the smiley face from the Editor Toolbar and drop it into the Terrain Editor? That's how we spawn new character entities! As soon as it drops into the terrain editor, I'm able to use the arrow keys and start walking it around the scene. Sure, it's ugly as heck, and gets the corners of the sprite clipped off - but it works! :)

Finally, the Game Window you see is just a blank window. A Window is a special type of object that accepts *all kinds of other objects* dropped onto it. I drag a button object on to it, and then a picture object on to it. Some day, this will become our Window Builder program, just like how the Form Builder worked in Visual Basic.

Date: Saturday December 21st, 2024
Time: 08:55:53 PM MST
From: @vga256
Keywords: programming, lua
Subject: Visual Programming Languages via Behaviours and Callbacks in Lua

I spent quite a bit of time in May figuring out what I call "Behaviours". It's an idea I stole from my days making games with Macromedia Flash (Dreamweaver had it too). Since Flash was designed to be drag-and-drop, Behaviours allowed novice users to add interactivity to their objects without writing a single line of code. For instance, if you wanted a button to play a sound when the user clicked on the button, you'd find the "onClick" event in the button, and drag a "Play Sound" Behaviour to that event. No code. Just a single drag.

Knowing nothing about how I might achieve the same kind of thing for Exigy, it meant understanding what a Behaviour is in the first place, and then figuring out how to implement one.

A Behaviour is a thing that I want to happen when another thing happens: it is a response to an event. So, it might be "when the object is clicked, play music" or "when the object intersects with another object, make it explode", or even "when the object gets updated every frame, change its animation frame". Each of these is an Event, followed by a Behaviour. Or, in psychological lingo, Stimulus -> Response.

For a programmer, this means implementing two things: objects must now process Events, and have a catalogue of Behaviours to respond to those events. In Lua lingo, they involve using "callbacks" - a programming concept that is very poorly explained, and used almost everywhere. Probably because it is very poorly named to begin with.

Imagine a situation where you want give your friend's mom your home address. You don't have her phone number or her home address. So you call your friend, and tell them to write down your address on a post-it note. You can't talk to their mom directly, and she can't talk to you directly. Your friend visits her, she asks for the address, and your friend hands the post-it note to her. Now she can drive to your house.

So what part of that is the "callback"? It's not the friend, it's not you, and it's not their mom. The callback is the post-it note. It is a piece of information that can be passed around, and provides directions (calls back) to some important location or thing or person, without the sender and the receiver knowing of one another directly in the first place. Furthermore, that little post-it note can be passed around anywhere! Your friend can hand it out to family, other friends, and mortal enemies. It will always point back to your house.

This is just an analogy, and won't stand up to serious scrutiny. But hopefully it shows the most important quality of callbacks: they give you the power of passing around an address/location without the originator and receiver knowing one another directly.

So why do callbacks matter for Exigy and games that can be modified at runtime? Imagine not being able to use callbacks: In order to deal with an interaction between objects without using callbacks, we have to know beforehand just what those objects are, where they are located, and how they should interact. And that's exactly how most game programming toolkits work: when the Player has a Knife object, and Uses the Knife object on the Orange object, show a Cutting Orange In Half animation. Every interaction like this is bespoke/handcrafted, and the game developer spends most of their existence writing interaction-response scenarios between every object in the world. There is code for use-orange-on-knife, use-knife-on-apple, use-apple-on-orange, use-orange-on-apple... you get the idea. It's awful, and 99% of adventure game developers are forced to write boilerplate item interaction code.

What would callbacks change in this scenario? I could, for instance, write a callback that goes like this in pseudocode:

DO EVENT:
OBJECT (A) HAS INTERSECTED WITH ANOTHER OBJECT (B)
       DO CALLBACK:
       SEND BOTH OBJECTS TO THE CUT-TESTING-MACHINE
              CUT-TESTING-MACHINE:
                     TRY TO CUT OBJECT A WITH OBJECT B
                     IF THAT FAILED
                     TRY TO CUT OBJECT B WITH OBJECT A
                     RETURN THE CUT OBJECT
EVENT (COMPLETED):
       THANKS FOR RETURNING THE OBJECT TO ME
       SHOW THE ANIMATION OF THE OBJECT

BEHAVIOUR:
       THE ORANGE IS SLICED IN HALF
       
That's a bit goofy, but now imagine that we've changed the callback from "CUT-TESTING-MACHINE" to:
       DO CALLBACK:
              SEND BOTH OBJECTS TO THE SHARPENING-MACHINE
                     SHARPENING-MACHINE:
                            TRY TO SHARPEN OBJECT A
                            IF THAT FAILED
                            TRY TO SHARPEN OBJECT B
                            RETURN THE SHARPENED OBJECT
EVENT (COMPLETED):
       THANKS FOR RETURNING THE OBJECT TO ME
       SHOW THE ANIMATION OF THE OBJECT

BEHAVIOUR:
       THE KNIFE IS SHARPENED


What we have now is a bit of code generalization. It's no longer necessary to write handcrafted scenarios for every knife/skate/scissor or orange/apple/pear in the game. We can use the "CUT-TESTING-MACHINE" callback or the "SHARPENING-MACHINE" callback, without changing any other code in the game.

Callbacks work as the glue between the event and the behaviour. Thankfully, writing them in Lua is an absolute cinch. Lua allows for the one thing I've wanted from every single programming language I've used: passing a function as a parameter.

For example, take these three functions:

function ExplodeBehaviour(npcName)
       print(npcName, "explodes like a blood sausage.")
end

function HitBehaviour(npcName)
       print(npcName, "falls over, bruised by the pummeling.")
end

function DodgeBehaviour(npcName)
       print(npcName, "dodges the attack deftly.")
end

       
Passing those functions around as parameters in most languages is gnarly, and requires the use of "pointers" or "lambda expressions". (C# is an exception - it uses a similar special command "func<>"). For the most part, writing callbacks are ugly, and it's not easy to read when you're trying to understand someone else's code.

So how do you pass the above functions in Lua to a receiving function?


-- first we store each function in a callback variable
explodeCallback =
       function(npcName)
              ExplodeBehaviour(npcName)
       end
hitCallback =
       function(npcName)
              HitBehaviour(npcName)
       end
dodgeCallback =
       function(npcName)
              DodgeBehaviour(npcName)
       end

-- and then we pass the callback variable as a parameter!
AngryPistolero(hitCallback)
FriendlyGringo(dodgeCallback)
AngryPistolero(explodeCallback)


Running the game, you see:


Friendly Gringo dodges the attack deftly.
Angry Pistolero falls over, bruised by the pummeling.
Angry Pistolero explodes like a blood sausage.


Callbacks let us pass around Behaviours like a pack of cigarettes in a federal penitentiary. It's no longer necessary for the Receiving object (the enemy you're attacking) to know anything about the Player, or for the player to know anything about the enemy. They're kept separate, and all that gets passed around are the Behaviours they engage in.

Now, no one wants to be writing callback functions like that constantly. What Exigy does is let you pick a Behaviour like "Dodge", and then lets you drag it to an event like "OnAttack". It takes care of packaging up the behaviour in a callback. So when the player attacks, it automatically calls the Dodge behaviour. Or plays a sound. Or plays back an animation.

This isn't meant to replace programming, but instead allows the user to trigger simple one-off behaviours that are annoying to write boilerplate code for. Stuff that we use constantly in games: like playing back interaction sounds.

Date: Saturday December 28th, 2024
Time: 08:55:53 PM MST
From: @vga256
Keywords: unity, godot, interfaces, design, ui
Subject: Why Unity and Godot Suck, and the Joys of Kai's Power Tools

This morning I watched this excellent talk by Ivan Safrin, creator of the Polycode IDE/game development toolkit. In the talk, Ivan argues for the importance of free, open-source tools in game development, and offers Polycode as an alternative to Unity and other commercial software packages. He makes three points about what makes good tooling in software development:

* It's free and open-source.
* It's easily accessible and simple; yet deep enough for professional use.
* It's cross-platform.

It's hard to argue with any of the above. He continues, "My goal was to create something like Unity, but is free and open source." And in that way, Polycode succeeded in becoming a viable Unity-like alternative, which preceded Godot by two years. If you watch where Ivan demos Polycode in the video (~24:00), you'll notice just how similar Polycode is to both Unity and Godot: they all revolve around the same kind of interface - a 3D scene with entities, a compass rose for navigating the scene, a panel composed of a hierarchical tree of scenes and entities and resources, a scripting window that loads scripts from a list of filenames in the tree, and so on. If you've worked with either Unity or Godot, this should be familiar to you.

Later in the video (36:00), Ivan clarifies that his beef with commercial game development tools like Unity isn't the commercialization of games, but that the IDE is explicitly designed with commercial production in mind. That's a really important point. But what does it mean?

When I began working on my own little game projects with Unity and Godot (and Polycode), I really struggled with their interfaces. Dragging and dropping entities into the scene was frustrating, and required all kinds of fiddling to get the placement just right. Searching for the right object in the file navigator felt like I was back living in the Norton Commander days again, digging through collapsible trees of directories and filenames.

Despite Polycode's superior attention to aesthetics (which to this day, I appreciate), the overall metaphor for interaction among all three of these IDEs was the same: a kind of bleak, utilitarian, function-over-form, attitude toward the user interfaces. There was no sense of joy or exploration when trying to build a game with these tools, and none of them encouraged experimentation or creativity. They were about "getting shit done" instead of figuring out what could be done by just goofing around.

With Unity's style of IDE design, the game developer is treated as an "implementer": they received their marching orders from a design bible or technical design document, and have to figure out the fastest way of getting the job done. Tweaking something, like modifying a sprite or changing an enemy's strength, must be done outside of the IDE - jobs that are done by the artists and scripters on the team. For highly polished, professional AAA titles, that IDE design style is absolutely important. Baked into the design of the IDE is the assumption that you are working on a large game, with a large specialized team, and that the IDE's role is to glue pre-formed assets together. The IDE isn't there for any serious scripting, or bitmap repainting or 3D modeling.

Despite Ivan's intention to make Polycode different than Unity, it ended up baking in the same kinds of interface design assumptions. It ended up becoming an IDE built for people who already know how to paint, already know how to program, and just need an interface to glue together and compile assets. Godot, while having an entirely different history, ended up with the same kind of interface design. Sadly, Ivan moved on to other projects and Polycode was abandoned to github about 9 years ago. (Ivan, if you ever read this: I'd love to read a post-mortem on Polycode if you have any interest in writing about it some time!)

So what is the alternative to utilitarian, function-over-form, implementation-driven IDEs?

I've been thinking about this a lot lately, and started thinking about all the truly great interfaces I've worked with over the years. The first that came to mind were the programs designed by Kai Krause.

You might remember Kai for his incredibly goofy, playful applications like Kai's Power Goo:
A screenshot of Kai's Power Goo, showing the Mona Lisa with a distorted, goofy face, like someone has smeared her features with a fingertip.

There are a few things worth noticing in the screenshot:

* The interactive context is immediately obvious to the beginner: the content is in the center of the frame, and the control knobs are arranged around it.
* The controls are large and very clearly labelled.
* The animation frame control uses an easy to understand film strip metaphor.

Bryce 3D - a modelling and rendering package (screenshot credit: Anatoly Shashkin) - is far more complex, but manages to find the same kinds of simplicity:
A scene in the 3D modeling program Bryce 3D 2.0, showing a landscape in the center of the frame. All kinds of cylindrical, pyramidal, and cubic buttons surround it.

Notice how:

* All of the controls are shaped like physical knobs, meant to be twisted and turned.
* The content remains in the center of the frame, and controls surround it.
* There are no drop-down menus or panels or windows.
* All controls are on the screen; nothing is hidden.

Moreover - and not shown in the above screenshots - is that all of the action happens in real-time. Experimenting with buttons and settings and knobs results in an immediate response in the scene: a nose gets distorted, the eyes bulge out, or fog appears in the distance. The core value is interactivity.

(If you want to get deeper into Kai Krause's design work, there are already some great articles out there on Kai's interface design philosophies, and Matthias Müller-Prove's article in particular is a fascinating read.)

Kai's software is designed to be invitational instead of functional. Every button on the screen begs the user to be clicked on or twisted or dragged. It's designed for the kid who enjoys playing around with things and seeing what happens, and not the adult professional who wants to get things done as fast and cheaply as possible.

That's my aim for Exigy: to design as much of the UI as possible around the joy of experimentation and just-seeing-what-happens-when-you-click-something. It's not there yet. I spent the bulk of 2024 roughing in all of the utility code that lets stuff display on the screen, lets you drag around things, and saves the data to the hard drive.

Now comes the hard part: in 2025, turning Exigy into a game toolkit that Kai himself would have wanted to play around with. I hope you decide to check it out, and help me figure out how to design joyful interfaces.

Date: Saturday January 04th, 2025
Time: 09:22:19 PM MST
From: @vga256
Keywords: testing, tomo
Subject: A drunken walk roadmap for the next couple of months

first - cool news: i found out today that Thom over at OSnews wrote a little article about Exigy! I honestly never imagined anyone would write anything about this project outside of mastodon D: thanks Thom!

one question I continue to get almost daily is: when can we start goofing around with Exigy?
The first 9 months of the project involved roughing out all of the basic functions a 2D game making toolkit would require. I managed to get some basic saving and loading (aka. serialization) set up a few weeks ago, and while it requires some re-tuning, it's in there and working.

in anticipation of a pre-pre-pre-pre-alpha coming soon, I'm spinning up a tomo shard to facilitate tester feedback, bug reports and creating a little Exigy community. If you've never heard of tomo, I don't blame you! :) I've been pretty quiet about tomo's development over the past year, as all of my development time has been laser-focussed on Exigy.

The short of it is: tomo is a public forum/discussion system that runs on NNTP (the protocol that powers USENET). i realized a few weeks ago that it would be the perfect platform to use as Exigy's home for discussions about the project, get some ideas and responses on the design of the program, and so on. if you want to read more about tomo, head over to tomo's project page.

so for the next couple of weeks, Exigy will be on pause while I rebuild tomo to support posting, user profiles, avatars, bug reports, attachments so you can share your XGY projects, and all the fun stuff we'll need for some old fashioned bug huntin'. (tomo is brand spankin' new software too. so that means we'll be doing two pre-alphas in one!)