Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics

Internet Janitor

A member registered Aug 02, 2018 · View creator page →

Creator of

Recent community posts

Cool stuff! It's wonderful to see programs that recreate the visual style of Hypercard.

I recently built my own 1-bit drawing program, and only later discovered Strike- maybe Ditherpaint could have some inspirational ideas? I use the same internal model of "patterns as colors", but allow users to edit the patterns and create sequences of those patterns to cycle through, as a limited form of animation.

(1 edit)

You seem to be unclear on what "pixels" are, so I will try to explain. I apologize in advance if this seems in any way condescending.

The Nokia 3310 has a display consisting of a uniform grid of squares. The grid has 84 columns and 48 rows. At any given time, each square can be either a dark or a light color. It is not possible to have "half" of one of these squares illuminated; all graphics (including text!) must be drawn using these pixels as the minimum element of granularity.

Your game displays many objects at varying sizes which are not even multiples of a pixel size which divides your display into an 84x48 resolution. Objects move smoothly at "sub-pixel" intervals. Text is often scaled or animated in fine gradations which are not multiples of pixels and use anti-aliasing to smooth their edges. The background border of levels uses very finely-spaced lines which in practice appear as a different color from the proscribed 2-color palette. Even the introductory sequence of the game uses additional colors (black and white) beyond the palette constraints.

I hope this has helped clarify why your game has received criticism with respect to its adherence to the jam's aesthetic constraints.

This was a very interesting concept for a narrative game. For the most part, puzzles were logical and easy to trace out.

I actually had the most trouble with the initial PIN. I assumed that the hint was suggesting some permutation of day/month/year for the birthday instead of just the four-digit year. Not sure how to prevent overthinking on that one. If you want to make it more forgiving perhaps you could make the game quietly accept a few alternative solutions?

While I get that the battery level mechanic was included to incorporate the jam theme, I felt it was mainly a source of frustration when trying to explore the contents of the phone thoroughly.

(1 edit)

Generally a nice-looking and well-executed game.

I did feel that the text speed of dialogue was excessively slow, and would have liked space to advance to the end of pages of dialog instead of skipping unfinished paragraphs entirely. Simple changes to this UI would have made the plot more enjoyable.

In gameplay, I rarely felt that there was any reason not to hold down fire continuously. A charged shot, a limit on projectiles in the air, an ammo limit, or any number of other mechanics could make firing something that benefitted from careful timing.

This is really great!

Graphics, gameplay, and the control scheme are all clear and simple. I can can easily tell what's going on, and the game strikes a nice balance and pace. This submission really is the total package, and I could see myself enjoying this on a real phone.

Controls are laid out reasonably, all the animations look nice, and everything appears to faithfully adhere to the jam restrictions.

That said, I am completely baffled by the gameplay. Choosing a square appears to show a different random animation every time. This doesn't behave like the normal "match-two" memory games I am familiar with, and the game does not clearly explain how these animations are connected to anything.

The core mechanic is potentially interesting, but as others have pointed out this isn't remotely attempting to conform to the creative constraints of the jam.

The mechanic is an interesting use of the theme, but the control scheme is really awkward. I feel like I need an extra hand to play this. Why not go for something like arrows for movement and Z/X to jump/switch?

The audio was interesting and atmospheric.

I didn't feel like there was much to do in the game, though. Movement is very slow, and the environment is barren. I don't get the sense that there's much to find as I plod around in a featureless maze.

I never had any difficulty finding enough batteries, so the time limit didn't produce any tension.

There's some great pixel art and animation here! Level design is reasonably varied and interesting.

One thing that mars the presentation a bit is that (at least for me) the web build has blurred the upscaled display instead of using nearest-neighbor.

(1 edit)

This game doesn't adhere at all to the jam's 84x48 pixel resolution constraints- pixel art is nonuniformly scaled and anti-aliased, objects are moved smoothly at "sub-pixels", and text and background graphics are much too detailed.

The control scheme is intuitive. Gameplay seems very repetitive and simple. If the enemies escalate in difficulty, the ramp-up is far too slow to be noticeable.

Sound would have been a nice addition.

I like the visuals in this game- the atmospheric particle effect is particularly nice. The player sprite and game tiles all read clearly.

The music gets grating rather quickly. It might have been better to focus on sound effects giving feedback from the player's movements instead of music.

I think you have a typo in the description of the controls on your jam page.

This game looks great- visuals read well, and there's a lot of subtle attention to detail!

I'm not as sold on the gameplay. Controls feel very sluggish and unresponsive; while this may be somewhat intentional to make the input "weighty", I didn't enjoy it very much. It seems like I lose when I fail to stack a block on a previous one, but there isn't much feedback to failure- it seems like the block slips, and then a few moments after, when I expect the next piece to fall, the game suddenly ends. Maybe there's an audio cue I'm missing with the web version?

I wasn't really clear on my objective or the controls. More explanation, either on the itch page or in the game itself, would help. Using B/N for dialogs and Arrows/Space for gameplay is a bit confusing; consider unifying the control scheme.

Good adherence to the jam constraints. Sound would be a nice addition.

This game suffers from lack of feedback and affordance. For example, while "pumping" a tree and collecting money from it, the player has no indication of how much money they have until they move to a different menu entirely. Before money started growing, it was unclear to me whether I was supposed to hammer a button or something to make the tree develop faster. I found the control scheme somewhat unnatural, as I needed to move my hand back and forth between the arrow keys and other portions of the keyboard to navigate menus.

For the most part, this game adheres to the necessary design constraints, but some animations (notably water drips and progress bars) are not pixel-aligned, breaking the illusion of an 84x48 screen.

Gameplay is varied, though the player's motion feels a bit sluggish to me. Reading the manual outside the game is essential, as I don't think I could have made heads or tails of what was happening without a primer.

The conceit of a display which is slowly obscured and must be periodically "refreshed" is an interesting mechanic based on the jam's theme.

Aesthetically, this game adheres to all the constraints of the jam well.

Requiring the use of a numpad makes this game far less accessible than it could otherwise be- I couldn't play at all on my laptop. I think this game would have benefited greatly from a simpler and more consistent control scheme. I also think the game would have benefitted from more explanatory text/legends integrated with the gameplay, instead of frontloading all the explanation and relying mostly on pictures when e.g. collecting items.

Graphics read fairly well, and everything about the game appears to correctly adhere to the jam's aesthetic constraints.

Controls feel reasonably good, pixel art reads well, and the audio sounds authentic for the 3310. Visually, though, adherence to the jam constraints is poor. Some sprites are drawn with alpha transparency and some graphics are anti-aliased, resulting in far more than 2 colors. Graphics are not drawn pixel-aligned, breaking the illusion of an 84x48 pixel display.

Thank you! I'm glad you had an enjoyable and engaging experience.

The 3330 might be more feasible; it has the same external appearance, rez, and so on as the 3310, but according to Wikipedia that model supported J2ME. Even limited to MIDP 1.0, Java ME is quite capable and accessible.

Actually transferring software to the phone is its own hairy challenge. I don't know if there's any sort of data transfer cable you can get for these phones, and afaik downloading games over WAP would mean you had to set up a little local cellular network...

Really cool stuff, Dean- thanks for sharing!

Do you plan to open-source your chip8 interpreter? I didn't see any mention of it on the Hackaday project page.

I wrote some example code for writing nokiajam-compatible games with Octo, my CHIP-8 IDE:

Here's a stream from Darzington/No Problem Games:


This uses XO-CHIP instructions, mostly because I need the "scroll-up" instruction that is conspicuously absent from SCHIP. The sound effects and use of a third color are side benefits. :)

The source is available as a download, if you're curious.

Sure- sounds like fun!

First thing I noticed when I assembled your game is that it's 3814 bytes. That means that it won't quite fit in the low 4kb of RAM. (remember: the first 512 bytes are reserved, and CHIP-8 programs always begin assembling at 0x200.) If you pop a compile-time assertion like the following:

:assert "overflowed code RAM" { HERE < 4096 }

Somwhere in your "game over" routine, you'll see that the assertion fails, which confirms the theory.

Instructions like "jump" (which is emitted as part of an "if...begin" or a "loop...again") take a 12-bit address, so they can only point somewhere in the low 4kb of memory. We need to make your program shorter, or at least ensure that the code fits in a smaller space. Fortunately, I see some easy opportunities to make this happen!

The simplest option might be to move some or all of your graphics data to the end of the program. This may require you to use "i := long NNNN" instead of "i := NNN" in some cases, since that data will now be located somewhere that needs a 16-bit address to access; Octo's assembler will complain when this is necessary.

Another option to explore is reworking that "text" macro. As written, it emits 3 CHIP-8 instructions (6 bytes) for every character printed. That adds up quickly! Even just special-casing spaces like this should save you a couple dozen bytes:

:stringmode text "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,!?/" {
:calc addr { font + VALUE * 4 }
i := addr
sprite vx vy 4
vx += 4
:stringmode text " " { vx += 4 }

Does that make sense?

(1 edit)

When you've completed all the finishing touches on your submission(s) to the Octojam, please consider contributing your software to the CHIP-8 Archive. This repository gathers together dozens of modern CHIP-8, SCHIP, and XO-CHIP programs, including most of the entries from previous Octojams.

Everything in the archive is made available under a highly-permissive CC0 license: This allows future generations to learn from and remix all the great CHIP-8 software we've built over the years without falling into a murky gray area of copyright. The archive also stores all the metadata for entries, so future emulators can display games with the intended palettes and compatibility settings, and many entries include source code and other raw assets. The source directory can contain supplementary information about a program, including links to your itch pages, other online source repos, and postmortems.

Participation in the archive  is entirely optional: it's up to you!

First, the simplest case: you have a single byte in memory and you want to load it into a register:

: data  0xAB
i := data     # set i to the base address
load v0       # load from i into v0

Slightly more complex: you have an array of up to 256 bytes, and you want to load one by index into a register:

: data  1 1 2 3 5 8 11
i := data    # set i to the base address
i += v1      # add an offset (in this case, the value in v1)
load v0      # load data[v1] into v0

Same as before, but now we want 2 bytes:

i := data    # set i to the base address
i += v1      # add an offset. items are two bytes wide...
i += v1      # (we alternatively could have pre-doubled v1.)
load v1      # v0=data[2*v1], v1=data[(2*v1)+1]

Are those cases clear?

This came out fantastic; well done!

I also greatly enjoyed reading the postmortem on your GitHub repo.

Yeah; it's a browser limitation, I'm afraid. To start an audio context playing, you must kick it off as a direct result of a user input action. If the subsystem hasn't been set up yet, Octo will make an attempt in response to keyboard or touch input.

(1 edit)

Exactly; the argument is an AND mask.

Sometimes it's clearer to write the argument to `random` in binary (e.g. `0b1100`) instead of hex or decimal. Then just imagine that every 1 in that mask could wind up as either 1 or 0 in the result.

Currently I'm running at 500, and it's written in a pretty sloppy fashion. I think something like this could be made to work at 200 or less with more care.

I've been doing some tinkering with a tile engine that can handle scrolling a large map and dynamically repainting the edges.

I think I have some ideas for turning this into an actual game. We'll see, I suppose...

Your first example, or anything like

:org 0x210
    0xAB 0xCD
:org 0x200
: main
    loop again

Should work now.

I corrected a flaw in the assembler; give it another shot. It doesn't actually stem from any sort of implicit :org, but rather the fact that the "main" label is special. For programmer convenience, Octo will reserve space for a jump instruction at 0x200 to branch forward to main if it is not the first label defined in the program. Once you start re-orging things this gets a little fiddly, and it broke some assumptions I made very early in Octo's history. It would have worked fine if anything *except* main was the first definition in code-space, but now you can have those precious two bytes back.

Yes; :unpack also predates XO-CHIP overall.

(1 edit)

It's not a built-in feature, but you could write a macro:

:macro unpack-long ADDR {
  :calc hi { 0xFF & ADDR >> 8 }
  :calc lo { 0xFF & ADDR }
  v0 := hi
  v1 := lo

`:unpack` itself was added before macros existed, much like `:next`.

The Octo mode I'm aware of for emacs is here, and it hasn't been updated with language features over time. If you make any improvements, I'd greatly appreciate it if you submitted pull requests to that repo or provided a link to a more up-to-date mode!

Great to have you here, Tom!

A long time ago I did a crude PoC for a raycaster engine. It needed to run at very high speed, and the concept of PWM-ing the display to achieve distinct colors was visually quite painful:

Your progress so far looks rad, Timendus! Really excited to see how it turns out.

(1 edit)

Octo can be used to create a standalone HTML build from an existing .ch8 file; it just takes a few steps:

1) Use your assembler to create a .ch8 binary file.

2) In the "Binary Tools" panel of the toolbox, choose "Open .ch8..." and select the file. This will load the file and display its contents as a hex dump in the field above.

3) Create a minimal Octo program- A "main" label followed by the hex dump, like this:

: main
  0xA2 0x1E 0xC2 0x01 0x32 0x01 0xA2 0x1A 0xD0 0x14 0x70 0x04 0x30 0x40 0x12 0x00
  0x60 0x00 0x71 0x04 0x31 0x20 0x12 0x00 0x12 0x18 0x80 0x40 0x20 0x10 0x20 0x40
  0x80 0x10

4) Customize your palette in the "Appearance" panel, adjust compatibility flags or touch controls  in the "Options" panel (as necessary),  and test your program by running it.

5) When you're satisfied, choose "Save HTML..." from the "Binary Tools" panel, and confirm the remaining settings. Your browser will then save a file to your default download location. You may need to rename it to add a ".html" extension.

Alternatively, if you have nodejs installed locally, you can use Octo's CLI to create a standalone HTML build- see the readme for an explanation.

Does all of that make sense?