I found the following text while looking up the origin of the aphorism "perfect is the enemy of good". Though there are surely much older sources from where the meaning of the aphorism comes from, I found Shakespeare's retelling of it particularly beautiful.
How far your eyes may pierce I cannot tell.
Striving to better, oft we mar what's well.
I have been developing a system to serve as a platform layer and provide a small set of primitives that are sufficiently expressive for describing graphics and audio. The name I've been giving this system is "term10", because I wanted to cram all of this functionality into ≤1024 lines of code per platform. This limitation is less of a strict requirement and more of a reminder to myself that I want to keep this work tightly scoped.
Anyways, once the graphical primitives were in place, I wanted to take a short detour to see if I could port term10 to Windows and the Web. I was slightly apprehensive about my strategy of having a game consist of two processes: the engine (term10) and the game (clients written in standard C). The goal was to write platform specific versions of term10 that would implement the application protocol and keep the client code completely unchanged.
Would this work well on Windows, a not-Unix-like operating system? It turns out that porting to Windows went about as easy as any port could go. I plan to write a post later on how the translation of Unix-like idioms map to the Windows APIs. For now, I'll just emphasize that it really was a 1-to-1 translation.
Could I do something similar on the Web by using emscripten? This proved to be more difficult and I ultimately decided to deemphasize porting to the Web as a goal. The problem I encountered was with the interprocess communication between term10 and the client code. The goal was to implement term10 in JavaScript and then compile the clients (which are written in standard C) using the C compiler emcc as part of the emscripten tool chain. Then, term10 should be in control of executing the program produced by emcc. After term10 executes the client, we need to somehow read from the client's stdout and write commands to the client's stdin. This proved to be an issue, because emscripten's version of read() does not block! Shock! The emscripten system treats the case of no data being ready as EOF instead of blocking to wait for data to arrive. As of writing this, my current idea for how to fix this issue is to somehow wrap the execution of the client code in a web worker that would hopefully give term10 more freedom to pause and resume the client in the case when the client tries to read messages from term10 but none are ready yet. On paper, that seems very possible. I need to figure out the particulars of doing that in JavaScript, though.
When I ran into issues porting term10 to the web, I became defeated for an evening while I tried to readjust my expectations. I felt that my design that utilized interprocess communication was responsible for cutting of access to porting games to the Web. My response to this realization was to assume that I needed to take a more extreme approach and perhaps start work on a virtual machine, which is a much more traditional way of making video games that are more easily ported to different platforms. I want to avoid taking that approach, though; that's the main reason why I went down this path in the first place. Creating a virtual machine means creating a programming environment, and it is a lot of work to make a programming environment that is as comfortable to use as the programming languages that we use day-to-day. Too much work, for now.
After some reflection, I realized that I often too quickly find faults in a design (whether it is a game design or software architecture). For example, I don't even know whether porting term10 to the Web is a bust or not, but I'm already thinking about changing the design of term10. This is very detremental to the actual goal of shipping a game, because I have already succeeded at creating a very comfortable setup for porting between Linux and Windows. Perfect really can be the enemy of good if you are impatient with your work. It is much more wise to continue using this system I've spent a month on and treat porting to the Web as a goal I can put on the back-burner.