Balatro Steamodded Mod Installation Guide

VUjOlQM.jpeg


After some tinkering, Steamodded now launches on the switch version of Balatro! Here's the guide!

Prerequisites:
  • A legal switch copy of Balatro
  • A modded Nintendo Switch
  • A valid python install
  • A computer, preferably Windows, but works on any OS

Limitations:
  • Lovely is not supported on the Switch, so mods that require it will NOT work.
  • Limited to mods that function on 0.9.8 version of sMOD. You may need to find an older version of a mod to use it.
  • Card suit customization introduced in version 1.0.1g (Friends of Jimbo, v1.0.7) will not work.

Installation Instructions:
  1. Download the SteamoddedNX repo by clicking the green Code button near the top and clicking Download ZIP, and extract it somewhere safe.
  2. Dump your current update of Balatro, in NCA FS or romFS format using your favorite NX dump tool.
  3. Once complete, connect your SD card to your computer, navigate to the dumped update location. Copy the Patch RomFS folder to inside your repo extraction folder. Now enter the folder and ZIP the contents of the Patch RomFS into a standard ZIP, ensuring that your ZIP contains the dumped files at the root, and are NOT nested in an additional folder inside the ZIP.
  4. Copy your dumped ZIP inside the safe location of your extracted repo on your computer.
  5. The script requires one package to run, open your terminal and run: python -m pip install requests
  6. Drag the ZIP onto SteamoddedNX_injector.py and wait for the injector to complete. If you see Process completed successfully. Press any key to exit... then continue, if not, check your zip structure.
  7. Extract the contents of the modded ZIP into the included \atmosphere\contents\0100CD801CE5E000\romfs directory.
  8. This step is not needed but if you would like to see exact crash errors from your mods: while in your romfs folder, open globals.lua and jump to line 62 self.F_NO_ERROR_HAND = Now replace true with false
  9. Copy your prepped atmosphere folder to your switch SD card and ensure Balatro launches and functions with the included example mods! More mods can be found below.

Where to Find Additional Mods:

Discord is bad for listing mods but heres the invite link to access the thread. Remember to ask for help HERE on GBATemp and not on the discord!


How to Install a Mod:
  • Find and download a sMOD 0.9.8 compatible mod (see Limitions.)
  • Navigate to your Mods directory (see the installation instructions.)
  • Put the mod into that directory (The mod can be a single file if there is only one file provided, or it can be a whole folder.)
  • Launch the game and enjoy!

More specific information can be found on the github page created here: https://github.com/JonJaded/SteamoddedNX/ Enjoy!
 
Last edited by JonJaded,

JonJaded

Well-Known Member
OP
Member
Joined
May 22, 2016
Messages
717
Trophies
0
XP
3,309
Country
United States
Updated Jaded's 0.9.8 Mod collection v2. :)

If there are any major compatability issues or problems let me know! Remember most of these mods are technically outdated, so don't bug the creators with issues for their older versions, bug me!
 
  • Like
Reactions: Dewid

batouttahell24

Member
Newcomer
Joined
May 12, 2024
Messages
9
Trophies
0
Age
27
XP
32
Country
United States
Dumped my game just like stated in this guide and it didn't work. From what I could see from the quickprompt flas (and slowing down a video), it's throwing a "ModuleNotFound" error because it can't find a module named "requests".

Note that I did install Python before doing this so I have no idea what the issue is.
Post automatically merged:

Nevermind, I just manually installed the requests.
 
Last edited by batouttahell24,

Steamo

Member
Newcomer
Joined
Oct 4, 2015
Messages
7
Trophies
0
Age
27
XP
55
Country
France
Hey, I'm Steamo the creator of Steamodded.

Very cool project I love it.

We don't speak a lot about porting Steamodded/Lovely into other platform, outside of some Linux Proton support (because LocalThunks asked us to keep this type of discussion outside of the official Discord server, probably to not have issue with some external actors like Nitendo hehe), but I may start to look into it more deeply.

For Lovely, we are currently discussing some changes permitting to use it on Android/IOS but everything is yet to be done. The new structure however can probably be helpful for your project and may make it compatible.

For Steamodded, I'm thinking about creating a Fork aimed for other systems (And this fork can so be forked by other projects targeting a specifc env). The aim would be to use some kind of reworked injector 0.9.8 style, that will load Lovely modules. Then, Lovely will be able to inject all other .toml defined rules into the game. I still need to dive into it and see if it's possible, but it's absolutly in my BackLog.

With few words: It would make pure Lovely Mods and Steamodded 1.0.x-alpha mods compatibles with the Switch version!
 
  • Love
Reactions: JonJaded

NotXeroShi

Member
Newcomer
Joined
Jun 3, 2017
Messages
11
Trophies
0
Age
30
XP
96
Country
United States
Find and download a sMOD 0.9.8 compatible mod (see Limitions.)
I am interested in knowing the limitations. I just installed a mod (Hand Preview) that is for v1.0.0, but it just barely works on my switch. It crashes once the cursor goes over it and I'm just curious on why's that.

Edit:
Is it me, or is the Deck Builder mod crashing whenever you try to create a deck?
 
Last edited by NotXeroShi,

JonJaded

Well-Known Member
OP
Member
Joined
May 22, 2016
Messages
717
Trophies
0
XP
3,309
Country
United States
Hey, I'm Steamo the creator of Steamodded.

Very cool project I love it.

We don't speak a lot about porting Steamodded/Lovely into other platform, outside of some Linux Proton support (because LocalThunks asked us to keep this type of discussion outside of the official Discord server, probably to not have issue with some external actors like Nitendo hehe), but I may start to look into it more deeply.

For Lovely, we are currently discussing some changes permitting to use it on Android/IOS but everything is yet to be done. The new structure however can probably be helpful for your project and may make it compatible.

For Steamodded, I'm thinking about creating a Fork aimed for other systems (And this fork can so be forked by other projects targeting a specifc env). The aim would be to use some kind of reworked injector 0.9.8 style, that will load Lovely modules. Then, Lovely will be able to inject all other .toml defined rules into the game. I still need to dive into it and see if it's possible, but it's absolutly in my BackLog.

With few words: It would make pure Lovely Mods and Steamodded 1.0.x-alpha mods compatibles with the Switch version!
Hey Steamo lovely seeing you here! Thanks, I'm glad you actually like this little hackjob. I didn't want to bring this to your attention as to not heavily distract you with supporting a much older version of you project and to respect localthunk as well as the discord rules of course, but alas, here you are. Your remedy sounds perfect. Switch and mobile platforms are clearly the platforms that would benefit the most. Obviously take your time but yeah, that load order sounds way more beneficial.

I'll say it again, it's was pleasently amazing seeing how universal and dynamic Steamodded is designed, and how it was relatively simple making a port. Great engine, great mod. I've already seen the talks on getting lovely and steamodded running on Linux, you guys work hard. Thank you again.
Post automatically merged:

Dumped my game just like stated in this guide and it didn't work. From what I could see from the quickprompt flas (and slowing down a video), it's throwing a "ModuleNotFound" error because it can't find a module named "requests".

Note that I did install Python before doing this so I have no idea what the issue is.
Post automatically merged:

Nevermind, I just manually installed the requests.
Okay thanks for letting me know, I can add that req to the guide. Problem is, I've had python for so long I don't know what I have installed already. :rofl:

I am interested in knowing the limitations. I just installed a mod (Hand Preview) that is for v1.0.0, but it just barely works on my switch. It crashes once the cursor goes over it and I'm just curious on why's that.

Edit:
Is it me, or is the Deck Builder mod crashing whenever you try to create a deck?
I actually got Deck builder mod to work for me. But it did crash with one specific modded voucher, the that fills your voucher slots. I think it was a race condition of it trying to fill and redeem as soon as the game started. I'll need to go back and find which one- I believe it's from betmna voucher. But if there are others that crash send me your attempted created deck and I can take a look.

As for Hand Preview, the reason it's crashing is likely because of the move window function. I'll take a look at it and see if just commenting out that feature stops it from crashing. If you have crash reports enabled you can take a screenshot and send it to me. Just post here.

I finally got my OLED switch functioning again so I'll have more time to mess around again.

Also forgot to announce I updated my modlist with links to the direct release or commit of the last compatible version, and if it can be updated in the future or not.

If you have any issues just discuss here and I'll take a look when I can.
 
Last edited by JonJaded,

NotXeroShi

Member
Newcomer
Joined
Jun 3, 2017
Messages
11
Trophies
0
Age
30
XP
96
Country
United States
I actually got Deck builder mod to work for me. But it did crash with one specific modded voucher, the that fills your voucher slots. I think it was a race condition of it trying to fill and redeem as soon as the game started.
That's weird then, since it crashes as soon as I press "Create deck", I don't have that many mods besides some of the defaults plus a few more. Here's a crash with the deck builder mod and another one and the crash with hand preview
If you need me to list the mods I also have installed, I can do that as well. But this is just the errors I have been receiving
Okay thanks for letting me know, I can add that req to the guide. Problem is, I've had python for so long I don't know what I have installed already.
I also forgot to mention that when you try to use the python script on MacOS, it doesn't work because of something relating to "7zz", it works fine on windows enough but getting the script to work with my limited python knowledge was a little hard
 

JonJaded

Well-Known Member
OP
Member
Joined
May 22, 2016
Messages
717
Trophies
0
XP
3,309
Country
United States
That's weird then, since it crashes as soon as I press "Create deck", I don't have that many mods besides some of the defaults plus a few more. Here's a crash with the deck builder mod and another one and the crash with hand preview
If you need me to list the mods I also have installed, I can do that as well. But this is just the errors I have been receiving

I also forgot to mention that when you try to use the python script on MacOS, it doesn't work because of something relating to "7zz", it works fine on windows enough but getting the script to work with my limited python knowledge was a little hard

Go into Balalib.lua and comment out lines 396 to line 410. The mod attempts to show a desktop cursor[?] Which isn't possible on 0.9.7. But as you said, with that fixed it works well.

Code:
--- STEAMODDED HEADER
--- MOD_NAME: BalaLib
--- MOD_ID: balalib
--- MOD_AUTHOR: [Toeler]
--- MOD_DESCRIPTION: A core library providing common features to other mods. v1.0.0
--- PRIORITY: -10

----------------------------------------------
------------MOD CODE--------------------------

function SMODS.INIT.balalib()
    local TAG = 'BalaLib'

    local balalib_mod = SMODS.findModByID("balalib")
    local s_sprites = SMODS.Sprite:new("balalib_sprites", balalib_mod.path, "sprites.png", 32, 32, "asset_atli")
    s_sprites:register()

    local function get_lock_icon(ui_box, is_locked)
        if is_locked == nil then
            is_locked = not ui_box.states.drag.can
        end

        local _x = is_locked and 0 or 1
        local icon = Sprite(0, 0, 0.2, 0.2, G.ASSET_ATLAS["balalib_sprites"], { x = _x, y = 0 })
        icon.states.drag.can = false
        return icon
    end

    local function get_anchor_icon(ui_box, anchor)
        local x_index = {
            ["Top Right"] = 3,
            ["Right"] = 4,
            ["Bottom Right"] = 5,
            ["Bottom"] = 6,
            ["Bottom Left"] = 7,
            ["Left"] = 8,
            ["Top Left"] = 9,
            ["Top"] = 10
        }

        if anchor == nil then
            anchor = ui_box.states.anchor or x_index[1]
        end

        local _x = x_index[anchor]
        local icon = Sprite(0, 0, 0.2, 0.2, G.ASSET_ATLAS["balalib_sprites"], { x = _x, y = 0 })
        icon.states.drag.can = false
        return icon
    end

    function UIBox:remove_UIE_by_ID(id, node)
        if not node then node = self.UIRoot end

        if node.config and node.config.id == id then
            node:remove()
            return true
        end

        local childIndex = nil
        for k, v in pairs(node.children) do
            if v.config and v.config.id == id then
                childIndex = k
                break
            end
        end

        if childIndex then
            node.children[childIndex]:remove()
            table.remove(node.children, childIndex)
            return true
        else
            for k, v in pairs(node.children) do
                local removed = self:remove_UIE_by_ID(id, v)
                if removed then return true end
            end
        end

        return nil
    end

    MoveableContainer = UIBox:extend()
    function MoveableContainer:init(args)
        if args.config.locked == nil then
            args.config.locked = true
        end
        if args.config.anchor == nil then
            args.config.anchor = "Top Right"
        end

        local settings_icon = Sprite(0, 0, 0.2, 0.2, G.ASSET_ATLAS["balalib_sprites"], { x = 2, y = 0 })
        settings_icon.states.drag.can = false

        local function get_lock_tooltip()
            return {
                n = G.UIT.R,
                nodes = {
                    {
                        n = G.UIT.T,
                        config = {
                            text = 'Position: ' .. (self.states.drag.can and 'Unlocked' or 'Locked'),
                            scale = 0.15,
                            colour = G.C.UI.TEXT_DARK
                        }
                    },
                }
            }
        end

        local btn_lock = {
            n = G.UIT.C,
            config = {
                id = 'btn_lock',
                colour = { 1, 1, 1, 0.010001 },
                padding = 0.01,
                r = 0.1,
                hover = true,
                button = 'bl_toggle_moveablecontainer_lock',
                button_dist = 0,
                tooltip = { filler = { func = get_lock_tooltip } }
            },
            nodes = {
                { n = G.UIT.O, config = { id = 'icon', object = get_lock_icon(self, args.config.locked) } }
            }
        }

        local function get_anchor_tooltip()
            return {
                n = G.UIT.R,
                nodes = {
                    {
                        n = G.UIT.R,
                        nodes = {
                            {
                                n = G.UIT.T,
                                config = {
                                    text = 'Anchor: ' .. tostring(self.states.anchor),
                                    scale = 0.15,
                                    colour = G.C.UI.TEXT_DARK
                                }
                            },
                        }
                    },
                    {
                        n = G.UIT.R,
                        nodes = {
                            {
                                n = G.UIT.T,
                                config = {
                                    text = 'Click to cycle window anchor point',
                                    scale = 0.15,
                                    colour = G.C.UI.TEXT_DARK
                                }
                            },
                        }
                    }
                }
            }
        end

        local btn_anchor = {
            n = G.UIT.C,
            config = {
                id = 'btn_anchor',
                colour = { 1, 1, 1, 0.010001 },
                padding = 0.01,
                r = 0.1,
                hover = true,
                button = 'bl_cycle_anchor_point',
                button_dist = 0,
                tooltip = { filler = { func = get_anchor_tooltip } }
            },
            nodes = {
                { n = G.UIT.O, config = { id = 'icon', object = get_anchor_icon(self, args.config.anchor) } }
            }
        }

        local function get_settings_tooltip()
            return {
                n = G.UIT.R,
                nodes = {
                    {
                        n = G.UIT.T,
                        config = {
                            text = 'Settings',
                            scale = 0.15,
                            colour = G.C.UI.TEXT_DARK
                        }
                    },
                }
            }
        end

        local btn_settings = {
            n = G.UIT.C,
            config = {
                id = 'btn_settings',
                colour = { 1, 1, 1, 0.010001 },
                padding = 0.01,
                r = 0.1,
                hover = true,
                button = 'bl_open_settings',
                button_dist = 0,
                tooltip = { filler = { func = get_settings_tooltip } }
            },
            nodes = {
                { n = G.UIT.O, config = { id = 'icon', object = settings_icon } }
            }
        }

        args.definition = {
            n = G.UIT.ROOT,
            config = {
                align = 'tr',
                colour = G.C.CLEAR,
            },
            nodes = {
                {
                    n = G.UIT.C,
                    config = {
                        align = "cm",
                        padding = 0.1,
                        mid = true,
                        r = 0.1,
                        colour = { 0, 0, 0, 0.1 }
                    },
                    nodes = {
                        {
                            n = G.UIT.R,
                            config = {
                                align = 'cr',
                            },
                            nodes = {
                                {
                                    n = G.UIT.C,
                                    config = {
                                        id = "header_container",
                                    },
                                    nodes = {
                                        args.header or nil
                                    }
                                },
                                {
                                    n = G.UIT.C,
                                    config = {
                                        minw = 0.1,
                                    },
                                    nodes = {}
                                },
                                {
                                    n = G.UIT.C,
                                    config = {
                                        id = "button_container",
                                    },
                                    nodes = {
                                        {
                                            n = G.UIT.R,
                                            nodes = { args.config.settings_func and btn_settings or nil, btn_lock, btn_anchor }
                                        }
                                    }
                                }
                            }
                        },
                        {
                            n = G.UIT.R,
                            nodes = args.nodes or {}
                        }

                    }
                }
            }
        }

        UIBox.init(self, args)

        self.states.drag.can = not args.config.locked
        self.states.anchor = args.config.anchor

        self:set_relative_pos(args.T.x or args.T[1] or self.T.x, args.T.y or args.T[2] or self.T.y)

        self.attention_text = 'MoveableContainer' -- Workaround so that this is drawn over other elements

        local header_container = self:get_UIE_by_ID('header_container')
        local header_align = header_container.align
        header_container.align = function(self, x, y)
            -- Left-align header while controls are right-aligned
            header_align(header_container, 0, y)
        end

        local btn = self:get_UIE_by_ID('btn_anchor')
        local btn_click = btn.click
        btn.click = function()
            btn_click(btn)
        end
        local is_hover = false
        local btn_hover = btn.hover
        btn.hover = function()
            is_hover = true
            btn_hover(btn)
        end
        local btn_stop_hover = btn.stop_hover
        btn.stop_hover = function()
            btn_stop_hover(btn)
            is_hover = false
        end

        if args.config.instance_type then
            table.insert(G.I[args.config.instance_type], self)
        else
            table.insert(G.I.UIBOX, self)
        end

        sendDebugMessage("MoveableContainer:init", TAG)
    end

    function MoveableContainer:remove()
        sendDebugMessage("MoveableContainer:remove", TAG)
        UIBox.remove(self)
    end

    function MoveableContainer:calculate_xywh(node, _T, recalculate, _scale)
        local old_rel_x, old_rel_y = self:get_relative_pos()
        local old_w, old_h = self.T.w, self.T.h

        local new_w, new_h = UIBox.calculate_xywh(self, node, _T, recalculate, _scale)


        if node == self.UIRoot and (new_w ~= old_w or new_h ~= old_h) then
            self:set_relative_pos(old_rel_x, old_rel_y)

            if G.SETTINGS.paused then
                self:hard_set_T(self.T.x, self.T.y, self.T.w, self.T.h)
            end
        end

        return new_w, new_h
    end

    function MoveableContainer:update(dt)
        UIBox.update(self, dt)
        self:get_UIE_by_ID('button_container').states.visible = self.states.collide.is
    end

    function MoveableContainer:set_relative_pos(x, y)
        local new_x, new_y = x, y

        if not self.states.anchor then
            return
        end

        if string.find(self.states.anchor, "Top") then
            -- Do nothing (y is correct)
        elseif string.find(self.states.anchor, "Bottom") then
            new_y = y - self.UIRoot.T.h
        else -- Mid
            new_y = y - self.UIRoot.T.h / 2
        end

        if string.find(self.states.anchor, "Left") then
            -- Do nothing (x is correct)
        elseif string.find(self.states.anchor, "Right") then
            new_x = x - self.UIRoot.T.w
        else -- Center
            new_x = x - self.UIRoot.T.w / 2
        end

        self.T.x = new_x
        self.T.y = new_y
    end

    function MoveableContainer:get_relative_pos()
        local x, y = self.T.x, self.T.y

        if not self.states.anchor then
            return x, y
        end

        if string.find(self.states.anchor, "Top") then
            -- Do nothing (y is correct)
        elseif string.find(self.states.anchor, "Bottom") then
            y = y + self.UIRoot.T.h
        else -- Mid
            y = y + self.UIRoot.T.h / 2
        end

        if string.find(self.states.anchor, "Left") then
            -- Do nothing (x is correct)
        elseif string.find(self.states.anchor, "Right") then
            x = x + self.UIRoot.T.w
        else -- Center
            x = x + self.UIRoot.T.w / 2
        end

        return x, y
    end

--    function MoveableContainer:hover()
--        if self.states.drag.can then
--            local sizeall_cursor = love.mouse.getSystemCursor("sizeall")
--            love.mouse.setCursor(sizeall_cursor)
--        end
--
--        UIBox.hover(self)
--    end

--    function MoveableContainer:stop_hover()
--        local arrow_cursor = love.mouse.getSystemCursor("arrow")
--        love.mouse.setCursor(arrow_cursor)
--
--        UIBox.stop_hover(self)
--    end

    function MoveableContainer:bl_toggle_lock()
        self.states.drag.can = not self.states.drag.can

        local btn_lock = self:get_UIE_by_ID("btn_lock")
        self:remove_UIE_by_ID('icon', btn_lock)

        local new_icon = get_lock_icon(self)
        self:add_child({ n = G.UIT.O, config = { id = 'icon', object = new_icon } }, btn_lock)

        btn_lock:stop_hover()
        btn_lock:hover()
    end

    function MoveableContainer:bl_cycle_anchor_point()
        local function get_next_anchor(anchor)
            local anchor_points = {
                "Top Right",
                "Right",
                "Bottom Right",
                "Bottom",
                "Bottom Left",
                "Left",
                "Top Left",
                "Top"
            }

            if not anchor then
                return anchor_points[1]
            end

            for i, a in ipairs(anchor_points) do
                if a == anchor then
                    return anchor_points[i % #anchor_points + 1]
                end
            end

            error('Unknown anchor point ' .. tostring(self.states.anchor))
        end

        self.states.anchor = get_next_anchor(self.states.anchor)

        local btn_anchor = self:get_UIE_by_ID('btn_anchor')
        self:remove_UIE_by_ID('icon', btn_anchor)

        local new_icon = get_anchor_icon(self)
        self:add_child({ n = G.UIT.O, config = { id = 'icon', object = new_icon } }, btn_anchor)

        btn_anchor:stop_hover()
        btn_anchor:hover()
    end

    function MoveableContainer:bl_open_settings()
        if self.config and self.config.settings_func then
            self.config.settings_func('exit_overlay_menu')
        end
    end

    local function bl_toggle_moveablecontainer_lock(UIE)
        if not UIE or not UIE.UIBox then
            return
        end
        UIE.UIBox:bl_toggle_lock()
    end
    G.FUNCS.bl_toggle_moveablecontainer_lock = bl_toggle_moveablecontainer_lock

    local function bl_cycle_anchor_point(UIE)
        if not UIE or not UIE.UIBox then
            return
        end
        UIE.UIBox:bl_cycle_anchor_point()
    end
    G.FUNCS.bl_cycle_anchor_point = bl_cycle_anchor_point

    local function bl_open_settings(UIE)
        if not UIE or not UIE.UIBox then
            return
        end
        UIE.UIBox:bl_open_settings()
    end
    G.FUNCS.bl_open_settings = bl_open_settings
end

----------------------------------------------
------------MOD CODE END----------------------

As for Deck Creator, when I touch the create deck button, it works, but if I try to do it with gamepad I run into a crash. I'll have to see how it works with docked but I assume it'll be that cursor crash again. Another mod that's sensitive to cursors it seems. :unsure: But once the deck is created it works without issue. Boy is that annoying.
 

NotXeroShi

Member
Newcomer
Joined
Jun 3, 2017
Messages
11
Trophies
0
Age
30
XP
96
Country
United States
Go into Balalib.lua and comment out lines 396 to line 410. The mod attempts to show a desktop cursor[?] Which isn't possible on 0.9.7. But as you said, with that fixed it works well.
This fixed it, thank you!
As for Deck Creator, when I touch the create deck button, it works, but if I try to do it with gamepad I run into a crash. I'll have to see how it works with docked but I assume it'll be that cursor crash again. Another mod that's sensitive to cursors it seems
I rarely touch the screen when it comes to playing balatro but I can confirm it does work as long as you don't use the gamepad
 
  • Like
Reactions: JonJaded

MarlbororMan420

Member
Newcomer
Joined
Nov 10, 2024
Messages
7
Trophies
0
Age
19
XP
47
Country
United States
Hi, hate to open up this thread again but I can't figure out something about this guide. In step 3, it mentions a "Patch RomFS Folder" and I have no idea what it's referring to. I'm still a relative novice in switch modding so it's probably on my part, but I just can't figure out what step 3 is really telling me to do. There isn't a folder named Patch RomFS anywhere in the Steamodded package or in my update dump. Any help would be greatly appreciated. Thanks.
 

JonJaded

Well-Known Member
OP
Member
Joined
May 22, 2016
Messages
717
Trophies
0
XP
3,309
Country
United States
Hi, hate to open up this thread again but I can't figure out something about this guide. In step 3, it mentions a "Patch RomFS Folder" and I have no idea what it's referring to. I'm still a relative novice in switch modding so it's probably on my part, but I just can't figure out what step 3 is really telling me to do. There isn't a folder named Patch RomFS anywhere in the Steamodded package or in my update dump. Any help would be greatly appreciated. Thanks.
Make sure you're using the rewrite poc nxdumptool. The steps are:

Open NXDumptool_rw_poc
Select User titles menu
Select 0100CD801CE5E000 - Balatro
Select nca / nca fs dump options
Select dump update
Press Y to set the dump mode into nca fs selection mode (so if its selected correctly, you'll see "raw nca mode", because the mode that is currently selected is nca fs mode, which is what you want.)
Select Program #0
Select FS selection #2 Patch RomFS
Start NCA fs dump.

Your files will dump to nxdt_rw_poc/NCA FS/User/Extracted/Balatro [...]/

Not gonna lie, I thought I was more comprehesive when I made the guide but thank you for letting me know it wasn't completely clear.

The only reason there are this many steps is because I don't know how thunk would feel about pieces of game code being redistributed, so I feel like its better to shift to the end user (sorry!)
Post automatically merged:

I also forgot to mention that when you try to use the python script on MacOS, it doesn't work because of something relating to "7zz", it works fine on windows enough but getting the script to work with my limited python knowledge was a little hard
Ah I forgot to mention that macOS support isn't implemented. I believe linux should work... I'll change that as well.
 
Last edited by JonJaded,
  • Like
Reactions: Dewid

MarlbororMan420

Member
Newcomer
Joined
Nov 10, 2024
Messages
7
Trophies
0
Age
19
XP
47
Country
United States
I hate to be the guy who asks multiple questions, but I'm super new to all this and I really wanna get this to work. So again, sorry, but I have another question.
Step 5 I just do not understand at all what it's asking me to do.
Again, very sorry for asking a whole entire second question, but I'm stumped again. I think after that I'll be able to figure it out but need more clarification here.
Post automatically merged:

I hate to be the guy who asks multiple questions, but I'm super new to all this and I really wanna get this to work. So again, sorry, but I have another question.
Step 5 I just do not understand at all what it's asking me to do.
Again, very sorry for asking a whole entire second question, but I'm stumped again. I think after that I'll be able to figure it out but need more clarification here.
Also clarifying this isn't a fault of the guide, this is on me not fully understanding because I'm still new to this.
 
Last edited by MarlbororMan420,

MarlbororMan420

Member
Newcomer
Joined
Nov 10, 2024
Messages
7
Trophies
0
Age
19
XP
47
Country
United States
Ok I figured that last step out, I didn't have python installed and couldn't open it. Silly me.
But
When I drag the zip file onto the injector, it immediately opens and closes without doing anything. Same thing happens when I try to open the injector file on its own.
Anyone have any idea what I should do from here?
I am so sorry I'm asking so many questions I feel like I'm being annoying but I'm so lost lol
 

Chellarina

Member
Newcomer
Joined
Aug 4, 2011
Messages
6
Trophies
1
XP
22
Country
Ok I figured that last step out, I didn't have python installed and couldn't open it. Silly me.
But
When I drag the zip file onto the injector, it immediately opens and closes without doing anything. Same thing happens when I try to open the injector file on its own.
Anyone have any idea what I should do from here?
I am so sorry I'm asking so many questions I feel like I'm being annoying but I'm so lost lol

Hi, don't want to be THAT person but as long as you can afford it, if you're struggling that much, maybe just buy a PC version instead?

Even if you want to play on android, the process of extracting the PC version from Steam or similar and running it on android is gonna be infinitely more simple than ripping a switch game.

I think it's cool that things like this exist, and morally we have every right to play our software where we want, but sometimes the simplier option with the least downsides is to get your wallet out, especially for a relatively cheap indie game. Nothing personal, I just don't see the point struggling with something like this if you're not already comfortable with pseudo programming tasks.
 

MarlbororMan420

Member
Newcomer
Joined
Nov 10, 2024
Messages
7
Trophies
0
Age
19
XP
47
Country
United States
Hi, don't want to be THAT person but as long as you can afford it, if you're struggling that much, maybe just buy a PC version instead?

Even if you want to play on android, the process of extracting the PC version from Steam or similar and running it on android is gonna be infinitely more simple than ripping a switch game.

I think it's cool that things like this exist, and morally we have every right to play our software where we want, but sometimes the simplier option with the least downsides is to get your wallet out, especially for a relatively cheap indie game. Nothing personal, I just don't see the point struggling with something like this if you're not already comfortable with pseudo programming tasks.
I get this suggestion completely, but I've just got a laptop, and it has a hard time really running anything, so it's easier to go through all the trouble trying to mod the switch version imo
 

JonJaded

Well-Known Member
OP
Member
Joined
May 22, 2016
Messages
717
Trophies
0
XP
3,309
Country
United States
When I drag the zip file onto the injector, it immediately opens and closes without doing anything. Same thing happens when I try to open the injector file on its own.
Are you on mac? Someone else said they have problems with mac. You can try one of these injectors for mac, but I have no way to test. https://github.com/Steamopollys/Steamodded/issues/23#issuecomment-2033283714

And are you sure you're dragging it onto the steammoddednx.py? You can send the error output by:
Opening a cmd prompt in the directory (or just cd-ing there)
then running
py steamodded_injector.py balatro.zip
they should be in the same folder
I also forgot to mention that when you try to use the python script on MacOS, it doesn't work because of something relating to "7zz", it works fine on windows enough but getting the script to work with my limited python knowledge was a little hard
Maybe if Xeroshi has some time they could check for us.
 

Dewid

New Member
Newbie
Joined
May 29, 2024
Messages
4
Trophies
0
Age
37
XP
36
Country
Germany
I got the error that the steamoddedNX_injector.py does not exist or can't be opended.

Then i moved my SteamoddedNX-main folder to the Python Scrips folder and got a new error

ImportError: No module named requests

I installed that module with Windows Terminal:

"C:\Users\XXX\AppData\Local\Programs\Python\Python313\Scripts\pip3 install requests"

And now it worked.

*edit

But Balatro is crashing after the loading screen.
 
Last edited by Dewid,

JonJaded

Well-Known Member
OP
Member
Joined
May 22, 2016
Messages
717
Trophies
0
XP
3,309
Country
United States
I got the error that the steamoddedNX_injector.py does not exist or can't be opended.

Then i moved my SteamoddedNX-main folder to the Python Scrips folder and got a new error

ImportError: No module named requests

I installed that module with Windows Terminal:

"C:\Users\XXX\AppData\Local\Programs\Python\Python313\Scripts\pip3 install requests"

And now it worked.

*edit

But Balatro is crashing after the loading screen.
Oops, I wrote it down in my notepad to edit the guide and tell people to install the requests package and never did it. I'll do that when I get back.

As for your cras, do step 7 to enable the crash screen and tell me whats wrong.
 
  • Like
Reactions: Dewid

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Psionic Roshambo @ Psionic Roshambo: https://m.youtube.com/shorts/grwnjZRWmMg