Skip to content

iJDN/underclone

Repository files navigation

Underclone

Preamble and Purpose

Preamble

Underclone is an Underhand Clone for the PC, built in Love2D and open source, it aims to provide the same gameplay and feel as the original on mobile.

"Underhand is a CCG (Cultist Card Game) that puts you into the role of a cult leader. Your job is to manage your cult's resources effectively as you respond to different event cards drawn from the deck. How you respond to these events will determine how far you'll go-- will you succeed in summoning one, or maybe even all of the Ancient Ones? Or will you be just another would-be upstart falling prey to the trials and tribulations of time? Only you can decide!"

Underhand is a free mobile game which has no ads and no in app purchases, I highly reccomend checking out the original

If you are from SpoopySquad and have any issues with this clone please reach out and I will take action. I love your game and wanted to provide more options for people to discover, play, and potentially expand upon it.

I have not decompiled the code for the original game at this time - and have created this clone based on my many hours of playtime and research in how the game works. - While I believe this knowledge to be enough to be faithful, there may be some small innacurracies.

Purpose

This project was created as a learning task for myself to create games not just using love2D but in general.

While I have a technical profession and do create code and scripts, this is not exactly my field.

Code may not be the most efficient or immaculate, but I atleast aim to make it functional, modular, and understandable enough to modify from its groundwork, potentially opening the door for new content such as Gods, Events, and Resources to be created by not just me, but others.

Fixes and Changes

I do not intend to replicate bugs from the original. These include events completing without taking/giving resources, and visual bugs such as foresight displaying on the wrong layer. These are (hopefully) fixed in Underclone and was part of the reason for me choosing to create a PC clone in the first place.

While I want this to feel as tactile and play as well and accurately as the original, I also aim to fix minor things in the game/provide QoL, However I intend to allow these to be toggled off if you want the pure experience

These include

  • foresight - when using foresight at the end of your deck you lose the resource and the deck starts shuffling without viewing any cards.
    • This always felt unfair to me - there are arguments to be made that perhaps you should be counting the cards to know when youre near the end, but forcing the player to memorise their whole deck isnt "fun" as a gameplay tool
    • heres the idea to fix this
      • implement a deck counter ui element that simply states how many cards are left before a reshuffle, this would allow you to still use the resource (perhaps if youre one resource away from greed, or its your only event which allows you to get rid of food while the milkman keeps forcing it on you) while also knowing that you will not recieve foresight
      • other ideas included making foresight cards never be the last card, making ones that cost, cost nothing (or less) if it is the last card, whiting out the cost if it a forsight card with a cost.
  • Tactile Feel - While dragging cards in and out of the play area and scrolling the rounded deck will always be a large part of what made the original feel so tactile, I have included some optional control methods which benefit from being on the PC platform
    • key binds
      • I have included some keybinds for tasks such as selecting, deselecting, and mass movement of cards. It is entirely the players choice to use these.
        • [S] Select Hovered Card (Place Into Play Area)
        • [D] Deselect Hovered Card (Remove From Play Area)
        • [SPACE] Deselect All Cards (Remove All From Play Area)
    • Card displays
      • due to the landscape orientation provided by most configurations of PC monitors,it is possible to see much more of the hand at once this allows for a straight hand rather than a rounded rotating one - as of now this is the only hand display option but I do plan to make the original an option in future.

Release

A windows executable is provided in releases. Just extract the content and run the executable.

(Obligatory Im a Linux user line, I will create a linux executable if there is enough demand)

If you have love2d installed you can also clone this repo and launch it directly with love using love . in the same directory.

There is a web version available on itch io - https://ijdn.itch.io/underclone please keep in mind that this is highly untested may have bugs seperate from the executable release. This version is not a focus, but a nice option if it works.

By request of the developers, Underhands original art and sounds will not be used. I am not an artist, however some early art has been created by SentientCrumb (So far just the resource cards). Work is being done to have more new artwork in the game.

Modding

Part of this project goals was to create a clone of underhand which is easy for people to create their own gods, events and blessings.

Folder Structure

love executables are just fancy zip files. To create a mod open the executable with a zip editor (such as winrar, 7zip or ark (linux)) and insert a folder in the mods folder with the structure seen below

if you are just running the cloned repo with love . the mods folder is readily available

Files and folders in the format <name> can be renamed to whatever you want

<modName>/
├─ common/
│  ├─ <commonCard>.lua
│  ├─ <anotherCommonCard>.lua
├─ chained/
│  ├─ <chainedCard>.lua
│  ├─ <anotherChainedCard>.lua
├─ gods/
│  ├─ <godName>/
│  │  ├─ blessings/
│  │  │  ├─ <blessing1>.lua
│  │  │  ├─ <blessing2>.lua
│  │  ├─ summon/
│  │  │  ├─ <startingEvent>.lua

Common: These are cards that can be put into the deck randomly at the start of the run. e.g Travelling Salesperson, Potion Vendor, Tax Day. If you want the card to potentially appear in any run this is the place for it.

Chained: These are cards that are created from other cards. e.g Harvest, Tea, Spoils of War. If the card is created or even respawned e.g aeromancy by another card at any point it should be in here.

Blessings: These are the cards that are included in the deck when selecting the god they are attached to. While all gods in the base game only have 2 blessings, this implementation supports any number of blessings.

Summon: This is the initial card that is put into the deck to begin the summon chain for this god. There should be only one of these cards per god. All further events in the summon chain should be in the chained folder.

File Structure

The format for the cards in the game is a port of the original games cardwip.json seperated out into lua tables

I will run through the basics here

  • Cases where an integer is treated as a boolean It will be marked as a BOOL in the comment
    • 1 = true
    • 0 = false
  • Cases where an integer is treated as a value it will be marked as VAL in the comment
importingTea = { --initiate the table with the name of the card,
                    --this index is used to call it if its a chain card
    title = "Importing Tea", -- Title printed on the card in game
    flavortext = "Mysterious teas from far away lands", -- Flavour Text printed on the card in game (optional)
    option1 = {
        optiontext = "Buy a shipment", -- Printed at the top of the option
        outputtext = "Insert 'Tea'", -- Printed at the bottom of the option (optional)
        cultistequalsprisoner = 0, -- BOOL Dictates whether cultists and prisoners are interchangeable
        foresight = {
            hasforesight = 0, -- BOOL Dictates whether the card has foresight
            candiscard = 0 -- BOOL Dictates whether the foresight effect can discard cards
        },
        shuffle = {
            lowerbound = 115, --UNUSED
            upperbound = 118, --UNUSED
            specificids = { "tea1", "tea2", "tea3", "tea4" }, -- List of card IDs which can be shuffled into the deck
            allowsdupes = 0, -- BOOL Dictates whether the insertion can have duplicate cards
            numcards = 1 -- VAL how many of the cards to randomlu shuffle into the deck
                            -- do not exceed the amount of IDs if dupes are disabled
        },
        randomrequirements = 0, -- VAL if this is anything more than 0 the requirements table will be randomized to have a total equalling this value. e.g Greed has a value of 5
        requirements = { -- VAL how many of each requirement to take
            relic = 0,
            money = 1,
            cultist = 0,
            prisoner = 0,
            food = 0,
            suspicion = 0
        },
        rewards = { -- VAL how many of each requirement to give
            relic = 0,
            money = 0,
            cultist = 0,
            prisoner = 0,
            food = 0,
            suspicion = 0
        },
        iswin = "", -- name of the God this summons (if applicable)
        islose = 0 -- BOOL does this end the run
    },-- to make an unselectable option make optiontext blank, outputtext blank and 0 out the rewards and requirements
    option2 = { [REDACTED FOR BREVITY] }, -- replica of option1 with different values
    option3 = { [REDACTED FOR BREVITY] }, -- replica of option1 with different values
    isinitial = 0, -- BOOL unused in this implementation (for now) was essentially used to denote a common card (no need to change)
    isrecurring = 0, -- BOOL Denotes whether this card is shuffled back into the deck or removed from play
    weight = 10, -- VAL how much more likely this card will be at the top of the deck after a shuffle.
                    -- Default value is 10. very few cards use this mechanic.
},

return importingTea

Each lua file contains 1 lua table containing the data for the card.

The file should be named after the name it should be called in game

This is most important for chained cards and blessings but should be applied overall for consistency.

e.g if you have a card which adds another card with specificids = {"myCard"} the file for the new card should be called myCard.lua

An example mod has been included in this repo and the release build. Mods are turned off by default so dont worry about it affecting your default experience unless you specifically want to enable it.

As of right now blessings are not included as the God selection menu needs to be rebuilt dynamically. Common, Chained and Summon Cards work as intended however.

Credits

  • Programming:

    • JDN
  • Art:

    • SentientCrumb (twt: @sentientcrumb)
  • Music:

    • Dances and Dames - Kevin Macleod
  • Sounds:

  • Original Concept:

    • Underhand - SpoopySquad
  • Special Thanks:

    • Underhand and Underhand RAVAMPED discord communities
      • For being an awesome community and helping to answer the questions I couldnt find answers to.
    • underhand.clanweb.eu
      • For being a great resource on the history and inner workings of Underhand

License

  • Code: Licensed under CC BY-NC 4.0 — you can use and modify the code for non-commercial purposes only.
  • Images: © SentientCrumb, All Rights Reserved — not for reuse or redistribution.
  • Sounds: “54 Casino Sound Effects” by Kenney (CC0 1.0) — free to use.
  • Music: “Dances and Dames” by Kevin MacLeod (CC BY 3.0) — must credit the author.

See LICENSE.md for code license details and CREDITS.md for sound/music attributions.

About

An Underhand clone written in love2d

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages