Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics


A member registered Feb 21, 2018 · View creator page →

Recent community posts

I just pulled off the same glitch in the same level! I was trying to run from the Lost Soul following me when going in the secret area, only for me to accidently trigger the glitch. I don't think I even had the weapon selector open! I just ran into the pickup sprite and... voila!

Do you mean chaingun?

Why is the audio so noisy? I'm gonna guess that you're poking signed samples to the audio buffer stored in general-purpose RAM, but the PCM channel expects unsigned samples.

Did you do the glitch where the chaingun's pickup sprite turned into the chaingun's handheld sprite, and firing the currently-selected weapon also fired the chaingun at the same time?

Has anyone had problems trying to get the assembler script to work with the newest Python version? I have!

I just found a similar bug while I was playing Level 3 (Avernus Annex). When I got the chaingun in the first secret area, the chaingun's pickup sprite turned into the same sprite as when the chaingun is held in your hand. It fired more rapidly than normal, and firing the shotgun or punching with the fist also fired the faster chaingun's bullets at the same time!

I've only been able to pull this off twice. I've tried for a couple hours trying to replicate it a 3rd time with no luck. By the way, I was playing on a slightly-modified version I made where the E and D keys affect Poomguy and the monsters' gravitational forces.

I think this bug has to do with object-oriented programming anomalies. Retro Game Mechanics Explained made a video some time ago going further in-depth about what I mean. But I don't have time to check so sorry.

(1 edit)

Assembly language! It has a custom 8-bit fantasy architecture called the F8B25 (yeah, not the Fairchild F8!). It has sixteen 8-bit general-purpose data registers/accumulators, a 64K address space, and a pretty basic instruction set (which honestly shares some similarities to the 6502 and some RISC-type designs, but is more limited in the context of addressing modes).

Code density is just low to be honest. They sure had enough spare opcode space for add/subtract without carry, and a way to get the stack pointer value (which is certainly a must-need thing other 8-bit ISA's have, otherwise stack-based arguments is difficult, and multi-stacks are impossible).

Also, note that the manual has a few typos here and there. I downloaded the source code, and confirmed that some opcodes are misaligned, "PSH I" exists and ALS appears to be broken. I think "CMP R, I" might be broken too, in that it doesn't set the CARRY flag if the immediate operand is 0 (always clears it, since the AND-mask and +1 add are backwards), which may indicate the code that there was a borrow even though any unsigned value minus 0 doesn't produce one.

Also, I don't think the OVERFLOW flag's detection handles all cases correctly, since it literally just detects if the MSB of the destination register is flipped by an ADD/SUB/CMP.

Me testing this fantasy console for the first time:

I wish this would actually be back in dev.

If the pin is black, then the bank selection buttons (0...7) will affect all sections of the cart. If gray, then it'll only affect the current section (sprites/map/SFX/music). Also, please don't use code banks, as this feature was removed in 0.80.0-dev due to bugs.

Use poke() and poke4() to write to RAM.

Did you see I've made a bit of edits to it recently after some research of the different sections of the RAM.

Keep in mind he disabled code banks in 0.80.0-dev PRO due to various implementation bugs, so it's probably just ideal to use only the first 64 KiB in bank 0.

You can use pmem() to access persistent storage for the cart.

What are your PC's specs?

You can save cartridges in TIC-80.

There are also JavaScript, MoonScript, Wren, and Fennel languages too.

MoonScript and Fennel are Lua-based languages. JavaScript and Wren are non-Lua languages.

Here's some sample code:

function sget(sprID,x,y)
if x<0 or x>7 or y<0 or y>7 then return 0 end
return peek4(0x8000+((sprID&511)<<6)+(y<<3)+x)
function sset(sprID,x,y,color)
if x<0 or x>7 or y<0 or y>7 then return end

How are these profile pictures possible on the TIC-80 site? :

The latter is an 852x818 all-transparent image, which shouldn't be the case. All generated profile pictures on the site are 256x256, which are supposed to be emulated 16x16 pixel-art in the DB16 palette. The former is a 256x256 image though, but it exceeds the limitations of what you can draw on your main profile page.

When will there be a sound chip here?

  1. The clip() function just limits the drawing area of the the other drawing functions. You give it two coordinates (X and Y) specifying where the top-left corner of the drawing rectangle is located, and two size parameters (W and H) specifying its width and height, in pixels. After this call is made, subsequent drawing function-calls get limited to being drawn in the area specified by the rectangle, with all other pixels outside of it not being updated at all. This leaves quite a bit of border around the game when using clip() to emulate a smaller resolution.
  2. After loading a cart using `load`, press F1 to go into the code editor. You can see how the cart's author coded the whole thing.
  3. The TIC-80 is completely open-source under the MIT license, which means you can make your own mod of TIC-80, free of permission from nesbox.
(2 edits)

They are eight general-purpose flags assigned to each sprite individually, used for whatever purpose by your game. PICO-8 already has something similar, but there isn't any part of the TIC-80 API that has yet to do anything with these sprite flags (other than peek/poke).

Here's some sample code for you:

function fget(sprID,bit)
 return peek(0x14400+sprID)>>bit&1==1
function fset(sprID,bit,flag)
 local old=peek(0x14400+sprID)
 poke(0x14400+sprID,flag and old|(1<<bit) or old&~(1<<bit))

EDIT: Changed base address for sprite flags, after a certain commit on GitHub added the persistent storage memory to where they were previously.

(1 edit)

What was the TIC-80 snap all about? When I access its page, it says 404.

EDIT: Nevermind, it's working again.

Type 3 (cover) is essentially a GIF image file. You can just copy any GIF image's binary data you want, as long as it's less than 65536 bytes. (Nesbox was wrong, only 2 bytes for size are actually being read, the 3rd byte is unused.)

Type 5 (code) is plain text. All other valid types are based on the TIC-80 RAM layouts for each of those assets.

Useful wiki pages:

Can you publish this on

What are your PC specs?

There's textri() function now for rendering textured polygon triangles

Make a 32-bit Windows download

I suck at this game

What do you mean?

(1 edit)

Decide on your fantasy console's specifications. Include control input, graphics and audio capabilities.

The editors need at least some code or assembly language editor, a graphics editor, a map editor, and audio editors. There should be some command shell, and maybe a BASIC included.

You can reply to me all of your planned specifications here.

Also make your fantasy console support 32-bit

What do you mean? A TIC-80 game or a fantasy console that competes with TIC-80?

The PSP can operate up to a 333MHz CPU, and has a 480x272 screen, which I also thought it being four times the size of TIC-80's graphics buffer. However, lag will be more frequent than it is on more recent devices. If you'd really want to play FPS80 on your PSP, then you shat out of luck because FPS80 hogs CPU time, almost becoming unplayable under 333MHz.

I've heard that the PICO-8 requires at least 700MHz, and Voxatron requires at least 800MHz. So I suspect TIC-80 needs over 700MHz due to the better hardware specs than PICO-8.

The behavior with the frequency registers seem weird with the TIC-80 soundchip. It seems like it's a look-up table with a 1789773Hz frequency divider, playing a N Hz frequency with a value of N in the corresponding frequency register.

I'm concerned about the same thing!