9 users online: ASMagician Maks, crocodileman94, IkeSMB, leafermetrics, lolyoshi, MeNe,  Nanako, SepiaSepia, T.CYAN.S-smwcentral - Guests: 103 - Bots: 275
Users: 66,263 (2,216 active)
Latest user: onyxblaster

Sprite Insertion with PIXI

FundamentalCustom SpritesTool-Specific

Sprite Insertion with PIXI

You have seen hacks which uses sprites aside from these existing. And this is, why we chose this tutorial. You want to know, how to use these sprites and this thread is your operations manual.

Table of Contents


The tool we want to use is PIXI, the latest sprite tool.
The advantages over romi's Sprite Tool are following:
  • Quick insertion time.
  • Per-level (or "local") sprites, saving a couple sprite slots
  • Shared subroutines, saving a couple of ROM space
  • Extra Bytes
  • Support for other sprite types
  • Native SA-1 support
  • Uses Asar
  • Open source

If these aren't reasons to not use PIXI over Sprite Tool, what else?

Preparing PIXI

The first thing is to extract all files (okay, there are optional files but still, if you don't know how PIXI works, just do it). I also recommend to put PIXI in its own folder to avoid conflicts with tools which use files with the same name as PIXI's ones. To use PIXI in a separate folder, simply use a batch or shell script, presumably a drag and drop one. It would look something like this:
@echo off
pixi.exe %1

Unix (Linux, MacOS):
./pixi.exe $1

Aside from that, at the end of each chapter there are some questions to test if you have understood the tutorial.


Mario wants to use PIXI. There is one problem, though: It complains that some files aren't found.

After he managed to work PIXI correctly, other tools start complaining.

Sprite Insertion (Global)

Now, we have set up PIXI. The next step we want to do is to actually use it. We first get some sprites which I'll link them throughout the tutorial (originally, PIXI used to come with some examples but they have since been removed). For more sprites, take a look at the Sprites section, though you can also find but be aware that they may not be PIXI compatible which I'll explain later on.
Anyway, after you got your sprite, there are two important types of files:
  • ASM files which contain the sprite code and
  • CFG/JSON files which contain some sprite configurations

Both require to be in the same folder which is for now sprites. The amount of CFG/JSON files can be higher than these of ASM file and don't match up necessarily with the file name but don't worry, the ASM file is specified in the CFG/JSON file and can be used multiple times.

In case you're wondering on what I mean with the whole "CFG/JSON" nonsense: Basically, there are two types of configuration files PIXI supports: The older CFG files used by mikeyk / romi's Sprite Tool and the newer JSON files only used by PIXI.
PIXI is backwards compatible to the old CFG files (in particular since they were added in later in the development) and so are common but most newer sprites should come with a JSON file instead. In addition for being more human readable, JSON files also come in with a couple useful features both for coders and for users which were not implemented for CFG file. The insertion process is otherwise the same on the user's side.
It should be noted that this tutorial still mostly refers to the configuration files as CFG files both for being grandfathered in (this tutorial is older than JSON support) but also because it's clear what abbreviation literally means. The only exception is when the difference between both of them are explained in which case CFG refers to the old file.

We then create a file named "list.txt". This contains all the sprites which PIXI will insert. The format looks like this:
<Number> <Sprite>
  • <Number> is simply any number between 00-BF.
  • <Sprite> is the CFG file of the sprite you want to insert. You don't need to specifically the main folder (by default sprites). However, if the sprite is in any subfolder besides the primary ones, you have to enter the subfolder's name, followed by a slash and then the sprite's name (i.e. something like subfolder/sprite.cfg).

Confused? As an example, we try to insert this Hammer Brother sprite and this Stationary Piranha Plant. Extract the files into the correct folders The list should look like this:

Now try to insert these sprites into your level. Insert the ExGFX, set the GFX in the level correctly, switch to sprite mode and now press "Insert" on the keyboard. You then see a dialogue window:

Only the "Command" and "Extra Bit" fields are important.
  1. The former is the sprite number. I guess, you can figure out, what you have to enter into this.
  2. The latter is set to be either 2 or 3. This has got two functions: The first function is to determine that this sprite is custom (hence why you have to enter 2 or 3 into that field) and the second function controls the behaviour on some sprites with 2 being the first, default behaviour and 3 being the secondary behaviour (that feature is often referred as the "extra bit"). The Hammer Brother doesn't use the extra bit, the Stationary Piranha Plant does so insert both versions into the level.
    In fact, there even exists a vanilla sprite with that feature: The goal tape. Both, the normal and the secret goal are the same sprite but the extra bit controls the exit it activates (of course, instead to enter 2 or 3 to that field, you have to put 0 or 1 for the goal tape*).

The rest is irrelevant and can be left alone.
If you have done it correctly, a sprite on the top left corner of the window will appear. Depending on the sprite, it may or may not look like an X in Lunar Magic but since the level editor doesn't reflect on how the sprites look actually in-game, this shouldn't be a problem, the sprite is still functional after all. I also recommend you to reload the ROM in Lunar Magic so the data gets refreshed like the appearance of the sprites.

And this is where the first difference between both config files appear: CFG files cannot contain any display information while JSON may come with them. This is particular practical if the sprite's origin is offset as seen with the Piranhas. Some creators don't bother with the display graphics at all so even with the JSON, they may not even appear correctly in Lunar Magic either. More differences between both of them will come up throughout the tutorial.

After you set up the graphics, try to place a Hammer Bro and two stationary Piranhas (each facing in a different direction) into your level. If you have successfully done this, it should look like this:

Actually, I hid a small feature from you: Lunar Magic allows you to use your own sprite list which is primarily intended for custom sprites with PIXI being able to create a list for it. However, it only does it if the sprite comes with a JSON file:

CFG files are out of luck and thus must be inserted manually only (at least for now) hence why the stationary Piranha Plants don't appear if you use the included CFG file. To fix this, simply switch out the CFG files for JSON files:

It even comes with both versions available!

Some sprites also require another sprite to be inserted because they spawn a different sprite. This Boomerang Bro is one of them: In order to use them properly you also must insert the boomerang as well as telling the game to spawn the boomerang and not a different sprite. The information either come with an external readme or are found within the ASM file (yes, you can open them just fine).

If done correctly, it should look like this:

Finally, the "global" refers that these sprites can be used in all levels in contrast to the "local" sprites whose code and data is level dependent.

*Actually, before we go to the questions, I have one last thing to note: Starting from Lunar Magic 3.0, Goal Tapes use all four extra bit values. That means, it's impossible to insert any custom sprite as number 7B as that would otherwise conflict with the goal tapes. Should you get such an error, skip the number and use a different one.


Bowser want to place a couple minions into his level. Except it turns out that the minions in question are Koopas even though they were supposed to be the Brother enemies.

In a cave, he wants to put some stationary Piranha Plants but the one on the ceilings don't look like they're attached to them.

He also want to place some Boomerang Brothers but it turns out that they won't throw boomerangs but other enemies.

Sprite Insertion (Per-Level)

PIXI also allows the use of per-level or "local" sprites, sprites whose code and data is dependent of the level. In contrast, global sprites can be used for any level. That way, you can have more sprites then the initial list supports without relying on weird tricks.
Anyway, the insertion of local sprites follows a similar style as global sprites with one exception: You have to enter the level number and also tell PIXI that you use them. The format in the list is following:
<Level>:<Number> <Sprite>
  • <Level> is the level you want to have the sprite inserted.
  • <Number> is any number between B0-BF.
  • <Sprite> is simply the CFG file.

Once again, there is an example on how to use local sprites with inserting the Boomerang Brother for level 105 and the Falling Spike for level 106:
00 StationaryPiranhaPlant.json
01 hammer_bro.json
105:B0 boomerang_bro.json
105:B1 boomerang.json
106:B0 FallingSpike.cfg
Before you run PIXI, remember how I mentioned you first have to tell PIXI that you want to use per-level sprites? Yeah, this is what happens if you don't:

Due to the larger insertion size and issues in older versions of PIXI, the per-level function is disabled by default starting from version v1.2.5. This means, you have to enable it per command line. In fact, remember the batch file I mentioned above?
@echo off
pixi.exe %1

You can put in various flags for customisation which means between the executable and the input ROM name. They're all listed in PIXI's readme file.

Anyway, if you run PIXI, you'll get the following message:

This is normal because of limitations with so called "extra bytes" which I'll explain later but they aren't requires for per-level sprites.

If you place sprite B0 into level 105, you see that it's a Boomerang Brother but if you go to level 106, it's a Falling Spike instead despite both sprites using the name number.

Whether you put sprites as local or global doesn't really matter. It only gets important when the sprite in question spawns another sprite and its number isn't dependent of the mother sprite's number.
Here is another image for reference:

It should be noted that you still can insert a sprites on a per-level slot without it being local, even when a local sprite has already been inserted. You just omit the level number.

Lastly, there are some other limitations with per-level sprites:
  • PIXI will never generate data for the Lunar Magic appearance nor will make them appear in the Custom Collection of Sprites as it's impossible for Lunar Magic to track per-level sprites.
  • Per-level sprites can only use up to four extra bytes, though what they are is explained later on.


Luigi wants to use a Roto Disk only for one level. However, whenever he does, PIXI spits out the error that it "[tries] to insert per level sprites without using the -pl flag[...]".

Afterwards, he tries to place it into the level only for him to not find it in the sprite insertion window.

Shared Subroutines

As mentioned above, PIXI supports shared subroutines. The idea is that some routines are found in almost every sprite. Which is especially problematic for a couple routines like the large GetDrawInfo or SubOffScreen. Before PIXI, you had to use an external patch. PIXI doesn't require that since it has integrated that feature which can be used by sprites directly.
Now, I won't write about how to create them (that's a tutorial for the programming part) but on how to insert them. The idea is simple: There often is a readme which explains which file belongs where and routines simply belong to the folder routines. That's it. Alternatively, you can insert this sprite without the shared routines and look what errors appear. If a macro is missing and apparently has got the same name as an ASM file, it's this one you have to put in routines.

Sprite Insertion (Shooters and Generators)

The next two kind of sprites are from different types: Shooter and generators. They belong to their own kind of sprite and such work differently including the insertion (though only a bit). Here is a short list of differences:
  • They don't feature any tweaker bits (see below) or property bytes but they still have got the extra bit.
  • Shooters use numbers C0-CF, generators D0-DF.
  • All of them are global.
  • They belong in their own folder (shooters in shooters, generators in generators.
  • You can only have eight active shooters (obviously, they disappear if they're too far off-screen) and one generator at time.

Other then that, the procedure is the same as with regular sprites.

My challenge here is to insert the Shell Shooter which should be fairly simple:


Bowser Jr. want to use a vertical Bullet Bill shooter. However, it doesn't do anything or worse yet, crashes the game. Here is the list:
10 vertical_bill.cfg

After he entered the correct sprite number, PIXI complains that it couldn't be opened even if it is located in the folder "sprites".

Final note: Generators are a mostly depreciated feature and gets slowly replaced by UberASM. Finding them, especially on SMWC can be difficult, though there still are a lot of valid use cases for them (in particular using them for stuff which spawn other sprites like they're originally intended).

CFG Editor

Sometimes, you want to edit some sprite properties but don't know where to look at the ASM file. Thankfully, most of them aren't really hardcoded i.e. set up in the ASM file. Instead, these properties (also known as tweaker bits) are controlled in the CFG file which is easier to edit and also saves bytes.
You can open them with the notepad but it is more of mess of data. Instead, you use a tool included with PIXI, the CFG editor. It is specifically made to edit the CFG files. This is how a screenshot of it looks like:

There are quite a few settings, some of which are quite technical and should not be changed unless one knows what one is doing. I reduce the list to all settings which matter for non-programmers as well as some side notes to them:
  • Can be jumped on: If checked then you can jump on this sprite without getting hurt (think of non-spiked enemies). This only applies if "Don't use default interaction" is unchecked unless implemented in the custom sprite.
  • Disappear in a puff of smoke: Some sprites like Piranha Plants do this when they're killed.
  • Use second graphics page and Palette: Most sprites' tile colours and page number can be edited within the CFG file.
  • Disable fireball killing: Mario's fireballs disappear in a smoke when they hit this sprites.
  • Disable cape killing: Depending on the implementation, the sprite may get thrown upwards (see powerups) but other then that can't interact with capes at all.
  • Invincible to star/cape/fire/bouncing blk.: Regarding the fireball immunity, the sprite simply stops interacting with them. And Bomb-Ombs and Yoshi's stomp (due to the latter being technically a bounce block) can't hurt these sprites too while Yoshi can't get scared of these sprites (think of the line-guided chainsaws). On top of that, some sprites come with their own interaction which may override this setting. Otherwise, it's self explanatory.
  • Process when offscreen: But remember to use these sprite sparingly as they fill up the sprite slots and cause slow downs quickly. Likewise, some sprites won't check if they're offscreen at all which comes with its own side effects, making this bit useless.
  • Inedible: Yoshi simply can't eat it. That's it. Actually, a sound effect is played if the tongue hits an inedible sprite but that's the only side effect.
  • Stay in Yoshi's mouth: But remember to only use it for carryable sprite. The sprites Yoshi will spit out are in the stunned or kicked state which can cause glitches on these without a stunned routine.
  • Don't turn into a coin when goal passed: Keep in mind that sprites will still disappear if they haven't checked "Don't erase when goal passed" too. They simply won't give any coins instead.
  • Don't erase when goal passed: This only gets applied if you have checked "Don't turn into a coin when goal passed" too. Otherwise, this means nothing.
  • Can't be killed by sliding: But only if "Don't use default interaction" is unchecked.
  • Don't turn into a coin with silver POW: Read: Silver P-switch, self-explanatory.
  • Extra Property Bytes: In order to save ASM space, some sprites will change their behaviour depending on these two bytes. For example, some custom Koopas will change their behaviour independently from their palette and use these bytes instead. The second byte has got an extra function but it's only interesting for programmers.
    Keep in mind that many extra property bytes also work bitwise. There will be a chapter later explaining what it means.
It should be noted that some settings must be implemented by the sprite. The jumped on, puff of smoke and sliding settings are all settings which are checked with the default interaction but not all custom interactions will check for them so if a bit is ignored, that's the reason and likewise, not all sprites use the palette nor implement the second page settings either.
For the rest, only use them if you know what you're doing (e.g. if a readme tells you so).

Here is e.g. if you change the hammer bro's palette E and make it unstompable:

(Of course, nothing stops you from copying these files and have two different versions of sprites. In fact, having multiple CFG files of a sprite is why tweaker bits exists in the first place.)

Now, you already know that Lunar Magic displays sprites independently from the game so it should be no surprise to see them unchanged. Even then, you still can confuse them with regular Hammer Brothers so how could we change the palette and potentially the description? With the CFG Editor, of course. You may have noticed the three tabs Default, Lunar Magic and Custom List before but I always ignored that.
  • Default is the standard view which I've explained throughout already.
  • Lunar Magic handles the sprite's display but also its hover description within the level editor.
  • Custom List is where you find the settings for the sprite in Custom Collection of Sprites and allows you to set some presets like the extra bit and bytes.

Let's focus on Lunar Magic first where switching to the tab reveals this page:

The Hammer Brother looks like a glitched mess but it makes sense when you consider that the corresponding graphics haven't been loaded yet so do it. There are quite a few settings, some of which are more interesting for creators than users but the one we're interested in are the description, Map16 and the table in the bottom middle.
The description is simple: It simply is the tooltip description. Within Map16, you can find all the appearances of the vanilla sprites (this table, btw, can be found in the Map16 editor at pages 100+) as well as that of the current custom sprite at the end. The last 256 tiles also are the only ones PIXI allows you to edit. Simply select the tile you want to change, go to the palette drop down and select the palette (yes, the palette which is displayed there has its values subtracted by 8 but that's mostly for internal reasons), save the file and run PIXI again. Lunar Magic should now display the Hammer Brothers black (or whatever palette E is in the level):

The last widget I have to mention is the table in the middle. It contains all display states which is a mixture of extra bit and either the initial position or an extra byte (see the next chapter for more information) depending on what Lunar Magic should consider for the display. This is useful to know why e.g. a sprite suddenly reverts back to the old graphics when the extra bit is set even though you know you changed it (you can check this out with the Stationary Piranha Plant and change the stem red that you need to change both states).

The last tab of interest is Custom List which allows you to change but the only function of interest is the name as of now. Simply select the row you want to change and then type in the new name:

Alternatively, you can edit it by selecting the same cell twice (not too fast that the tool thinks you're double clicking, though).

That should be all to cover the basics of the CFG Editor but it clearly is more advanced then that. And of course, this is only possible with a JSON file as a CFG file doesn't contain any display data.


Toad wants to change a sprite's colour but for some reason, it just don't work.

The sprite is still shown in its original colour even after reloading Lunar Magic.

He also has another one but don't want it to get removed when Mario hits the goal. For some reason, the sprite still turns into a coin.

Finally, Toad wants to use a couple custom shelless Koopas in the level. He knows that the behaviour is independent from the palette but in the end, he has no idea, how to change it.

Extra Bytes

One of the more powerful features PIXI has got are extra bytes (not to be confused with "extra property bytes" which are defined in the CFG files). Before that, only Tessera ever made great use of it. To explain what this one does: When you place a sprite in Lunar Magic, it inserts three bytes of data into the ROM containing position, sprite number and extra bits. Lunar Magic allows you to increase the sprite size, though, which is what we call "extra bytes". That way, you can insert sprites with different behaviour without different ASM files (or CFG files for that matter).
The usage gets a bit more complicated then usual. Let's take a look at the insertion window again:

The extra bytes are set on the extension field and in fact are sometimes called "extension bytes" for this reason.

However, there is an easy pitfall with extra bytes: The sprite level data is read in a continuous stream and the level loader (both of the game and of Lunar Magic) don't immediately know which byte belongs to which sprite. As a result, there is the danger of breaking the sprite level data by reading too many or too few bytes.

To give you example, let's imagine you have the following stream of data: A1 A2 A3 A4 B1 B2 B3, where Ax is the first sprite and Bx the second one. Sprite A has got one extra byte, sprite B has none. If you shrink down A's number of extra bytes to none, the game reads the data like this instead: A1 A2 A3 B1 B2 B3 C1" which means it reads A's former extra byte as B's first byte in the sprite level data. This isn't an issue with per-level sprites, though, which permanently use four extra bytes.

Fortunately, this problem is not an issue when you run PIXI (you often see the message "Extra Bytes remapped" — which you hopefully saw previously — which tells you that your levels are fine after running PIXI) but the ROM still needs to be reloaded so that Lunar Magic knows how many bytes a certain sprite uses and likewise, MWL files contain no sprite size information either and so will break if you use it on the wrong ROM. The one exception are per-level sprites but only because they always reserve four extra bytes. Relatedly, they also can't use more than four either both for bloat reasons but also for making the code for spawning a sprite from the level simpler.

Bitwise Stuff

Now we go into something more technical. This is where we explain how to write the correct value for the extra bytes and extra property bytes. In case you didn't know, most kinds of computer (at least in the classical definition which also included consoles) calculates in dual or binary (there were attempts with trinary computers but these were inferior to binary computers). Each digit in binary is called "bit", eight bits (or an octet) equal one byte.
The problem is to get the correct value if you have knowledge of binary. To get some help, we use some kind of calculator, preferable these made for programmers. The Windows calculator has this mode so I'll use that. Keep in mind that you have to switch to programmer mode (scientific in older versions) so that you can use binary numbers. Programmer calculators also have got the property to set the value bitwise.
Anyway, here is a look at the calculator:

The sprite we want to explain the bitwise stuff are Shelless Koopas. Opening their ASM file and you find out that their behaviour is controlled by the extra property bytes. Specifically, it allows you for different eight options. You take a look at line 5:
In binary, its format is [dgrh jfls]

What this means, you can assign each bit a flag. We take a look at the two most rightward groups of bits at the most bottom row. Here is the image of the calculator with the important bits marked in blue:

These are the bits you have to enter. Setting a bit to one means the property is activated, if reset to zero, it's disabled.

You then have to make sure the value you got is in hexadecimal et voilà, you got the value you can to enter in the CFG Editor for the Shelless Koopas' properties.

However, the usage isn't always as easy as the Shelless Koopa are.
We first have to explain, how bits are handled: The rightmost bit is called "bit 0", the bit to the left is "bit 1", then "bit 2", and so on. (Notice we put the units also to the right, the one next to the light are the tens, etc.)
The reason why we start with zero and not one is because of the bits' values: It's 2 to the power of n which where "n" is the bits position (for anyone who don't know what a power of exponentiation is: It's a simply repeated multiplication). Bit 0 such has got the value 1, bit 1 the value 2, bit 2 the value 4, etc.
It also explains, why the numbers below the bits are multiple of fours and the value hasn't been added with one.

Our next example are Para-Beetle. This is where our definition comes handy as instead to talk about flags, it uses a description. It also uses groups of bits. But don't worry, the procedure is similar. You have to mark these (in your head). I have got some help with a graphical image of the calculator:

The problem is how to set the direction for the Para-Beetle as the values are written in decimal and in binary, only 0 and 1 as digits exits. But don't worry, you know how binary numbers work: Bit 0 controls the ones and bit 1 the twos. You such have got the amount of four possible states:

If you don't want to convert between decimal and binary (e.g. because you don't know how to or the numbers become unhandy), you can use the calculator instead. The only problem is that not all groups of bits start with bit 0. Some are in the middle of the bytes. But don't worry, your job is to adjust the value with the help of bit shifting. Bit shifting is nothing more but a multiplication or division by 2. The buttons for bit shifting are often called Lsh and Rsh or X<<Y and X>>Y (the former is bit shifting to the left, the latter to right) which is what you have to use them. After clicking on it, you have to enter the value for the smallest bit in the group (e.g. if a group consists of bits 3-6, you shift the amount of bits by 3 bits).
If you already have a value on the calculator, there is an easy way to go around with it: You add the values or "OR" them together (a bitwise OR is simply merging to bytes together where the final byte has all bits set which were set in either byte 1 or byte 2). Bit shifting comes before bitwise operators so there is no need to use parenthesis (brackets) but you can add them for safety.

Music porters knows this from the hexadecimal opcodes which work similar to that (e.g. ADSR uses two bytes of which the first one controls attack and delay and the second one sustain and release).

If you find this chapter confusing, then I'm sorry for that!
If you have a better way to describe this chapter then feel free to do so!

Sprite Insertion (Cluster, Extended and the Other Sprite Types)

PIXI not only allows you to to insert sprites, shooters and generators but all the other sprite types used in levels. To explain what these sprites types are, these are sprites which you cannot place in the level directly but are rather generated by other sprites and thus often fill in a secondary role like particles or decorations. A side effect is that none of them come with CFG nor JSON files so you insert ASM files instead.

Here is a list of all available sprites:
  • Cluster sprites. They are extremely simplistic. That's because they're supposed be spawned en mass in a level without slowing it down too much (thus the name "cluster sprite" i.e. a sprite which comes in a cluster). A list of cluster sprites can be found here.
  • Extended sprites: They are mostly projectiles and sometimes visual effects in case minor extended sprites don't work. A list of extended sprites can be found here.
  • Minor extended sprites: Purely visual sprites (exception: The trail of a Boo Stream) which disappear after some time. A list of extended sprites can be found here
  • .
  • Smoke sprite: Static sprites which disappear after some time. A list of extended sprites can be found here
  • .
  • Bounce sprite: The sprite of a block which has just been activated. This will give the block a nice little animation to make it more impactful. A list of bounce sprites can be found here.
  • Spinning coin sprite: The coin which comes out of a block and is automatically collected. A list of spinning coin sprites can be found here.
  • Score sprite: The score display when you do stuff, though it also includes the x-up display. A list of score sprites can be found here.
Cluster and extended sprites are placed in the folder where PIXI is located (cluster and extended, respectively), the other types in the folder misc_sprites to reduce clutter in the main folder.

Anyway. All sprite types share the same list so in order to tell PIXI which file belongs where, you must switch modes. This is done using <folder_name>:. For example, inserting an extended sprite means you need to put in EXTENDED:, a spinning coin instead as SPINNINGCOIN: and bounce sprite as BOUNCE:. To insert normal sprites, shooters and generators, again, simply put SPRITE:.

With this knowledge, let's try to insert a Cluster Effect like the fish one. The caller file is found in sprites and is just a normal sprite, the cluster sprites are located in cluster instead (there also is the option to insert them in UberASM in case you want to save on sprite IDs). The number of the cluster sprite is determined using the first extra byte (I hope you paid attention to the second previous chapter!), though other sprites may hardcode it into the ASM file.
The list should look something like this:

The procedure is similar to the other sprites.

Anyway, want an image for this effect? Here you are:

That's it. Inserting other sprite types ultimately isn't that much more different than inserting normal sprites, shooters and generators.

Bonus: Try to insert a Fire Brother enemy. Unlike the Boomerang Brother, it uses extended sprites for projectiles (it also is a differently coded one — the previously bother sprites were by mikeyk for their simplicity, though hammer and boomerang throwing versions by Sonikku exist as well).


Peach finds the level lacks some effects. She uses a cluster flower effect. After successfully inserting the sprite, the game crashes or the flowers won't appear. Nothing is wrong with both codes, btw.

She puts flower.cfg into the list but uh oh, PIXI complains! Here is how it looks like:
00 clusterspawn.cfg

01 flowers.cfg

It still complains! Why can't be the insertion of cluster sprites be so easy!

Error and Crash Handling

Not everything is fine and problems will arise after some time. Here are a couple problems which you may come up during the use:
  • TRASM sprites: Before PIXI was a thing, Sprite Tool was the local sprite inserter. That being said, it supported two assemblers: Xkas (and in the latest version, Asar) and TRASM. That being said, the latter had a very different syntax from the former two (ASM itself is mostly unchanged, just the assembler commands). As such, sprites using that tool are incompatible which unfortunately includes a list of sprites on SMWC and (older) sprites on other sites likely won't be Asar-compatible too. Luckily, you can convert TRASM sprites to Xkas with Trashkas (included with PIXI) which uses a similar syntax as Asar.
  • JSR (Label,x): There is a bug in Asar where it can't compile this command, no matter the label. There is a simple fix, though: Just replace the JSR with a JSR.w and sprite should compile. This has to do that Asar tries to compile it with a long address (JSR.l ($xxxxxx,x)) even though this command doesn't actually exist, only absolute ones (JSR.w ($xxxx,x)) do.
  • incsrc / incbin: A problem mostly common on dynamic sprites. This one isn't bug but a different way on how both assemblers determine the mother directory when using these commands. Simply remove "sprites/" from the incsrc / incbin inside the sprite (just search for incsrc / incbin to get to the erroneous line).
    This has to do with the reason that Xkas (and TRASM for that matter) uses its directory as the mother directory whereas Asar the directory of the file which has got the incsrc / incbin instead. That means, xkas searches in the directory it's located for the folder sprites (which usually exists) first and then for the e.g. graphics file whereas Asar searches for sprites inside another sprites (i.e. if the directory where PIXI is located is PIXI, Asar tries to go to PIXI/sprites/sprites) (which usually doesn't exist unless there is one for some reason).
  • SA-1: This problem is similar to the TRASM problem: Not all sprites supports SA-1 natively so you can use the SA-1 converter (again, included with PIXI). If there are some conversion problems, please post it in either of these threads.
  • Sprites not respawning after not loading into the level: In 99% of all cases, this happens because of older code. Basically, PIXI allows you to place up to 255 unique sprites into a level (though SA-1 Pack also comes with this behaviour) while the original game only supports up 127 sprites loaded. In order to support this many sprites, the sprite load table has to be moved to freeRAM. This usually is not a problem because this usually is handled by a shared subroutine which can easily be replaced so this change went pretty much unnoticed.
    The only exception are older sprites (for romi's Sprite Tool) and sprites which come with their own SubOffScreen. For the former, you have to search for a line which contains JSR SUB_OFF_SCREEN_X and replace it with LDA #$nn : %SubOffScreen() with "nn" being the number after the subroutine call. If a sprite is newer and uses a custom SubOffScreen, please report it instead unless you know what you're doing.
  • If you see any sprite which you just can't insert, crashes the game or notice any other problem, it's important to report it.


Wario wants to insert some sprites he got some someone's filebin except multiple errors appear. Most of them have got stuff like "Invalid Number", "Label XXX not found" and "Unknown Command".

Wario wants to insert a dynamic sprite instead. He runs it though TRASHKAS but there is an error that a file couldn't been opened.

Edit: Updated the tutorial to reflect the new changes in PIXI (changed per-level sprites, other sprite types, etc.).
Thanks for make!
When this is done (no sections under construction) I'd like to go over it to fix up some grammar, if you don't mind.
Your layout has been removed.
I have a problem with the local sprites (a.k.a per level sprites):

The local sprite is inserted sucessful, but the sprites doesn't appear in the later screens.
What will I do?
For Errors, I'd recommend adding a section for incbin/incsrc file not found. As pixi handles the working directory differently than romi's sprite tool. (Pixi has a temp asm file in the main directory which runs a an incsrc on the target sprite where romi's copies the sprite code into the temp file)
Anime statistic on MyAnimeList:
400 animes completed ✓
6000 episodes completed ✓
100 Days completed ✓
... what even am I doing with my life?
I barely started, I already have 2 issues #ab{x_x}
- I don't really get the part with the batch file. No idea what to do and how to do it.
- I can't open "list.txt" since I have no such file
Not the best of starts #tb{^V^}
Super Mario Pants World
Luigi's Lost Levels
New Super Mario Pants World
Luigi's Lost Levels 2 - Back With A Revenge
Luigi's Lost Levels 3 - Electrik Boogaloo
VLDC12 - 72HoKaizo#1
Originally posted by Romano338
- I don't really get the part with the batch file. No idea what to do and how to do it.

  1. Open notepad or any other text editor.
  2. Copy the code in this thread an paste it into the editor.
  3. Save the file as a batch file. That means, you when save it,
    remember to use "Save As..." and chose either batch file extension or "All Files". Remember (if or especially if you use All Files) to attach the extension ".bat" (without quotes) at the end of the file too.

Originally posted by Romano338
- I can't open "list.txt" since I have no such file

Then why don't you create a new list.txt?
Considering putting batch file on other drive, it should do as follows.
@echo off
cd /d "PIXI"
pixi.exe %1

(use /d option for cd command)

You can use it only if you put the batch file in the same directory as pixi
@echo off
cd /d "%~dp0"
pixi.exe %1

Post footer:
Also known as signature. This will be appended to your posts. HTML is allowed.
I've got the Cluster Sprite insertion stuff, here's how it'd be inserted:
00 shyguy.cfg
01 alcaro.cfg
02 cluster_sprite.cfg
02 cluster_sprite.asm

basically, this list has to be switched to cluster sprite mode, so while it's in that mode, any cluster sprite requires that the .asm listed too.

As for custom extended, I have no clue, maybe it's similar????
Hi, I'm a signature!
Hack Thread
Hack Testing Status: Available.
Layout by Koopster.
Originally posted by Konata Izumi
I've got the Cluster Sprite insertion stuff, here's how it'd be inserted:
00 shyguy.cfg
01 alcaro.cfg
02 cluster_sprite.cfg
02 cluster_sprite.asm

basically, this list has to be switched to cluster sprite mode, so while it's in that mode, any cluster sprite requires that the .asm listed too.

As for custom extended, I have no clue, maybe it's similar????

Thank you for the information but I wanted to (and will) add the information to the main part. And extended sprites are similar as cluster sprites except you use "EXTENDED:" instead.
I know this seems minor, but:
And because it hijacks a the vanilla sprite table

100% Orange Juice Playthrough:

VLDC9 Playthrough:

Originally posted by MarkVD100
I know this seems minor, but:
And because it hijacks a the vanilla sprite table

How is that bad?

edit: notice the error you smart
Hi, I'm a signature!
Hack Thread
Hack Testing Status: Available.
Layout by Koopster.
Does anyone have a basic explanation on how the extra bytes work? I know they're supposed to be binary (represented in hex), but is there anything else to know about them? In particular, I don't know what the "Extra Bytes Count" option in the CFG editor does.
I don't know what the "Extra Bytes Count" option in the CFG editor does.

It tells the game (and Lunar Magic) how many extra bytes a sprite uses. If you put a 1 there it'll use 1 extra byte, if you put 2 there it'll use 2 etc (up to 4 extra bytes are supported)

I know they're supposed to be binary (represented in hex), but is there anything else to know about them?

I'm not sure what you mean.
If that's a complicated way of saying that it's a number then yes.
If not then idk.

The extra bytes are simply extra numbers a sprite can use. In Lunar Magic there is a field where you can set the extra bytes of a sprite.
The sprite itself can then load what you entered and do stuff with it.
Common uses are for variable effects like speed of a sprite or what sprite it spawns, but it can be used for anything.
When I try to insert a sprite and change the extension to FF, it instantly reverts back to zero. Why does this happen and how do I fix it?

EDIT: it does this with any other number, too.
Originally posted by Darkbloom
When I try to insert a sprite and change the extension to FF, it instantly reverts back to zero. Why does this happen and how do I fix it?

The extension only applies for sprites with at least one extra bit. Sprites without these can't make use of it.
Moreover, the value isn't limited to just 0xFF but in theory infinitily high because you can set the sprite to infinite size (again, theoretically).
Finished the section for cluster and extended sprites, extra bytes and bitwise stuff though the latter might be confusing for total beginners.
About the cluster sprites

I did everything you said, i put
02 cluster spawner/rainspawn.cfg


02 rain.asm

but it still doesn't work, my game crashes.
Yeah, it's a problem with the rain cluster sprite. But you can easily fix that: The RTS in the code is supposed to be an RTL.
A similar problem accurs with the sandstorm which has got the same problem.

And as a tip for the others: If the game crashes no what you do, try to insert other sprites to see if the crash happened because of the sprite itself and not because you inserted it wrongly.

Help, i have a Angry Sun, a fairly old sprite. When i try and make it compatible with PIXI, it complains that the label DIR wasn't found. For Jebus's sake. Here's the code.

LDA $157C,x ;direction...

LDA $15F6,x ;properties...

LDX #$00 ;frame index
If you're on Firefox 70+, and you don't see the blur effect, go to about:config and enable layout.css.backdrop-filter.enabled and gfx.webrender.all
For the best aesthetics, use Chrome, or with some settings, Firefox.

Colour scheme based on the awesome ViM theme, Gruvbox.
That's not a code, it's a piece of a code (i.e. not enough to see how to fix it).

Anyways. The problem was some faulty conversion or sprite had a faulty code regardless of TRASM or Asar. Can you give us a link to the sprite? If not then post the code of the whole sprite and I'll on that. But please, if you give the code, don't add it to your post but link it from somewhere!

FundamentalCustom SpritesTool-Specific