The Super Jamicom imaginary console is patterned after the way 16 bit
consoles used to work back in the late 80s to mid 90s or what was commonly
referred to as the “16 bit era” †. This means a
relatively low resolution, paletted graphics and constrained sound.

In contrast to those old platforms though, Super Jamicom offers a much
simpler development experience, with a modern programing language,
a suite of built in tools and very low iteration time; The goal is to make
starting a collaborative game jam game as easy as clicking a link!

Super Jamicom improves from time to time. To keep up with the latest changes
visit the news page.

If you’re interested in exploring how the game works, you can
click the edit button to move to the game’s edit page. On this page,
you can read and modify the graphics and code that make up the game.

Unless you were the original creator of this game though, you will not
be able to save any changes you make. To really get started making
your own games, you’ll also need to
login
so that the system can save your data.

Once you’ve done so, choose a game from the main page
that most closely matches what you want to
do and then go to its edit page.

Once inside the editor you can “fork” the game, that is to say make a
copy of the game where you are the owner instead. You can now edit your
forked game without affecting the original.

To modify the information displayed under a game on its player page,
find the ‘edit this info’ button in the edit page of a game you own.

Here, you can modify the game’s title, give it a description, and
add additional authors to the project who will have the same ability
as you do to add new graphics and code to the game.

Super Jamicom games, and Super Jamicom itself, are written in a
language called CoffeeScript. CoffeeScript is an extension of
the Javascript language that runs in your web browser, and in fact
works by compiling itself back into Javascript. When you write
CoffeeScript for your games, in the background Super Jamicom does
the conversion for you.

The CoffeeScript Cookbook
is another useful resource, providing an advanced guide
and tips for programmers coming from different languages.

Should you make a mistake while coding (and who doesn’t!) then
errors will appear in the System Messages panel. These should tell you
the file name and the line and character numbers where the error
was detected, as well as what it thinks the error might be.

To work out errors in your logic, it’s often useful to observe some
crucial value as your game unfolds. The Watched Variables panel will
display any named value you pass it from your code using the
watch command. For example, if you have the variable
playerXPosition and you’d like to call it “player x”,
then invoke the watch command as so:

watch 'player x', playerXPosition

Each subsequent call to the watch command using the same name will
intentionally overwrite the same line in the Wached Variables panel,
letting you call watch repeatedly while only retaining the latest value.

Finally, for the deepest look at how your code is behaving, please see
your browser’s developer tools documentation†.
Super Jamicom publishes the information necessary for your browser to
’see’ the code files you write, enabling the full range of its
developer tools.

In order to address the game environment, Super Jamicom reserves the
global name game. This variable holds crucial state information
and is the only variable that is visible to the code across all of your files.
That is to say if you have files foo.coffee and bar.coffee, and you’d like
to share variable health between them, you’ll need to name the
variable game.health.

Advanced note: Accessing the game variable is so common,
that it is actually bound as the root context for each of your files.
This means that the CoffeeScript shortcut @ can be used to
refer to it when you are not in a function; e.g. @health.

There are two critical hooks to get to know when developing a Super Jamicom
game:

game.init

This function will be called when your game first starts up or is reset,
after every code file has been evaluated. This means that all your
classes and assorted globals will be ready to use at this point.
You should use this hook to create your game’s initial state, e.g. your
player’s starting position and health.

This function will be called after game.init as often as possible,
up to a maximum rate of 60 times per second.
Use this function to run your main game
logic, moving sprites around, detecting intersections, etc.

Most of the functions available in a normal Javascript environment
are present in Super Jamicom. In addition, due to common usage,
the following functions have all been lifted into the global namespace
from the Math namespace, allowing you to omit the prefix:
sin, cos, tan, abs, floor, ceil, round, random, min, max, pow, PI

For instance, you can type min(x, y) or sin(angle) rather than
Math.min(x,y) or Math.sin(angle)

Returns value, or min if value is less than min, or max if
value is greater than max.

lerp(min, max, fraction)

Returns an interpolated value between min and max, where a
fraction of 0 means min and a fraction of 1 means max.
When the value of fraction is less than min or greater than
max, linear extrapolation occurs.

There are two main components to the graphics system: sprites and
backgrounds. Think of sprites as smaller pieces of graphics that
move around independently, while a background is a larger, full screen
sized graphic.

Both sprites and backgrounds are made of characters. A character is
an 8 by 8 pixel square of pixels †.
Each pixel can have one of 16 colors.
Which 16 colors are applied to a sprite depend on its palette index.

A palette is a list of colors. A full palette has 256 colors, organized
into 16 rows of 16 colors each. A palette index refers to one of these rows.

The Super Jamicom screen is a 256 by 224 pixel surface which can
display up to 4 backgrounds and up to 128 sprites.
Positions on screen are specified in terms of the pixel distance from the lower
left corner of the screen, in whole pixels. For example the position (4,6)
means 4 pixels from the left of the screen and 6 pixels from the bottom.

There are a fixed number of 128 sprites. Each sprite can be enabled and
positioned independently on the screen.

To setup a sprite, adjust the values in the global sprites array.
Here’s an example:

sprites[0].on = true
sprites[0].x = 10
sprites[0].y = 40

This turns on and then positions the 0-th sprite (the first sprite in the
system) such that its bottom left corner will be 10 pixels from the left
of the screen, and 40 pixels from the bottom.

Here’s the full list of properties that a sprite understands. Because these
are so very common in a Super Jamicom codebase, the parameter names have
been severely abbreviated.

sprite.on

This controls whether the sprite will (true) or won’t (false) be
displayed on the screen.

sprite.x

The x position, that is to say the distance in pixels
from the left edge of the screen

sprite.y

The y position, so the distance from the bottom of the screen
Note: both sprite.x and sprite.y refer to the position of the
bottom left hand corner of the sprite. So an x of 0 and a y of 0
would mean that the sprite’s left and bottom boundaries would
be exactly up against the left and bottom boundaries of the screen.
Try it out!

sprite.w & sprite.h

The width and height of the sprite in characters, that is to say
in multiples of 8 pixels. A sprite with w = 2 would be 16 pixels wide.

sprite.cx & sprite.cy

The offset, in characters, of the sprite source in its character sheet.
In contrast to the x and y positions, this offset is from the top left
instead. So the top left most character on a sheet is cx 0 and cy 0.
The best way to discover these values is to hover over the Sprite Editor
panel and read the output in its title bar.

sprite.fx & sprite.fy

These control flipping, horizontally and vertically respectfully.
Each should be set the value 1 for a flip, and 0 for no flip. A flipped
sprite occupies the same space as an unflipped sprite; that is to say
that the sprite is always flipped across its center.

sprite.pi

“Palette Index” This controls which row of the current palette
the sprite will draw its colors from.
You can change this at any time to quickly recolor
the whole sprite.

sprite.po

“Palette Offset” This is a numerical shift offset applied to the
palette index, letting you easily setup the most common style of
palette based animation.
Palette indexes wrap on a single row, so increasing this value
will shift colors on the right around to the left side.

Like the sprites, backgrounds are composed of characters which
can be flipped horizontally and vertically.
Entire backgrounds as a whole can also be positioned on the screen,
allowing for scrolling effects.

Unlike sprites, the characters used by a background don’t have to be next
to each other on the character sheet. To work out which character goes where,
you create and assign a map object: a rectangular array of information that
encodes for each character on the map, where to get the data from the
character sheet and how to flip it. See the Maps topic below for more
information about programming with maps, and read about the Map Editor for the easiest way to set one up.

Backgrounds can wrap, meaning that if you move
a background to the right, instead of being blank, the area further to the
left of the leftmost edge of a background will look like a copy of the far right
side of the background instead.

To setup a background, adjust the values in the backgrounds array.
Here’s an example:

This turns on the first background in the system, and sets it to read
from the ‘forest’ map, using the colors in the ‘daylight’ palette. It
then sets it to draw 20 pixels from the left of the screen, and to
wrap horizontally, meaning that the left most 20 pixel column of the
screen will actually show the right most characters in the ‘forest’ map.

background.on

This controls whether the background will (true) or won’t (false) be
displayed on the screen.

background.x & background.y

Offset the position of the background on the screen.

background.map

This it he name of the map you want this background to use.

background.palette

This is the name of the palette you want this background to use.

background.paletteRowOffset & background.paletteRowOffset

These values let you offset the palette index for every pixel in the
background. Use this to create large palette animation.

background.transparency

Whether the first color of the background should be considered transparent
or solid.

background.wrapX & background.wrapY

Whether the background should wrap around horizontally and vertically

background.pr

“Priority”. Determines the order that the background will draw in,
compared to the rest of the sprites and backgrounds in the system.
See the Priorities and Sorting topic below for more info.

A map contains the information a background uses to choose
which characters go where on screen.

While the easiest way to create a map is to use the map editor,
there are plenty of interesting uses for creating and modifying
maps from code.

To begin working with a map, fetch it from the map system with the
command ‘mapSystem.getByName(YourMapName)’.

Once you have one, working with maps involves calling functions
on the map object.

map.setDimensions: (width, height, options)

This lets you change the size of a map. A map can only be up to
1024 character in width and height, and must be at least 16
characters wide and tall.
Specify the width and height in
characters.
This function gives you some options with regards to what to
do with the data that was in the map before the resize.

map.set(x, y, cx, cy, flips)

Sets which character should be used at offset x and y, where
x and y are given in whole characters from the top left of the
map.
The cx and cy values work like the same named properties on sprites,
representing offsets in the character sheet.
The flip value is a specially encoded set of numbers meaning:

value

action

0:

do not flip the character

1:

flip the character horizontally

2:

flip the character vertically

3:

flip both horizontally and vertically

map.get(x, y)

This will return the cx, cy and flips values for the character
at the given x and y offset in the map. The result is given in
the form of an array as so [cx, cy, flips].

By default, all backgrounds draw before all sprites.
There are 8 levels of priority in the rendering system that allow you to
influence this ordering.

By default all sprites and backgrounds have a
priority of 0. Increasing this number causes the item to be rendered later.

Backgrounds in the background system that have the same priority
draw in their index order, i.e. backgrounds[0] draws before backgrounds[1].
Likewise, sprites[0] draws before sprites[1].

So, let’s say you want to draw your level backdrop in backgrounds[0],
then your player character sprites[0], then a user interface in background[1] on
top of that; you could to set your priorities as follows:

Each palette contains 16 rows of 16 colors each. Recall that a sprite
or a background can be set to use any color within a single row of
a palette.

To create a new palette, click the ‘add palette’ button in the palette
list to the left of the editor. All you need to specify at this time
is the name for the new palette.

To modify a color in a palette, click on the relevant color swatch and
use the sliders on the right side of the editor to modify the amounts
of red, green and blue in the color.

Notice that moving your cursor across the palette updates the display
in the editor title bar that identifies the row and column of the
color you’re hovering over. When writing code to modify palettes
dynamically, this is the easiest way to get your bearings.

When a pixel value is rendered to the screen later, it will used as
an index into a palette, which converts it into a full RGB color.

Each character sheet is 32 characters wide and 32 characters tall.

The editor displays the entire current character sheet using a single palette.
Use the row arrows at the bottom of the palette strip to switch to another
palette row.

Of the 16 possible values, one is always the selected value, and one is always
the alternate. To change the current selected value, click on it in the palette
strip. To change the alternate value, hold down the alt key while clicking
on a value, or click it with the right mouse button.

To see other parts of the character sheet, use the following controls:

Shift + click & drag or middle click & drag

moves the view around the sheet

Mouse wheel

zooms the view

Use the toolbar to select one of the following tools:

1 pixel brush

fill a single pixel with the currently selected value when you left click
on the sheet.
Hold down the alt key or use the right mouse button
to fill a pixel with the alternate value instead.

2 pixel brush

fill a 2x2 area of pixels with the currently selected value, or with the
alt key (or right mouse button) held, the alternate value.

Selector

left click and drag on the sheet to create a selection.

Once you have an active selection, you can use the arrow keys on the
keyboard to shift the pixels inside the selection.

Clone brush

you must already have created a selection to use this tool. Once you
have set it up, left clicking on the sheet will copy the contents of the
selection there.

Super Jamicom supports a fixed set of inputs, normally mapped to the
keyboard. You access these inputs using the buttons global variable
which contains a set of named booleans that are true when the button is
currently pressed.

For example, to move the player when the up button is pressed

if buttons.up
player.y += 1

buttons.up, buttons.down, buttons.left, buttons.right

These map to the directional arrow keys on the keyboard

buttons.a, buttons.b

The primary two buttons, these map to the keys Z and X.

buttons.x, buttons.y

The secondary buttons, these map to A and S

buttons.l, buttons.r

The extended buttons, these map to Q and W

buttons.select, buttons.start

These are mapped to the keys 1 and 2, usually used for invoking in‑game menus

The global debug object contains a system for plotting visual information
on the screen.
You could use this, for example, when you’re trying to work out if your
collision or movement code is correct.

All draw functions happen after the game render, so will always be on top
of every thing else the system draws.

Note: This system is disabled in the game player, so it isn’t available
for general game drawing! It is safe however, to leave your debug calls
in the code; the player will just ignore them.

debug.color( r, g, b )

This function sets components of the color for all subsequent debug draw
functions to the given red, green and blue, r, g, b values.
All values are in the range 0 to 255

debug.box( x, y, w, h )

Draws a box with the given x, y position, and the given height h and
width w.
All values are in pixels from the bottom left of the screen.

debug.boxOutline( x, y, w, h )

The same as debug.box, but instead of filling the area, it draws a single
pixel outline instead.

debug.circle( x, y, r )

Draws a circle instead, centered at x, y, with the radius r. Radius also
given in pixels.

debug.circleOutline( x, y, r )

The same as debug.circle, but as a single pixel outline instead

debug.line( x1, y1, x2, y2 )

Draws a single pixel line between the coordinates x1, y1 and x2, y2

debug.pixel( x, y )

Draws a single pixel at the given coordinate

So, let’s say you have some logic where you have a position x, y that will
chase a target tx, ty. It might be helpful to draw the current point and
target points as red dots, and to draw a green line between them.

Additionally, the print command can also be useful. This function draws
text to the screen at a given position, or sequentially from top to bottom.
Unlike the debug functions, the print function is still available in the player
page.

print( text )

draws the given text. The first call of this kind every frame will draw
the text at the top left of the screen. Subsequent calls will draw the
text beneath the previous line.

print( text, x, y )

when x and y coordinates are specified, then the text is drawn with the
bottom left corner of the text explicitly sitting at the given coordinates.