I still have to finish load and save-related stuff, and I realized I wanted to support multiple images. Maybe by next week!


I've made little paint programs a dozen times or more. Sometimes the "paint" programs are actually level editors. These tools always do similar things, but I haven't tried to reuse their functionality. This time I tried to make that generalization. It includes common tools, brush stroke shapes, and tool previews. For right now the core tools are freehand draw, straight lines, and rectangles. For the demo app I extend it with flood fill and copy-paste.

The current architecture is ignorant of actual canvas data - it takes "tool state over time" and returns lists of changed pixels. In the future I might include some way of getting at the canvas data to make those operations reusable.

Github libpainter

Did some writing and sketching on the editor component

The drawing-and-adjusting parts of Pixelbound are basically complete, but might go through some visual tweaks later. Remaining stuff:

  1. Finish the side panel for renaming and managing different rectangles(insert, remove, order)
  2. Add a ID tag for each rectangle(a number, associated with a project palette)
  3. Project load and save
  4. Some cleanup of the initial project load dialogue


This is a haxe library to extract some basic data from exported Twine stories(only tested against Twine 2 rn). I'll get to adding serialization and other stuff soon.

https://github.com/triplefox/libtwine

I've been working towards vector path tracing this week. This includes island detection, a marching squares implementation, and Ramer-Douglas-Peucker path simplification. My next plan is to decompose the vector paths into convex shapes; then I will be able to convert raster graphics into 2D physics objects.

https://github.com/triplefox/libpainter

This is an WIP audio engine. It's very low-level in design, everything is allocated against one buffer. I'm rushing a bit to get something out by the streak deadline, I'll keep updating it later.

https://github.com/triplefox/tone

This is a library I made for personal use a while ago. It contains MIDI manipulation and sequencing stuff, and a synthesizer.

https://github.com/triplefox/minimidi

I added a simple volume envelope and a PolyBLEP oscillator implementation. I also sketched something for FM.

Added a more complete envelope earlier this week. It still needs curvature adjustment...

"Value" is a demo web app I made that lets you create a blog of 320x160 1-bit animated images, all authored with a browser-based editor. I haven't deployed the live site yet - that will happen soon and whether I'll make it public is TBD - but the app is basically functioning and is fun.

Last week I posted about "Value", my animation blogging platform. This week I have something that can be tested. I might wipe the database in a future version so if you want to keep anything you make, save it locally. There's a lot of stuff that I'm likely to change with it going forward.

Value Alpha Demo

Decided to solve a thing I run into when I want to turn pixel mockups into real designs. Still working on final UI but basic concept works: drag a rectangle around the thing you want to make a bounding box for, then an algorithm auto-crops it. I will add some tools to adjust the result and some ability to adjust the tolerance. It'll output CSV or JSON.


I started implementing UI. I went through a few paper iterations to figure out a good UX strategy. Maybe the app will be complete-ish next week?

I'll be able to release a Windows build within the coming days, hopefully by Thursday so there's some time to test it before Ludum Dare. I still need to do some documentation though, especially for the project file format.

I actually did this earlier in this week, but it's ready now. Windows only. May try testing for other platforms soon.

http://triplefox.itch.io/pixelbound

Just did some paper design this week, tried to get some interest checks going. It's going to be a "voxel level editor", probably using a mix of heightmap, tiling, and scene hierarchy techniques. Pipeline will be scriptable in some fashion to export to a variety of things.

My thoughts about the voxel mapper shifted around towards unifying all my tools projects. Will it be implemented? We'll see! It should all be within an order-of-magnitude of possibility, though - just a matter of development time.


VX-32: fantasy console/engine, in the spirit of PICO-8, but designed more around pushing modern hardware with brute-force, easy-to-use techniques and an extremely integrated toolchain with a large number of presets. Hard limits aren't the focus, but we're aiming for 4-8 megabyte ROMs.

Desktop toolchain - we have a "ROM builder" that functions as an IDE. Open-protocol service to automatically store, share, synchronize games - accounts, registration, etc. This is not a web or mobile-focused project, so it'll use native code. Language not yet settled.

Rendering: stb_voxel_render.h as the basis, in mode 0 or mode 1. Fez-like 8x8x8 "trile" system used as the building block for maps; texturing and vheight also applied to lend additional shape and detail to trilemaps. Tools build around trile system. Goal is something like the uniformity and low memory consumption of graphics data on NES et al., just with additional dimensions. Detailed, smaller, static maps rather than rote emulation of big Minecraft landscapes and malleability. Voxel sprites, effects rendered as additional trile passes - rotation and alignment is freeform. Particles? Sprites? TBD

Ampliscape becomes the canonical sound engine: Reformulation from "game-like" tool into a more fully-formed DAW-like environment. Synthesizer redesigned around a flexible sampler system "Amplisynth". 64 voices assignable to 16 stereo mixgroups - voice allocation is automated. 16/48khz sample playback with panning, loop points and release. one multi-mode VA filter per voice. (Same filter I currently have in Ampliscape's synth.) 8-stage envelopes with loops. some undetermined FX chain per mixgroup. Ampliscape acts as the toolchain to generate sequences, apply procedural effects, trigger sounds, etc.

Built-in ROM containing default textures, triles, and sound samples, including an ASCII font, character and environment art, various bread-and-butter sounds and synth patches. Goal is never to feel reliant on importing data from elsewhere in order to finish a project and to have a distinctive base aesthetic.

Scripting -TBD.

Scripting focus for actual game code - to be "virtual console" like it shouldn't be necessary to dig into the engine, although some method of escaping and taking control of the engine and toolchain will exist for the brave and foolish. Entity management, collision data, camera, etc. - built in but designed for scripting control.

Target for higher-level game tools - e.g. walkthrough sim maker, shmup maker, etc.

All I really did this past week was try to get started with the D language, which, after having exhausted other shiny new options, I decided on for my native code projects:

  • Fixes the biggest issues of C++ as an applications language, but maintains a similar level of control and compatibility
  • Relatively mature - several generations of tooling and libraries, mistakes have been learnt
  • More than one implementation - low "bus factors" at this point

This isn't actually my first time trying out D, but the previous time I was still in high school, I think, and did not really have the background to do anything useful(plus it was a much less mature environment). What I remember about that experience was bitterly arguing with my older brother about whether we should include a "z" variable on a 2D sprite because it "might" be needed.

I managed to succeed in compiling a demo for the gfm framework/library collection, and made a binding for stb_voxel_render.h, but realized that I was a bit overwhelmed trying to dealing with a new language and a new API at the same time, so I will put getting cubes onscreen on hold for a little while in favor of porting some of my synthesizer code.

This week I reproduced a memory allocation strategy for audio buffers that I had previously made in Haxe - this time in D, making use of lower level constructs. It block-allocates buffers of variable sizes, with reference counting and some padding. It is not optimal on memory usage, but instead focuses on having all the processing data in one contiguous array for cache-friendliness purposes. The buffers may optionally describe an algorithm of "integer type and 16 floats and 16 ints as parameters." You can associate blocks into an entity and have the entity describe a list of blocks as a sequential program of "algorithm 1", "algorithm 2", etc. It's designed for very loosely defined usage - algorithms might be sharing a single buffer, copying between them, etc. The unit tests work, and I also got SDL audio output working with a sine wave test, so once I have some graphics rendering working and the buffers actually doing functional work, I will feel a little more confident about it.

This week will probably be about 2D graphics. I need a visualizer, and I'm feeling inspired to support sprites and text, at least at a basic level.

I guess I'm coding an engine at this point. This wasn't what I thought I was going to do when I started, but it actually lets me make the tooling all work together in a seamless design, which is Important To Me because it adds a lot of value.

I didn't end up doing graphics. Instead I figured out what the oscillators on VX-1's synthesizer, "AUD1", will behave like. The problem is that I wanted to have weird, colorful oscillators that may alias a lot - dropout distortions like the Atari 8-bits, chaotic functions, etc. - and so I can't just assume the input signal is good and work with it directly.

So I worked on making a cleanup strategy for naive oscillators that makes some compromises between anti-aliasing, high frequency preservation, and processing time.

For each output sample, I do this 4x:

1.5x oversample the original function with (osc(z) + osc(z + 0.5)) * 0.5

(This is actually a tricky simplification of using a "real" FIR filter kernel which relies on most of the terms cancelling out at the midpoint)

Run the resulting sample into my old IIR filter design, using the same 1.5x oversampling trick with (last filter input + this filter input) * 0.5. The IIR maxes out at samplerate / 2.5, which gives some additional headroom beneath the Nyquist frequency. Cutoff control of some kind will exist, possibly chained to amplitude control.

Output the final low-passed sample of the IIR.

It still aliases, you can hear it alias in the attached demo in the upper ranges. But the bulk of the signal is clear enough, which is what I'm aiming for, and while heavier oversampling improves it, the 4x/1.5x/1.5x strategy is "good enough" to work in a mix, especially as the filter cutoff dips lower.



The plan as of right now is to take this design, build 16 oscillator types around it(primitive functions, various noise/distortions, some fun/interesting stuff), a reverb and delay effect, and then some simplified amplitude and filter control. A key design goal is that the "knobs" on this have low granularity everywhere - there are exactly 256 pitches available, 16 volume steps, etc. It's inspired from early 80's chip sounds, but then will add things that give it optional shimmer and polish and make it a chameleon of an instrument.


I might even add some kind of lo-fi PCM.

test.wav10mb
1 download

And I realized that I don't need to write my own allocator to do what I'm planning. Yet.

(Still working on synthesizer-related stuff)

I've been distracted with job interview-related stuff but am still building up the synth and making some design changes. I decided that because I've succeeded in making naive oscillators acceptably anti-aliased, I could also use a customizable wavetable as the oscillator engine, rather than fixed-function oscillators. The wavetable implementation(right now) has a 7-bit depth, 16 steps, and can toggle linear interpolation per step. This means an exact reproduction of the naive sawtooth, square, triangle, etc. are possible, but also many more original timbres and dynamic timbres. When I first started with the synth concept I thought that I would have a lot of fixed-function choices, but this path still keeps things simple while adding a lot of flexibility. I thought of adding waveshaping, but it's also not necessary if the wavetable itself can be customized to this degree.

I still have to resolve how I'm doing the noise/distortion tones, finish a "real" implementation that integrates everything into a usable form for real-time, and do tests on the other parameters and see what ranges and resolutions work well(filter modes and parameter resolution is a kind of big topic). And then add some effects, if my resolve on that holds(reverb probably no, delay probably yes).

In conclusion, it's coming along, and then I will proceed to work on the rendering of TV-GAME.

I got in two good sessions in the past two days - cleaned up performance, fussed with the anti-aliasing methods a little more while I was at it(it's simpler now, maybe less distorting but also more obviously artifacted), got the noise working, got volume smoothing in for those that need smooth/fast envelopes, and added some filter controls.

After some more testing I can try adding the delay and making a sound engine on top of this.