Skip to content

Modding FAQ: Coding⚓︎

How do I understand the docs?⚓︎

Below is a breakdown of a documented function.

img

1
2
3
local player = Isaac.GetPlayer(0)
local hasTrinket = player:HasTrinket(TrinketType.TRINKET_SWALLOWED_PENNY) -- Notice how that second argument was optional, hence the equals sign.
print(hasTrinket) -- Either "true" if the player had it, or "false" if they didn't.

How do I do X? How do I code X?⚓︎

The fastest way to figure out how to do something is to download a few mods that provide similar functionality to what you want to do, and then study the code. Attempt to understand why things were made the way they were before attempting to replicate them yourself.

Where can I see the code for [some vanilla item] or [some vanilla mechanic]?⚓︎

You can't. The game is programmed in the C++ programming language and the source code is not publicly available.

This means that if you want to make a custom item that works in a similar way to a vanilla item, you will have to completely re-implement it yourself from scratch. (You can often use the wiki as an implementation reference.)

This also means that if you want to change the way a vanilla item works, you will often have to re-implement the item from scratch.

What is a callback?⚓︎

Mods affect the game by putting code inside of callbacks. Each callback fires when a particular event happens in the game. There are 74 different callbacks to choose from, so you have to choose the right one depending on what you want to do.

For example, the most basic callback is MC_POST_GAME_STARTED, which fires once at the beginning of a new or continued run. You would connect a function to this to do something custom at the beginning of every run.

Another common callback that mods use is MC_POST_UPDATE, which fires on every single update frame (i.e. 30 times per second). You would connect a function to this callback for custom items that have constant effects.

Go through the ModCallbacks page and read what all of the callbacks do so that you can get familiar with them.

What is the difference between require and include?⚓︎

See the tutorial on using additional Lua files.

How do I know when a player has picked up a collectible item?⚓︎

If you're using the script extender REPENTOGON, then you can use the MC_POST_ADD_COLLECTIBLE callback.

Otherwise, there is no vanilla callback for this. As a workaround, you can check EntityPlayer.IsItemQueueEmpty() on every PostUpdate frame, and then check EntityPlayer.QueuedItem when it is not empty. Obviously, this will not work for items that never get queued.

For IsaacScript users, you can use the provided MC_POST_ITEM_PICKUP callback.

If you want to implement this callback yourself, the source code / algorithm is provided here.

What is the ID of [the sound effect that I care about]?⚓︎

If you have REPENTOGON installed, you can this mod that gives you detailed information about a playing sound, including a button to copy its enumerator to your clipboard. Otherwise, use this mod, which will tell you what the ID of any currently playing sound effect is.

How do I make my custom character start with a smelted / gulped trinket?⚓︎

If you're using the script extender REPENTOGON, you can use this method of the player. Otherwise, you must accomplish this manually via code.

How do I modify the Devil Room / Angel Room chances?⚓︎

If using the script extender REPENTOGON, you can check out the multiple Devil/Angel room chance callbacks.

Otherwise, there is no built-in way to do this, so you will have to get inventive. For the most control, you can delete all vanilla Devil/Angel doors and completely re-implement the system from scratch. Otherwise, you can temporarily give items to the player such as Goat Head or Rosary Bead, or use things like Game.SetLastDevilRoomStage(), Level.SetRedHeartDamage(), and Level.AddAngelRoomChance(). You also might want to use LevelStateFlags.

How do I create a new floor/level/stage?⚓︎

Unfortunately, Isaac does not natively support modded custom floors. BudJMT and DeadInfinity have built a custom system called StageAPI that allows mods to add custom floors in a hacky way. However, StageAPI is not easy to use, so unless you are already an experienced Isaac modder & coder, you should stick to more simple projects.

How do I make the costume on my custom character persistent?⚓︎

Use Sanio's "Character Costume Protector" library for this, or study the source code and re-implement it yourself.

For a reference implementation, see Andrew the Bunny Knight.

What does the "[INFO] - [warn] item pool ran out of repicks" message mean in the "log.txt" file?⚓︎

This message means that the game attempted to get a new random collectible type from an item pool, but the item pool was all out of items. When an item pool is depleted like this, the game reverts to getting a random collectible from the Treasure Room pool instead, since that is the default pool. In the case that the Treasure Room pool itself was depleted, then the game will return CollectibleType.COLLECTIBLE_BREAKFAST instead.

If your mod is causing this message, it is likely a sign that you have a problem in your logic somewhere. Perhaps you are spawning a ton of random collectibles by accident, which would subsequently deplete the room's item pool. You might also want to examine the logic in any MC_PRE_GET_COLLECTIBLE or MC_POST_GET_COLLECTIBLE callbacks.


Last update: August 12, 2024