How to get started with Mini Micro

From MiniScript Wiki
Revision as of 14:06, 19 December 2024 by JoeStrout (talk | contribs) (→‎Create a sprite)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Mini Micro is a popular environment for creating 2D games and demos in MiniScript. It is a retro-style virtual computer, which runs on most desktop platforms. Mini Micro games can be packaged as stand-alone games for desktop or the web.

This page is meant for people who have never used Mini Micro before, but want to make a Mini Micro game. It is a step-by-step guide to building your first simple demo involving a sprite, game input, and sound effects, including your own resources, as quickly as possible.

Get Mini Micro

While you can run Mini Micro on the web, the web version has no ability to save files (nor does it support copy/paste). So it's not useful for developing your own Mini Micro games.

Go to the Mini Micro download page, click the button for your platform (Mac, Windows, or Linux), and save the resulting file to your local machine. (If you don't have a Mac, Windows, or Linux desktop machine, then unfortunately you can't use Mini Micro yet, though iOS and Android versions are under development.)

The downloaded file will be a .zip (Mac/Windows) or .tar.gz (Linux) file. Unpack this file completely. Don't try to run Mini Micro from within the archive; extract all files to a real folder on your hard drive.

Then, find the Mini Micro application in that folder. Double-click it to launch Mini Micro. The result should look like this.

MiniMicro.png

Mount a folder as /usr

Mini Micro can access two virtual "disks" at once; within the Mini Micro environment, these are accessed as /usr and /usr2. Each of these can be either a .minidisk file, or a real folder on the host (desktop) system. Out of the box, Mini Micro creates an empty .minidisk file for you, to keep things nice and neat. But for any serious development, you're going to want to mount a real folder instead, so that you can easily move files in and out of this folder, use your favorite external image/sound editors, etc.

Create a folder on your desktop system, wherever you normally keep your documents. This will be your project folder for your first Mini Micro game. Put a small text file, image (in PNG or JPEG format), or sound file (in WAV or OGG format) in there. Our goal now is to see and view this file (and any others in that folder or its subfolders) in Mini Micro.

Method 1: Use the disk slot menu

Those two thin dark rectangles in the bottom-left corner of the Mini Micro window are "disk slots." The top slot represents /usr, and the bottom slot represents /usr2. Click the top slot to pop open the menu, and select the "Mount Folder..." command.

MountFolder.png

Selecting that command should bring up the native file dialog for your platform, allowing you to select any folder you have access to. Pick the project folder you created above. (Note: some Linux platforms have a bug which crashes Mini Micro at this point; if that happens to you, go on to Method 2.)

Now, in the Mini Micro display, at the blinking orange prompt, type:

dir

and press Return or Enter. You should see your file listed. Now try:

view "myfile.txt"

but replace myfile.txt with the name of whatever file you placed in your project folder. Be sure to include the quotation marks; you're typing MiniScript code here, not some other shell language, so string literals always need to be surrounded by double quotes. If you do it correctly, the contents of your text file or image should appear on the screen.

(You could also do view findFile, which would pop up the little file browser within the findFile command, and select your file that way.)

Note that the currently mounted disk is saved in preferences, so if you quit and relaunch Mini Micro, you generally won't need to do this step again; the previously mounted disks will still be there.

Method 2: Use command-line arguments

If you are unfortunate enough to hit that Linux bug which causes the file dialogs to crash, or for some other reason you want to launch Mini Micro from the command line (or a shell script) with the correct folder already mounted, then you can use command-line arguments instead. Open your favorite terminal program, and navigate to where the Mini Micro executable is located. The details vary by platform, so let's break it down:

Linux

In Linux, the executable is called MiniMicro.x86_64, so you would type a command like this:

./MiniMicro.x86_64 -usr ~/mmdev

Replace ~/mmdev with the path to your project folder.

Windows

In Windows, you can open the command prompt by pressing Win + R to open the Run dialog, and entering cmd. (If you already have some other preferred terminal app, like PowerShell, that's fine too.) Then cd to the directory containing Mini Micro. The executable here is called Mini Micro.exe, so you would use a command like:

"Mini Micro.exe" -usr "%HOMEPATH%\mmdev

Replace %HOMEPATH%\mmdev with the path to your project folder.

MacOS

On Mac, the actual executable is hidden inside the application bundle, specifically under Contents/MacOS. So if you've already launched Terminal and navigated to where MiniMicro.app is found, then you would do

Contents/MacOS/Mini\ Micro -usr ~/Documents/mmdev

Replace ~/Documents/mmdev with the path to your project folder.

If successful (on any platform), you should be able to use the dir and view commands to view the file in your project folder within the Mini Micro environment.

Create a sprite

Now let's get a sprite up on the screen. We're going to do this using the Mini Micro command line (or REPL), where you type a command and executes immediately. We'll get to writing real programs later, but the command-line is a powerful tool for learning and exploring, so let's use it.

1. Make a sprite from the built-in images

At the orange blinking-cursor prompt in Mini Micro, carefully type the following:

clear
sp = new Sprite
sp.image = file.loadImage("/sys/pics/Wumpus.png")
display(4).sprites.push sp

You should see a furry purple Wumpus peeking out from the lower-left corner of the screen (which is the origin of Mini Micro's coordinate system).

ManualSprite.png

If you don't see this, go back and double-check your typing. Note that you can recall a previous command on the command line by pressing the up-arrow key, then just edit it and press Return to run the edited command.

How does this work? Let's break it down:

  1. clear clears the screen and resets all eight display layers to their default states. This includes setting display 4 to be a SpriteDisplay. (That's the default state when Mini Micro boots, but useful whenever your screen is cluttered anyway.)
  2. sp = new Sprite creates a new Sprite object, and assigns it to a variable called sp.
  3. sp.image = file.loadImage("/sys/pics/Wumpus.png") loads an image called "Wumpus.png" from the /sys/pics directory. (Notice that Mini Micro uses forward-slashes in file paths, even if the host system is Windows.)
  4. display(4).sprites.push sp pushes this new sprite onto the sprite list of display 4, so it can be seen.

Once you have the Wumpus peeking out of the corner, let's move it and rotate it a bit. Notice how the sprite updates immediately after each command.

sp.x = 480
sp.y = 320
sp.rotation = 45

2. Make a sprite from your own custom image

The Wumpus sprite above was created from one of the built-in images that comes with Mini Micro. There are hundreds of these, stored on a hidden, read-only disk mounted as /sys. Feel free to use the findFile command to explore what's there.

But for your own game, you're probably going to want to use your own custom sprites. So, put an image in PNG format into your project directory (the one you mounted as /usr). Use the pwd (print working directory) and cd (change directory) commands to be sure you are in your /usr directory. Then use the dir and view commands to ensure that you can see and load your user file.

Now, just repeat the commands you did to create a sprite above, but substitute the path to your custom image.

sp = new Sprite
sp.image = file.loadImage("myCustomImage.png")
display(4).sprites.push sp

If you haven't cleared the display since step 1, then you'll see your new sprite and the Wumpus on screen at the same time. And if you now move (by assigning to .x and .y) your sprites so that they overlap, you'll see that your new sprite is drawn on top of the older one. That's because sprites are drawn in the order in which they appear in the sprites list of the SpriteDisplay.

3. Extract an image from a sprite sheet

Often you have multiple sprite images arranged in one bigger image file, called a sprite sheet or sprite atlas. You can pull apart such a sprite sheet by using the Image.getImage function. Let's try:

enemies = file.loadImage("/sys/pics/Enemies.png")
view enemies

This loads and displays this big image, which contains a number of platformer enemies, in a 128x128 pixel grid. Let's make a sprite out of the top-left image. Keep in mind that coordinates in Mini Micro go from the bottom-left corner, so that top image starts at 128 * 3 = 384.

goob = new Sprite
goob.image = enemies.getImage(0, 384, 128, 128)
display(4).sprites.push goob

This creates a new sprite called goob, assigns it an image from our enemies sprite sheet, and pushes it onto the display. As always, it starts out in the bottom-left corner, but you know how to adjust that by now. Since this sprite is a bit bigger than it probably needs to be, also try goob.scale = 0.5 to shrink it down.

Play a sound

Almost any game needs sound effects! Mini Micro supports both playing both digitized sounds loaded from a file, and sounds synthesized at runtime. We'll focus here on playing sounds from a file, which can be in either WAV or OGG format.

1. Play one of the built-in sounds

Enter clear to clear the screen, then try this:

snd = file.loadSound("/sys/sounds/twinkle.wav")
snd.play

You should hear a twinkle sound. The Sound.play method supports several optional parameters. A handy trick when you need a quick reminder of function parameters is to use @ (the at-sign) before a function reference, to return the function without invoking it. On the command line, that will print the function parameter names and default values. Try it:

@snd.play

which prints:

FUNCTION(self, volume=1, pan=0, speed=1)

So let's try some variations on the sound. (In the code below, we're using // to add a comment on each line; you don't have to type these, but you can if you like.)

snd.play 0.1   // play very quietly
snd.play 1, -1     // play out the left speaker only
snd.play 1, 0, 2   // play twice as fast (an octave higher)
snd.play 1, 0, 0.5 // play half as fast (an octave lower)

2. Play your own custom sound

Put a sound file in WAV or OGG format into your project folder. (On some platforms you can also use MP3 format, but that doesn't work everywhere and so is best to avoid if you plan to distribute your game.) Let's suppose your file is called "bgm.ogg". Load and play it just as above:

snd2 = file.loadSound("bgm.ogg")
snd2.play

If your sound is very long, and you want to stop it, you can just do snd2.stop. Or you can use Sound.stopAll to stop all sounds.

Before we move on, let's make this sound loop forever, as you might want background music to do:

snd2.loop = true
snd2.play

Again, use snd2.stop to make it stop, or Sound.stopAll to stop all sounds. (The reset command will also do that, in addition to clearing the current program and variables.)

3. About synthesized sounds

Mini Micro has a sophisticated API for creating sounds out of nothing but code. You can specify a base waveform, frequency, envelope, fade-in/fade-out, and even mix basic sounds together to create more sophisticated sounds. You can find a couple of simple examples on the Sound.init page, and some more complex ones by doing run "/sys/lib/sounds" (followed by edit to see how those examples were made).

Write a program

Typing commands directly on the command line is a great way to learn, explore, and test things out. But to write more than a few lines, you'll want to use a code editor. Assuming you've mounted a folder (rather than a minidisk file), you have two options: the built-in code editor, or an external code editor.

Method 1: Use the built-in code editor

The Mini Micro code editor is invoked with the edit command. Just type edit by itself to edit the currently loaded program (or start a new program, if none is loaded). Or, you can add a filename argument, like edit "myGame", to load a different program and open the editor in one step.

Note that once a program is loaded, if you want to start a new program, use reset to clear the current program and variables.

The built-in code editor is full-featured and powerful, including auto-indenting, code snippets, a color picker for color constants, and a sophisticated find/replace dialog. See this page for usage details.

Method 2: Use an external code editor

When you have mounted a real folder as your /usr (or /usr2) disk, then you can edit MiniScript files therein using your favorite code editor, outside of Mini Micro. On the Tools page you can even find language models for editors like VS Code or BBEdit, to provide MiniScript-savvy syntax coloring.

When you edit code in this way, you will need to reload the program from disk in Mini Micro to see your changes. It's also generally a good idea to reset the environment before running the new code, so that old function definitions or other variable values don't inadvertently change the behavior. So after externally editing a script called "myGame.ms", do:

reset; run "myGame"

in Mini Micro. (And once you've done this once, you can generally just up-arrow to recall and repeat this command again the next time.)

A simple game demo

Using either method above, create a new MiniScript program called "ufo.ms", and paste in the following. (Or to learn even faster, retype it instead of using copy & paste.)

// prepare displays
clear
sd = display(4)  // sprite display

// prepare UFO sprite and other resources
ufo = new Sprite
ufo.image = file.loadImage("/sys/pics/UFO.png")
sd.sprites.push ufo
ufo.x = 480; ufo.y = 320

fireSound = file.loadSound("/sys/sounds/blam.wav")

// allow alternate "fire" buttons
fireButtons = ["space", "left shift", "right shift",
  "joystick button 0", "joystick button 1"]
firePressed = function
	for btn in fireButtons
		if key.pressed(btn) then return true
	end for
	return false
end function

// function to "fire" (play a sound)
fire = function
	fireSound.play
end function

// main loop
fireWasPressed = false
while true
	yield  // wait for next frame
	
	// move the UFO
	ufo.x += key.axis("Horizontal") * 20
	ufo.y += key.axis("Vertical") * 20
	
	// fire, when fire button goes down
	fireNowPressed = firePressed
	if fireNowPressed and not fireWasPressed then fire
	fireWasPressed = fireNowPressed
end while

This creates a simple game demo which allows you to move a UFO around the screen using the arrow keys, WASD, or a game controller (which all feed into key.axis). And when you press any of several keys (including joystick/gamepad button 0 or 1), it plays a sound.

Try changing the UFO sprite to your own custom sprite, and changing the fire sound to your own sound. That will verify that you're able to get your own assets working in Mini Micro in a custom game program. Then start playing around with the code. Some things to try:

  • Limit the sprite position so it can't go offscreen
  • Add some sort of target, as in /sys/demo/spriteDemo
  • Make the sprite drop/fire a second sprite when the fire button is pressed

Package your game for the web

If you've come here because you want to make a Mini Micro game for a game jam, then you should almost certainly learn how to package your game for playing on the web, and upload it to a site like itch.io.

This process is described in detail on How to package a Mini Micro game. Focus on the general instructions at the top, and the "packaging for the web" instructions at the bottom.

Where to learn more

Congratulations! You have learned how to set up a local Mini Micro environment for development, using your own game assets, and learned to use both the built-in and external code editors. You've made a very simple game demo, and know how to upload it to the web. All toolchain hurdles are behind you; now it's just a matter of designing a game, and writing the code!

If you are a Python or Lua programmer, see the Python or Lua page of this wiki to see how MiniScript compares to those.

When writing the code, you will probably lean most heavily on these resources:

  • The Mini Micro Cheat Sheet, a 4-page summary of the Mini Micro API and MiniScript language
  • This wiki, especially the How To articles
  • Sample code found in /sys/demo
  • Various blog posts, perhaps found through the Bibliography page

Most important of all, rely on the community Discord server, a link to which can be found at the bottom of the MiniScript home page. An active and friendly community hangs out on Discord, and you are encouraged to share screenshots, code snippets, and questions there.