A turn-based farming RPG.
There is some strong language in the game's text, as well as in some of the source code because I am 12 years old and think seeing a rabbit say bad words is funny.
This game's source code is licensed with the GNU Affero General Public License. All art assets are licensed with the CC BY-SA 4.0 License.
Sometimes I make choices. They aren't always good ones.
Running a npm install should get you pretty much everything you need to build this. It's all node based. You'll need ffmpeg for one of the (optional) build steps, though. All build scripts are in the tools directory.
Builds collision data based off the files in tools/collisionimg, which are in turn generated from BuildImages.js. tools/cave.png is also converted into collision data.
Collision datas are arrays of bools, where true means a tile is solid and cannot be walked through. In the image files, a tile will be read as true if the corresponding pixel is #FF0000 and false otherwise.
Cave Collision is more complicated and the structure is described in the comments of the BuildCaveCollisions function.
Builds enemy attack flows based off the files in tools/enemyjson, which are in turn generated with kelly.
Generate PNGs from the contents of the tools/ora folder. With no parameters passed it should generate every image needed for the game.
The following arguments can be supplied (all .ora files referenced are in tools/ora):
bg: Copies all layers fromcombatbg.orainto separate PNGs inimg/bgs.profile: Copies all layers fromportraits.ora(except ones with names starting with "_") into separate PNGs inimg/profiles.maps: Goes through all files intools/ora/mapsand populatesimg/maps,img/fg, andtools/collisionimgbased on their layers. Maps are generated from all layers not prefixed with_exceptForegroundandCollision. Foregrounds are generated from theForegroundlayer, and collision images are generated from theCollisionlayer. If a map has cover layers, they should be named with the_Cover:xxxconvention and specified in thecoversvariable in theRipMapsfunction in the format of"mapName": ["xxx"]. A few custom rules exist for handling thenorthcityandhq_IBmaps.cavecollisions: Buildstools/cave.pngused forBuildCollisions.js.basics: Equivalent to passing all of thetools/orafilenames at once (see next item).- Pretty much any of the files in
tools/orawithout their file extensions: Copies theContentlayer of each file (ex.sheetmaps tosheet.ora) intoimg/.
TODO: shop_XXX.ora, logo.ora, colorPreview.ora, and endcredits.ora files still require manual export.
Copies all images from img into imggb after converting them to a 4-color monochrome color scheme.
TODO: Sprites FarmInfo%, MetalInfo%, BtlSel%, CornerBtn%, and %Sel% must be manually set to the maximum brightness. TODO: Sprites %cursor%.% and optTile must be manually corrected.
Generates game data from the spreadsheets in the tools/ods folder. With no parameters passed it should generate all data needed for the game.
The following arguments can be supplied (all .ods files referenced are in tools/ods, all .js files referenced are in js/gamedata unless otherwise specified):
T: Convert rows fromDetails_Text.odsinto thefulltextmap intext.js. Spreadsheet is one header row and then several rows with the following columns:Key: The reference key for the line of text.noTrim: If not set, the end of the line of text will be trimmed off.profile: The name of the profile image to show if this text is displayed in world map dialogue.type: How the text is used in game. For reference; not used in-game.en-us: The English translation of the text.en-us-sfw: The profanity-free English translation.any other language: Other languages can be defined afteren-usanden-us-sfw, one per column. If a value does not exist in this language, the game will default to theen-ustranslation. Note: there is no way to change languages in-game at this time.
S: Converts rows fromDetails_Cutscenes.odsinto thescriptsmap incutscenes.js. Spreadsheet is one header row and rows withKeyandActioncolumns.Keyis the in-game reference key, andActionis a&-separated list of commands that are parsed injs/worldmap/cutsceneParser.js.C,Q,F,E: Rips crops, equipment, fixtures, and enemies into their respective files injs/gamedata.P: Converts cells fromDetails_BigSprites.odsandDetails_SmallSprites.odsinto thespritesmap inspritedata.js. For each cell with coordinates(x, y)and a valuev, they will be converted to the a key-value pair of the format"v": [x, y], or"v": [x, y, true]for cells ripped fromDetails_BigSprites.ods.
Run with node tools/Cordova.js ARG where ARG can be:
copy: Copies all production files to the cordova/www folder for building with Cordova.build: Build, sign, and zipalign the APK.all: Copy and build.
For the build step, you will need to create a tools/creds.js file that looks like this to package your Cordova app:
module.exports = {
store: "full path to your .keystore file",
name: "your key name",
pass: "your store password",
jarsigner: "full path to your jarsigner executable, or just 'jarsigner' if it's in your PATH",
zipalign: "full path to your zipalign executable, or just 'zipalign' if it's in your PATH",
};Generates upscaled spritesheets for optional in-game graphical filters. Requires ffmpeg for hq4x and scale2x for s4xe. You may need to update the s2xpath variable for s4xe.
Concatenates all source files into one out.js file. Calling it with the min argument will also minify it.
Calling gulp watch will ensure Package.js is executed every time a source file is updated.
These will create the instruction manual/strategy guide, with most data pulled straight from the game's code. Run BuildManualParts.js to populate the manual/parts folder with relevant metadata needed to generate the guide, and run BuildManual.js to populate the manual/out folder with the manual.html file and relevant images in the manual/out/assets folder.
All enemies, crops, fixtures and equipment are pulled from the game code. The instruction manual is hard-coded in manual/parts/template.html. Much of Calsotte's buffs and the Locations are hard-coded in the BuildManual.js file, as are the names of specific achievements and enemies for the purposes of skipping some and marking them as spoilers. Pretty much all map/level data is hard-coded.
Running node BuildManual.js maps will create the map images used in the guide - this should be done the first time you run this, but won't be needed afterwards unless you change how the maps look.
Run node tools/Package.js to build everything. All standard spritesheets and game datas are pre-built in the the git repository, but if you have made changes, you will need to run the appropriate script described above. Likewise, if you wish to include the filtered sprites, you will need to run node tools/FormatImages.js. After building, run index.html in your browser to play.
Run node tools/Cordova.js all or if you want to do the building manually:
node tools/Cordova.js copy
cd cordova
cordova build android --release
cd platforms/android/app/build/outputs/apk/release
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore [yourKeyStore] app-release-unsigned.apk [yourKey]
zipalign -v 4 app-release-unsigned.apk Uprooted.apk
If you want to make a version for other Cordova platforms like iOS or something, check out Cordova's documentation for how to add new platforms to a project. There is little custom Cordova code, so it is unlikely that anything in the existing codebase is Android specific.
Complete all the Standard Build steps above.
Dev Build: npm start
Package Only: npm pack
Package for Distribution: npm run dist
The game isn't even done yet hold your horses yo.
Pretty much all sound effects are taken from 512 Sound Effects (8-Bit Style) by Juhani Junkala and are licensed under the CC 1.0 Universal License.