Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

(WIP) Tiny Machine 16: Fantasy Computer

A topic by GlaireDaggers created Sep 17, 2020 Views: 412 Replies: 2
Viewing posts 1 to 3
(1 edit)

Hello, all!

I’m currently working on a new fantasy computer in a similar vein as offerings like Pico-8 or TIC-80. TM-16 is inspired by PCs of the mid to late 80s. It uses Wren as the scripting language and features a 64-color palette inspired by the EGA 6-bit RGB gamut, a unique MIDI-capable synthesizer, 8khz PCM sound effects, and support for keyboard, mouse, and joystick input.

Some screenshots (the code editor, the art tool, and a built-in sample game that comes with it):

Up until now I’ve probably spent a few months working on this. The VM itself is functionally complete, so I’m now nailing down the last few bugs, working on the online documentation, and giving some thought to how distribution will work (the goal is to allow people to distribute self-contained executables of their game on sites like Itch.IO or Steam, in addition to the shareable virtual disk files, so I’m still trying to nail down precisely how this should work).

I’ve been tweeting some stuff over at @TinyMachine16, and I also have the beginnings of a site up at https://www.allieinteractive.io/ with the current WIP documentation (note that purchase badge & forum links are currently busted, and docs are still under construction).

Anyway, I would love to talk more about it, gain some initial impressions & feedback, etc! My hope is that it won’t be too much longer until I can actually release it into the wild.

So I’ve been giving some thought as to how I would approach allowing people to bundle their games up as self-contained executables for sale/distribution. Would like to share my thoughts on this.

One idea I had was to simply ship a “redistributable” version of TM-16, where you’d just throw in your game, modify a skeleton script to boot your game instead of the shell, and then modify the EXE itself (adding a new icon, etc). For a couple of reasons, though, I don’t really like that idea. It seems a little messy.

The other idea I’ve had was to turn the VM into an embeddable library. This is also a bit of a challenge. Thing is, the core VM save for a couple of native dependencies is written in D. I could make it be a D library: a simple D container could consume this without a whole lot of effort, but other containers (like C/C++/Rust) would have a little more trouble as they would also have to worry about embedding and initializing the D runtime libraries.

I’m kind of leaning towards the latter, but wonder if anyone else has opinions on how this should work.

(3 edits)

So…. here’s something really interesting. I don’t yet know exactly how useful this would end up being, but I thought I would share anyway.

There’s an open source project over at https://github.com/shinh/elvm which aims to be a C11 compiler for various esoteric languages, but what caught my eye was that it had JS and Lua backends in the source code. After some skimming, I realized it might be possible to make a Wren backend. It turns out not only was it possible, it was actually incredibly easy. So over the span of today, I got a simple C program compiling and running right inside of TM-16. It took some extra modification but I even got it to be able to call into external code (it’s kind of a huge hack, but it works).

Effectively it produces code that looks very similar to asm.js. It’s all pure Wren, but it takes a stdlib interface, a foreign function interface, and an array of numbers representing the “heap” as input, and performs a variety of low-level operations entirely on that heap array. The way I’ve implemented the backend, it even exposes all defined C functions and lets you call them with an arbitrary argument array, get a return value, that code can call into yours via the foreign function interface, etc.

Interfacing with it looks something like this:

import "kernel" for Shell
import "stdlib.wren" for Stdlib
import "test.asm.wren" for Module

class Program {
	construct new() {
	}
	
	main(args) {
		_heap = List.filled(1 << 24, 0)
		_module_test = Module.new(Stdlib, Stdlib, _heap) // at the moment, the first object is expected to define "putchar" and "getchar", and the second object is expected to define all of the external functions the C code is allowed to invoke
		
		Shell.printLn("Native module initialized!")
		
		var retVal = _module_test.main([]) // all functions return a single number. This can either be a simple atomic value such as a number, or it could be a pointer in which case it is an index into the heap array
		
		Shell.printLn("Result: %(retVal)") // in my simple test case it simply returned 100.
	}
}

What I’m debating on is whether it would be worth the effort to define a full enough stdlib interface that I could compile this compiler itself, and perhaps ship it with TM-16 as an optional C compiler. Is that something people might want?

EDIT: FWIW, C code compiled to Wren seems to run faster for reasons that are currently beyond my comprehension. A 1000 iteration C fibonnaci sequence runs about twice as fast as a hand-written Wren equivalent. I have no idea why that is, but it’s pretty cool nonetheless.