Hi! This API allows you to interact with my save editor, allowing you to make macros like the one below. Check the sidebar for specific documentation.

  • this describes the API calls for the yokai editor (available through devtools console once the save is loaded).
  • this! describes the API calls for the key items editor (again, available through devtools console once the save is loaded).
  • thiswow! describes the API calls for the general editor (again, AGAIN, available through devtools console once the save is loaded).

Anyway, here are the examples :)

Examples

Yo-kai Example #1: Maxes out the legal IVs, EVs, SCs, Level, Attack, Technique and Soul levels along with hp remaining and soul bar:

function randomLegalIVs(yokai, ivTotalTarget = 40) {
    // Get current IVs to check if its already legal
    let IV_HP = yokai.get("IV_HP");
    let IV_Str = yokai.get("IV_Str");
    let IV_Spr = yokai.get("IV_Spr");
    let IV_Def = yokai.get("IV_Def");
    let IV_Spd = yokai.get("IV_Spd");

    let IV_Sum = Math.floor(IV_HP / 2) + IV_Str + IV_Spr + IV_Def + IV_Spd;

    // Checks if IV_HP even and sum matches target
    let needsFix = (IV_HP % 2 !== 0) || (IV_Sum !== ivTotalTarget);

    while(needsFix) {
        // ivs array: [IV_HP/2 units, IV_Str, IV_Spr, IV_Def, IV_Spd]
        let ivs = [0, 0, 0, 0, 0];

        // Distribute ivTotalTarget points randomly over 5 stats (IV_HP counted as half units)
        for (let i = 0; i < ivTotalTarget; ++i) {
            let r = Math.floor(Math.random() * 5);
            ivs[r]++;
        }

        // Set the IVs. Remember that the HP IV is worth half
        yokai.set("IV_HP", ivs[0] * 2);
        yokai.set("IV_Str", ivs[1]);
        yokai.set("IV_Spr", ivs[2]);
        yokai.set("IV_Def", ivs[3]);
        yokai.set("IV_Spd", ivs[4]);
        let needsFix = (IV_HP % 2 !== 0) || (IV_Sum !== ivTotalTarget); // recheck
    }
}

// Get the 1st yokai in a lazy way
let firstYokai = getAllYokai()[0];

// Max level
firstYokai.set("level", 99); // max level - in comp it gets restricted to lvl60 anyway

// Random legal IVs MUST total 40 points (HP is worth half which indirectly forces HP to be even and usually makes it the highest IV)
randomLegalIVs(firstYokai);

// Max EVs
firstYokai.set("EV_HP", 127); // max - the change is minor so everything is considered legal iirc
firstYokai.set("EV_Str", 127);
firstYokai.set("EV_Spr", 127);
firstYokai.set("EV_Def", 127);
firstYokai.set("EV_Spd", 127);

// Max SCs
firstYokai.set("SC_Str", 25); // SC goes from -10 to 25
firstYokai.set("SC_Spr", 25);
firstYokai.set("SC_Def", 25);
firstYokai.set("SC_Spd", 25);

// Max HP and Soul
firstYokai.setHelper.energy.HP.set(32767); // 16-bit int limit (may be signed?)
firstYokai.setHelper.energy.Soul.set(250); // iirc never goes higher than 150 lol but just to be safe

// Max special unlocks
firstYokai.setHelper.specialUnlock.attackLevel.set(10); // max level
firstYokai.setHelper.specialUnlock.techniqueLevel.set(10); // max level
firstYokai.setHelper.specialUnlock.soultimateLevel.set(10); // max level

console.log("First Yo-kai maxed with legal-ish stats!");

Yo-kai Example #2: The inner workings of the copy-paste button (requires API v1.1)



function copy() {
    const slotIndex = currentSlot();
    if (slotIndex === null) {
        alert("No Yo-kai slot selected to copy");
        return;
    }
    window.copiedYokaiSlot = slotIndex;
    console.log(`Copied Yo-kai from slot ${slotIndex}`);
}

function paste() {
    if (window.copiedYokaiSlot === undefined) {
        alert("No Yo-kai copied");
        return;
    }
    
    const targetSlot = currentSlot();
    if (targetSlot === null) {
        alert("No target slot selected");
        return;
    }
    
    copyYokaiSlot(window.copiedYokaiSlot, targetSlot);
    syncSave();
}

function copyYokaiSlot(sourceIndex, targetIndex) {
    let yokaiList = getAllYokai();
    if (sourceIndex < 0 || sourceIndex >= yokaiList.length) {
        console.error("Invalid source slot:", sourceIndex);
        return;
    }
    if (targetIndex < 0 || targetIndex >= yokaiList.length) {
        console.error("Invalid target slot:", targetIndex);
        return;
    }
    
    // Get raw hex for the source Yo-kai
    let fieldsToCopy = [
        "num1", "num2", "youkaiId", "nickname", "unused1", "specialUnlock",
        "expPoint", "energy", "ownerId", 
        "IV_HP", "IV_Str", "IV_Spr", "IV_Def", "IV_Spd",
        "EV_HP", "EV_Str", "EV_Spr", "EV_Def", "EV_Spd",
        "SC_Str", "SC_Spr", "SC_Def", "SC_Spd",
        "unknown", "level", "special6", "loafAndAi", "specialEquip"
    ];

    fieldsToCopy.forEach(field => {
        try {
            let raw = yokaiList[sourceIndex].getRaw(field);
            yokaiList[targetIndex].setRaw(field, raw);
        } catch (e) {
            console.warn(`Skipping field '${field}' (reason: ${e.message})`);
        }
    });

    console.log(`Copied Yo-kai from slot ${sourceIndex} to slot ${targetIndex}`);
}

Key items Example #1 Shuffles Item Order

// Simple Item Randomizer Example
// Swaps item IDs between all non-empty slots to randomize inventory order

function randomizeItems() {
    // Check if save is loaded
    if (!SaveAPI.isLoaded) {
        console.log("Please load a save first!");
        return;
    }
    
    // Get all non-empty items
    const items = SaveAPI.getAllItems().filter(item => item.itemId !== 0);
    
    if (items.length < 2) {
        console.log("Need at least 2 items to randomize!");
        return;
    }
    
    // Extract item IDs and shuffle them
    const itemIds = items.map(item => item.itemId);
    
    // Simple shuffle (Fisher-Yates)
    for (let i = itemIds.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [itemIds[i], itemIds[j]] = [itemIds[j], itemIds[i]];
    }
    
    // Apply shuffled IDs back to original slots (keeping nums)
    for (let i = 0; i < items.length; i++) {
        SaveAPI.setItem(items[i].index, {
            num1: items[i].num1,    // Keep original num1
            num2: items[i].num2,    // Keep original num2
            itemId: itemIds[i]      // Use shuffled ID
        });
    }
    
    // Update the UI
    SaveAPI.updateUI();
    
    console.log(`Randomized ${items.length} items!`);
}

console.log("Item randomizer loaded! Use: randomizeItems()");

Table of contents