Blåhaj's InfiniteBox Modding Guide

Welcome to the modding guide for InfiniteBox! This guide will help you get started with creating your own content for the game.

This guide is compatible with InfiniteBox v0.0.5

Prerequisites

Mod Structure

Mods are located in the MODS folder in the game's root directory.

InfiniteBox/
├── MODS/
│   └── MyAwesomeMod/
│       ├── infinitemod.json
│       ├── scripts/
│       │   └── MyMod.cs
│       └── resources/
│           └── sprites/
│               └── my_actor.png

Metadata (infinitemod.json)

Every mod requires an infinitemod.json file in its root.

This file defines your mod's name, author, description, and version.

{
  "name": "My Awesome Mod",
  "author": "YourName",
  "description": "Adds cool new things to the game!",
  "version": "1.0.0"
}

To add an Icon, add icon.png to the root of the mod's folder.

Available Builders

The game uses a builder pattern to register new content. Click any card to jump to its documentation.

Source Code (scripts/)

All .cs files in the scripts/ folder will be compiled at runtime.

The Entry Point (Core)

Create a class named Core inheriting from MonoBehaviour. You should register your content in Start() using a static initialization guard.

using UnityEngine;

public class Core : MonoBehaviour
{
    private static bool _initialized = false;

    void Start()
    {
        if (_initialized) return;
        
        // Wait for ArtifactManager
        if (ArtifactManager.Instance == null) return;

        _initialized = true;
        RegisterMyContent();
        Debug.Log("Mod Registered!");
    }
}

Important: Avoid UI Refresh

Do not use SendMessage("Start") on the UI. This will re-create every button in the game, leading to duplicates. By registering in the Core class using the pattern above, the game will load your buttons correctly when the UI first appears.

The MapRun Entry Point

While Core runs once at launch, the game looks for a class named exactly MapRun every time a new map/world is loaded.

public class MapRun : MonoBehaviour {
    void Start() {
        // This runs every time a map is generated or loaded.
        // Great for spawning initial units or modifying the world.
        Debug.Log("A new world has been born!");
        ActionLibrary.SpawnActor("cool_slime", new Vector3Int(128, 128, 0));
    }
}

Core vs MapRun

Class Execution Timing Primary Use
CoreOnce (Game Launch)Registering Artifacts (Actors, Items, Tabs)
MapRunOn Map LoadWorld logic, spawning bosses, map modifications

The Artifact System

Everything in InfiniteBox is an Artifact. Register them using the ArtifactManager.

Debugging & Troubleshooting

The game doesn't have a visible console. Use this Log class to print debug messages to a file in the game root.

using System.IO;
using System;

public static class Log {
    private static string _path = "mod_debug.log";
    public static void Write(string msg) {
        File.AppendAllText(_path, $"[{DateTime.Now:HH:mm:ss}] {msg}\n");
    }
}

The F12 Console

You can access a hidden debug console by pressing F12 in-game. However, be warned: it's questionable at best. It may be unstable or display incomplete information cuz Tux can't be fuckin bothered ig.

Advanced Troubleshooting

Full Mod Example

This is a professional Core.cs template. It uses static guards to prevent double-registration and includes a custom logger for debugging.

using UnityEngine;
using System.IO;
using System;
using System.Linq;

public class Core : MonoBehaviour {
    private static bool _initialized = false;

    void Start() {
        if (_initialized) return;
        if (ArtifactManager.Instance == null) return;
        _initialized = true;

        Log.Write("Mod Init Started");
        
        // 1. Register a Custom Tab
        ArtifactManager.Instance.Register(new TabBuilder("mod_tab")
            .SetName("My Mod")
            .SetIcon(ModUtils.LoadResource<Sprite>("MyMod", "ui/tab"))
            .Build());

        // 2. Register Custom Names
        ArtifactManager.Instance.Register(new NameBuilder("mod_names")
            .SetGroup1("Gloop", "Blorp")
            .SetGroup2("the Sticky")
            .UseSpaces()
            .Build());

        // 3. Register a Custom Actor
        ArtifactManager.Instance.Register(new ActorBuilder("mod_actor")
            .SetName("Sticky Slimer")
            .SetStat("health", 100)
            .SetStat("speed", 1.5f)
            .SetSprite(ModUtils.LoadResource<Sprite>("MyMod", "mobs/slimer"))
            .Configure(a => a.nametemplateid = "mod_names")
            .Build());

        // 4. Register a God Power
        ArtifactManager.Instance.Register(new GodpowerBuilder("gp_spawn")
            .SetName("Spawn Slimer")
            .SetBrushBased(false)
            .SetInterval(0.1f)
            .SetAction((pos, tile, power) => {
                ActionLibrary.SpawnActor("mod_actor", pos);
            })
            .Build());

        // 5. Add Button to Tab
        ArtifactManager.Instance.Register(new ButtonBuilder("btn_spawn")
            .SetTab("mod_tab")
            .SetIcon(ModUtils.LoadResource<Sprite>("MyMod", "ui/btn"))
            .SetGodpowerId("gp_spawn")
            .Build());

        Log.Write("Mod Init Finished");
    }
}

public static class Log {
    public static void Write(string msg) {
        File.AppendAllText("mod_debug.log", $"[{DateTime.Now:HH:mm:ss}] {msg}\n");
    }
}

Content Creation

Custom Actors (Mobs)

Create new entities like humans, animals, or monsters by using the ActorBuilder.

void RegisterActor()
{
    ArtifactManager.Instance.Register(new ActorBuilder("my_cool_mob")
        .SetName("Cool Mob")
        .SetStat("health", 100)
        .SetStat("speed", 3.0f)
        .SetSprite(ModUtils.LoadResource<Sprite>("MyMod", "sprites/my_actor"))
        .SetSizeID("human_size")
        .SetSpeciesID("human_species")
        .SetNameTemplate("human_names") // New in v0.0.5
        .IsBlob(false) // New in v0.0.5
        .AddTrait("strong") // New in v0.0.5
        .AddBehavior(new WanderBehavior { roamRadius = 10f })
        .Build());
}

Custom AI Behaviors

Create complex logic and decision making for your actors by defining custom behavior classes.

public class MyCustomBehavior : AIBehavior
{
    public override AIIntent? ProposeIntent(Actor actor, float deltaTime)
    {
        if (!actor.blackboard.TryGet<Vector3>("targetPos", out var target)) {
            target = actor.position + new Vector3(5, 0, 0);
            actor.blackboard.Set("targetPos", target);
        }
        return new AIIntent { type = AIIntentType.Wander, target = target, priority = 2.0f };
    }
}

Behavior Sets (v0.0.5)

You can bundle AI behaviors into a reusable BehaviorArtifact. This allows you to apply multiple behaviors to an actor or profession at once.

ArtifactManager.Instance.Register(new BehaviorBuilder("aggressive_set")
    .AddBehavior(new CombatBehavior { detectionRange = 50f })
    .AddBehavior(new WanderBehavior { roamRadius = 2f })
    .Build());

Custom Buildings

Buildings are structures where actors can live, work, or store resources. They are linked to Eras and Categories.

ArtifactManager.Instance.Register(new BuildingBuilder("stonefactory")
    .SetName("Stone Factory")
    .SetDescription("Produces basic tools and items.")
    .AddResourceToBuild("wood", 15)
    .SetStat("health", 20)
    .SetStat("defense", 5)
    .SetCanBeBuilt(true)
    .SetEra(Era.Stone)
    .SetCategory(BuildingCategory.Production)
    .Build());

Note: Building sprites are loaded procedurally from resources/Buildings/[ID]/main.png.

Advanced: Custom Eras

Because Era is a fixed C# Enum, you cannot add new ones directly through scripts. To create a "custom" era, it is recommended to use one of the later unused eras (like GodTechFuture) or use a SpeciesTrait as a technology requirement check in your Core logic.

Actor Traits

Define unique modifiers that can be applied to actors to change their stats or visuals.

ArtifactManager.Instance.Register(new ActorTraitBuilder("super_speed")
    .SetName("Super Speed")
    .SetStat("speed", 10f)
    .SetIcon(ModUtils.LoadResource<Sprite>("MyMod", "ui/traits/speed"))
    .SetCategory(ActorTraitCategory.Body)
    .Build());

Custom Illnesses (v0.0.5)

Create diseases that can spread between actors and cause various effects.

ArtifactManager.Instance.Register(new IllnessBuilder("my_plague")
    .SetName("The Gloop Virus")
    .SetDescription("Makes everyone turn green and sticky.")
    .SetContagious(true)
    .SetTransmission(0.5f) // 50% chance to spread per tick
    .SetFunctionBegin(actor => {
        Debug.Log($" {actor.actorName} has caught the Gloop!");
    })
    .SetFunctionNorm(actor => {
        // Runs every second while infected
        actor.currentHealth -= 1;
    })
    .AddCarrierSpecies("sheep_species")
    .AddInfectedSpecies("human_species")
    .Build());

Actors can be infected via code using actor.Infect("illness_id").

Items & Recipes

Create craftable items and define the resources needed to produce them.

ArtifactManager.Instance.Register(new ItemBuilder("magic_crystal")
    .SetName("Magic Crystal")
    .SetDescription("A glowing gem filled with energy.") // New in v0.0.5
    .SetStat("value", 50) // New in v0.0.5
    .SetIcon(ModUtils.LoadResource<Sprite>("MyMod", "items/crystal"))
    .SetRecipe(new ItemRecipe {
        resultItem = "magic_crystal",
        ingredients = new List<ItemCost> { new ItemCost { id = "gold", amount = 10 } }
    })
    .Build());

Custom Biomes

Define new world tile types with unique background colors, vegetation, and resource yields.

ArtifactManager.Instance.Register(new BiomeBuilder("frost")
    .SetTiles(new List<Sprite> { ModUtils.LoadResource<Sprite>("My Mod", "tiles/snow") })
    .SetFarColor("#FFFFFF")
    .SetFarColor2("#E0E0E0") // New in v0.0.5
    .SetSparse(true) // New in v0.0.5: Less dense vegetation
    .OceanBiome(false) // New in v0.0.5: Is this an ocean?
    .SetTrees("pine_tree")
    .AddResource("ice", 5) // New in v0.0.5: Resource yield/cost
    .Build());

Biome Groups (v0.0.5)

Group biomes together for planet generation.

ArtifactManager.Instance.Register(new BiomeGroupBuilder("cold_group")
    .AddBiomeId("frost")
    .AddBiomeId("tundra")
    .Build());

Planets & Systems

Configure custom celestial bodies and star systems for space exploration.

ArtifactManager.Instance.Register(new PlanetBuilder("planet_crystal")
    .SetName("Crystal Wastes")
    .SetBiomeGroup("temperate")
    .SetRarity(8)
    .Build());
ArtifactManager.Instance.Register(new SystemBuilder("purple_nebula")
    .SetName("Purple Nebula")
    .SetColor("#A020F0")
    .SetRarity(9)
    .Build());

Trees

Create interactive vegetation that actors can harvest for resources.

ArtifactManager.Instance.Register(new TreeBuilder("magic_tree")
        .SetHealth(100)
        .SetSprite(ModUtils.LoadResource<Sprite>("MyMod", "trees/magic_tree"))
        .SetBigSprite(true) // New in v0.0.5: Use larger rendering bounds
        .SetSizeID("large") // New in v0.0.5
        .AddResource("wood", 25)
        .Build());

Professions

Define jobs that actors can perform, linked to specific behaviors and buildings.

ArtifactManager.Instance.Register(new ProfessionBuilder("miner")
    .SetName("Miner")
    .SetRequiredBuilding("mine_building")
    .AddBehavior(new MiningBehavior())
    .Build());

Name Generation

Configure custom naming patterns and species definitions for your world.

ArtifactManager.Instance.Register(new NameBuilder("slime_names")
    .SetGroup1("Gloop", "Blorp")
    .SetGroup2("the Sticky", "the Slimy")
    .SetGroup3("Junior", "Senior") // New in v0.0.5
    .UseSpaces()
    .Build());

Species Configuration (v0.0.5)

Configure base race definitions, technology levels, and specialized buildings.

ArtifactManager.Instance.Register(new SpeciesBuilder("alien_species")
    .SetName("Xenomorph")
    .AddTrait("acidic_blood")
    .AddOpp("human_species") // New in v0.0.5: Natural enemies
    .AddBuilding("hive_nest") // New in v0.0.5: Species-specific buildings
    .SetEras(false) // New in v0.0.5: Toggle tech progression
    .Build());

Custom Tabs

You can create entirely new categories in the bottom menu bar.

ArtifactManager.Instance.Register(new TabBuilder("magic_tab")
    .SetName("Magic")
    .SetDescription("Spells and mystical things")
    .SetIcon(ModUtils.LoadResource<Sprite>("My Mod", "ui/magic_icon"))
    .Build());

Custom Buttons

Buttons can be added to any existing tab or a custom tab. They can either activate a Godpower or run a custom C# function.

// 1. A button that activates a Godpower
ArtifactManager.Instance.Register(new ButtonBuilder("btn_spawn")
    .SetName("Spawn Unit")
    .SetDescription("Spawns a unit at the cursor")
    .SetTab("spawning")
    .SetIcon(ModUtils.LoadResource<Sprite>("MyMod", "ui/btn"))
    .SetType(CoolButton.ButtonType.Godpower)
    .SetGodpowerId("gp_spawn")
    .Build());

// 2. A button that runs a custom function
ArtifactManager.Instance.Register(new ButtonBuilder("btn_custom")
    .SetName("Custom Action")
    .SetTab("other")
    .SetIcon(Resources.Load<Sprite>("items/axe"))
    .SetType(CoolButton.ButtonType.Click)
    .SetFunction(() => {
        Debug.Log("Hello from a custom button!");
    })
    .Build());

Custom Assets

Assets like Sprites should be placed in the resources/ folder of your mod. Use ModUtils.LoadResource<T>(modName, path) to load them.

Sprite Loading Example

Folder Structure:

MODS/
└── MyMod/
    └── resources/
        └── mobs/
            └── slime_blue.png

Code Usage:

// Load the sprite (omit the extension .png)
Sprite slimeSprite = ModUtils.LoadResource<Sprite>("MyMod", "mobs/slime_blue");

// Use it in a builder
ArtifactManager.Instance.Register(new ActorBuilder("blue_slime")
    .SetName("Blue Slime")
    .SetSprite(slimeSprite)
    .Build());

Animations

InfiniteBox does not currently support multi-frame sprite animations. Instead, the game uses a procedural animation system in ActorView to give units life:

When creating a mod, you only need to provide a single static sprite. The game handles the rest automatically!

Stats Reference

Actors and Buildings use stats to define their properties. Health and Speed are required for all actors.

Actor Stats Reference

health (Int): Total hitpoints. Unit dies if this is 0.

speed (Float): Movement speed across tiles. Standard units use 2.0.

vision_range (Float): The radius (in tiles) within which the unit detects enemies, mates, or resources.

attack_range (Float): The distance required to strike an enemy. (Melee is usually 1.1).

attack_damage (Int): Damage dealt per attack cycle.

Building Stats Reference

health (Int): Hitpoints of the structure.

defense (Int): Flat damage reduction for the building.

AI Behavior Reference

Built-in AI logic that you can add via .AddBehavior(). These can be combined to create complex entity logic.

Behavior Class Description
CoreBehaviorBasic survival and age logic.
CombatBehaviorDetection, attacking, and retreating from enemies.
ReproduceBehaviorFinding mates and producing offspring.
WanderBehaviorIdle roaming within a defined radius.
ResourceGatherBehaviorSearching for and harvesting resources.
NationBehaviorLogic for interacting with nation systems.
CivBehaviorCivilian logic like building or working.
SheepBehaviorSpecific logic for sheep (passive roaming).
BlobBuddingReproduction logic for blobs.
BlobMassGaining size/mass from consumption.
BlobTreeInteraction between blobs and trees.
BlobmegaPrimeAdvanced AI for Mega Blobs.
BlobmegaMassMass accumulation for Mega Blobs.
BlobzillaBehaviorBoss-level AI for Blobzilla.
ConstructionWorkerBehaviorLogic for building structures.
FactoryWorkerLogic for working in production buildings.
BabyBehaviorLogic for children following parents.
GuardMateProtection behavior for nearby allies.
TreeFuckingOptimized tree harvesting logic.

Vanilla Reference Guide

Use these IDs and paths when referencing vanilla content in your builders or using Resources.Load<Sprite>("path").

Vanilla Actors

IDNameSprite Path
humanHumanactors/human/human
peanutPeanutactors/peanut/Peanut_guy
sheepSheepactors/sheep/sheepy
blobBlob(Procedural)
blobmegaMEGA BLOBactors/blobmega/blobmega
blobzillaBlobzillaactors/blobzilla/blobzilla

Vanilla Biomes & Trees

Biome IDTreesDescription
grasswisp, whirly, whipLush green fields.
sandcacti1-4Desert wasteland.
rockwisp, whirly, whipMountainous terrain.
peanutpetree1-2The realm of peanuts.
ocean(None)Deep blue water.

Vanilla Items

Item IDTypeIcon Path
woodResourceitems/wood
goldCurrencyitems/gold
ironResourceitems/iron
copperResourceitems/copper
axeWeaponitems/axe

Vanilla UI Tabs

Tab IDNameIcon Path
mainMainui/tabs/Infinite
spawningMobsactors/human/human
landscapingLandscapingui/tabs/landscaping
nationsNationsui/tabs/Nations
disastersDisastersui/tabs/Disasters
spaceSpaceui/tabs/Space

Vanilla Buildings

Building IDCategoryDescription
campfire(Core)The heart of a nation.
hutHomeA small residential shelter.
stonefactoryProductionProduces basic stone tools.

Building Categories

Used in .SetCategory(BuildingCategory.[Type]).

CategoryPurpose
HomeResidential structures where actors sleep and store food.
CommercialEconomic structures for trade and gathering wealth.
ProductionIndustrial structures like factories or workshops.
MilitaryDefensive or offensive structures like barracks or walls.

Eras & Technology

Used in .SetEra(Era.[Type]). Progress is linear.

Era NameTechnical ID
Stone AgeStone
Medieval AgeMedieval
High MedievalHigh
RenaissanceRenaissance
Industrial EraIndustrial
Machine AgeMachine
Atomic AgeAtomic
Modern EraModern
Information AgeInformation
ContemporaryContemporary
Space AgeSpace
HyperwarHyperwar
Cyber EraCyber
InterstellarInterstellar
HyperfutureHyperfuture
God TechGodTechFuture

Tips & Tricks

InfiniteBox Studio

Hey! There is also a Block-Based Mod Maker (EXPERIMENTAL) available if you want to build mods visually without writing code.

Open Mod Maker