Welcome to Farm with Code

In this game your task is to program a drone so it does farming and earns money for you. Epic battles, challenging monsters, amazing graphics, nostalgic music - all of these you'll find in some other game. In this one you'll write code in JavaScript.

This game is not for everyone: it requires you to code, which not everyone can (and probably not everyone wants after a 72 hours of jamming) and it will take a relatively large (on jam game scale) amount of time to understand how it works, but if the idea of coding a farming drone sounds interesting - give it a try and let me know what you thing in the comments. Don't hesitate to ask questions - I'll answer all!

Before you start

Paste better starting code: Gist to the editor. It is mostly the same, but it properly loops (farms and earns money indefinitely).

You don't need to read this whole doc before you start playing, but I suggest you skim through the headlines to get familiar with what's in the doc in case you need it later

Basic gameplay

Move around map with WASD or arrow keys (map view needs to be focused - click on it). Press "Center" if you ever lose your island out of view (yeah, I had a big vision).

Press "Patch" to update your drone with the current version of the code in the editor.

Be sure to play in fullscreen for more available space (Itch button at the bottom right of the game window).

You can also change the vertical split of left/right (map/editor) views. There is a small icon at the bottom right of map view, which you can drag left/right to adjust horizontal sizes.

Warning

Game doesn't save it's state, but code is always auto-saved.

You can try to regenerate map if you want and tinker with numerous params, but be aware that any tiny move of any slider (except "Moisture" group) will wipe the current state (except code) and regenerate world from scratch.

Most notably, you might want to test out various seeds: Map Gen => Island => Seed

How it was made (video)

As you see, this is a pretty advanced game. If you are interested in a more advanced game-dev (unlike "I added this cube to the scene, it was super hard" kind of devlogs), you might like my YouTube channel:

Videos take a ton of work, so I don't post often (yet), but I hope I'll manage to make a video about this game, so if that sounds interesting and you liked the video about the maze - subscribe:)

But I don't know JavaScript

If you are coming from C#/C++/Java, you should get the hang out JavaScript pretty quickly. Most things are the same:

a = b * c + d * e // Variable assignment and expressions
if (cond) { } else { } // Conditions
while (cond) { } // Loops
array[20] // Array indexing
obj.x // Object field access
Math.cos(0) // Calling functions

Here are the most notable differences to get quickly up to speed:

  • No typings in JavaScript
  • You define variables with `let` (normal variable) or `const` (constant):
// C#:
float x = length * Math.cos(angle);
// JavaScript
const x = length * Math.sin(angle)
let y;
  • Defining functions is different:
// C#:
float multiply(float a, float b) { return a * b; }
// JavaScript: 
function multiply(a, b) { return a * b; }
// Or (shorter syntax):
const multiply = (a, b) => a * b;
  • Creating arrays is different:
// C#: 
new int[] { 1, 2, 3, 4 }
// JavaScript
[ 1, 2, 3, 4 ]
  • You can just create objects "out of thin air", no need to pre-define classes, structs and other stuff:
// C#:
struct Point {
    float x;
    float y;
}
// later:
var point = new Point { x = 10, y = 20 };
// JavaScript:
let point = { x: 10, y: 20 };

Logging

You can log into the console with:

console.log(obj1, obj2, obj3)
console.warn(1009, 'is prime')
console.error('something went wrong', 5 * 9)

It will output in your browser console (not in-game console), open it with "Right Click on empty space -> Inspect element" or Ctrl+Shift+I. There are some commented out debug console.log's in the starter code.

Starter code

The only two functions you need to code are at the end of the file: "start" and "update".

`drone` object provides you with very barebones control like setting motor "force", but if you want to fly to some point, you have to program it yourself, same if you want to sequence some "jobs" (e.g. fly to (200, 160) then plant). It's similar in this regard to programming AI for your game: game engine provides you with minimal per-frame control and it's your task to keep track of what AI does to make sure it finishes jobs and not switches them every frame.

The starter code contains this functionality for higher level drone control with job sequencing, but you don't have to use it. If implementing job/time-sequencing system sounds interesting, you can remove all of the starter code and start from scratch:

function start(drone) { }
function update(drone) { }

Moving

Fly to given point once
flyToJob(100, 200)
// Patrols infinitely between given points
patrolJob({x: 0, y: 10}, {x: 300, y: 20}, {x: 30, y: 400})

Buying and selling

// Buy maximum possible (money-wise and inventory-capacity-wise) amount of specified item
buyMaxJob('orangeSeed')
// Buys up to specified amount of specified item
buyUpToJob('orangeSeed', 5)
// Sells all of the specified item
sellMaxJob('orange')
// Note, example code buys 'orangeSeed', but sells 'orange' - those are different items

Watering

// The next two are without parameters,
// because they act on the current location
intakeWaterJob // intake water until waterContainer is full
outtakeWaterJob // outtake water until waterContainer is empty
// fly to given point then intake water
intakeWaterAtJob(300, 400)
// Water plants while patrolling between two given points
waterLineJob(new Point(10, 40), new Point(10, 200))

Planting and extracting

plantJob('orangeSeed') // Plants given seed at the current tile
plantAtJob('orangeSeed', 10, 80) // Fly to the specified point, then plant
extractJob // Extracts whatever is on the current tile
extractAtJob(10, 80) // Fly to specified location, then extract

Job combiners

// Following four jobs can have any number of parameters
// Executes all jobs simultaneously, completes when at least one of them completes 
anyJob(patrolJob(p1, p2), outtakeWaterJob)
// Same but completes when all jobs complete, continues to execute other jobs meanwhile
allJob(job1, job2, job3, jobN)
// Executes provided jobs in sequence once
sequenceJob(job1, job2, job3, job4, jobN)
// Executes jobs in sequence, but loops forever
loopJob(job1, job2, jobN)
// On a less abstract level, you have:
performAtJob(intakeWaterJob, x, y)
// which creates a job which executes given job at a given location

Combination examples from the starter code

const performAtJob = (job, x, y) => {
    const destJob = flyToJob(x, y);
    return sequenceJob(destJob, allJob(destJob, job));
}
const extractAtJob = (x, y) => performAtJob(extractJob, x, y);
const patrolJob = (...points) => loopJob(
    ...points.map(p => flyToJob(p.x, p.y))
);

Dynamic world

World lives it's own life. Most notably:

  • moisture spreads to nearby tiles and evaporates
  • plants grow or decay and die (their health increases or decreases)

Moisture

Moisture originates at water shores, spreads to adjacent tiles and evaporates from surface. It influences plant's health.

Health change of a plant is proportional (although capped) to:

tile.moisture - 24

which means that when moisture is above 24, plants grow, and when it's below 24, plants decay.

When plant's health reaches zero, it automatically dies. This is the same for the default grass as well as the plants your drone plants.

I chose the value of 24 to be quite simple on the default-seed map, but if you want more difficulty, you might regenerate map with another seed (read "Warning" paragraph above).

In any case, watering plants significantly increases their growth speed. For example, growth at `tile.moisture` = 72 compared to `tile.moisture` = 30 will be 8 times as fast ((72 - 24) / (30 - 24) = 48 / 6 = 8).

Tiles

All tiles except water function essentially the same: you can plant on any tile and you can extract any tile. Game idea is about farming, but nothing stops you from mining some rocks and selling them. Sample code sells grass.

Drone interface

All methods below (except setting `.motor.force`) operate for one frame only, so if you want to plant a seed, you need to call `.plant` numerous times until it is planted.

Memory

Any object you want to persist between drone patches. Anything saved here will stay the same throughout playthrough unlike top-level variables, which will re-initialize every patch.

drone.memory = { patchNumber: 4 };

Memory is like HDD.
Top-level variables - like RAM.

Refreshing the page will wipe memory as well though.

GPS

Provides access to drones location and velocity

drone.gps.position.x
drone.gps.position.y
drone.gps.velocity.x
drone.gps.velocity.y

Time

Provides access to frame delta time (in milliseconds)

drone.time.delta

Motor

Allows to control drone's motor to make it move

drone.motor.force = {
  x: 1000,
  y: 500,
};

Force will be automatically capped at

drone.motor.maxForce

You can also read from `drone.motor.force` if you need to.

Water container

Provides information to the state of drone water storage

drone.waterContainer.currentAmount
drone.waterContainer.volume // maximum amount

Pump

Pump to move water in- and out- of water container.

drone.pump.intakeSpeed
drone.pump.outtakeSpeed
drone.pump.intake()
drone.pump.outtake()

`.intake()` and `.outtake()` only affect one frame.

Shovel

Your main tool, use it to plant seeds and gather crops. Plant crops with:

drone.shovel.plant(item: string | Item): boolean

It takes either seed's itemKey (string) or item (Item) as a parameter and returns whether the seed was planted this frame. Before the seed can be planted, the current tile needs to be destroyed (think of getting rid of weeds or/and preparing soil) = it's health needs to reach zero. This tile damaging will happen automatically when you call `.plant`, but you need to continue calling `.plant` until you receive `true` which means that the seed has been planted.

drone.shovel.damage()

You can also just `.damage()` tiles without trying to plant anything, if you want it for whatever reason.

When you use `.plant()` or `.damage()` the current (under drone) tile is eventually destroyed no matter what was located on it. Typically, you want to gather crops instead of destroying them though. For that you use:

drone.shovel.extract(): boolean

Same as `.plant()`, it returns whether a tile (any tile) was extracted this frame. And same, it doesn't happen instantly: tile's firmness needs to reach zero before extraction will finally succeed. And same once again, `.extract()` will automatically decrease tile's firmness.

Inventory

The stuff drone carries. Some properties (hopefully) need no explanation:

drone.inventory.maxWeight
drone.inventory.totalWeight
drone.inventory.money

There are two ways to access information about specific item in your inventory:

drone.inventory.content.<itemKey>: Item 
drone.inventory.content[itemKey]: Item
drone.inventory.content.orangeSeed.quantity
drone.inventory.content['orangeSeed'].density

You can also enumerate all items with:

drone.inventory.list

`.list` has the same content as `.content`, but shaped as an array and not an object

Market

A place to buy your seeds and sell your crops at shitty prices. How shitty exactly? These params will tell you:

drone.market.buyPenalty
drone.market.sellPenalty

They were planned to be upgradable (as everything else ... I mean as everything else was also planned to be upgradable), but they are just equal 2 for now, which means that real purchase and sell price of an item is:

item.price * drone.market.buyPenalty 
item.price / drone.market.sellPenalty

You can access information about various items with:

drone.market.availableItems.<itemKey>: Item
drone.market.availableItems[itemKey]: Item
drone.market.availableItems.orange.price
drone.market.availableItems['orange'].density

And as with the inventory, there is a field to get the same information in the form of an array:

drone.market.availableItemsList

Item

Both `.inventory` and `.market.availableItems` contain objects of type `Item`, which has the following fields:

// item: Item
item.key // key to access this item
item.name // human readable name
item.density // how much each unit of this item weights
item.price // per one unit
item.quantity // in case item is in your inventory

Full list of available methods

drone.memory (get, set)
drone.gps.position (.x, .y)
drone.gps.velocity (.x, .y)
drone.time.delta
drone.motor.force (get, set)
drone.motor.maxForce
drone.waterContainer.currentAmount
drone.waterContainer.volume
drone.pump.intakeSpeed
drone.pump.outtakeSpeed
drone.pump.intake()
drone.pump.outtake()
drone.shovel.damage()
drone.shovel.plant(item: string | Item): boolean
drone.shovel.extract(): boolean
drone.inventory.maxWeight
drone.inventory.totalWeight
drone.inventory.money
drone.inventory.content.<itemKey>: Item
drone.inventory.content[itemKey]: Item
drone.inventory.list
drone.market.buyPenalty
drone.market.sellPenalty
drone.market.availableItems.<itemKey>: Item
drone.market.availableItems[itemKey]: Item
drone.market.availableItemsList
item.key
item.name
item.density
item.price
item.quantity

Available items

soil: $1, 1kg
stone: $25, 8kg
sand: $0.9, 0.7kg
grass: $3, 0.3kg
tree: $20, 15kg
orange: $4, 0.5kg
potato: $2.5, 2kg
rose: $75, 4kg
sunflower: $6, 3.5kg
wheat: $0.6666666666666666, 0.25kg
whiteFlower: $30, 3kg

Available seeds

Seed is also an item, but the one which can be planted

Tree seed: $140, 80kg // yes, this one is "Tree seed", mistake
orangeSeed: $80, 30kg
potatoSeed: $75, 40kg
roseSeed: $135, 250kg
sunflowerSeed: $80, 120kg
wheatSeed: $90, 25kg
whiteFlowerSeed: $105, 170kg

Share your thoughts

Unusual games likes this are hard to get played during game jams. That means that if you've made it to actual game and tried to code something, I'd be triple glad to hear your thoughts. Criticism is welcomed:)

I also understand that despite this long text, it might still be more confusing than it should be. Ask any question and I'll answer!

See you in the comments

Comments

Log in with itch.io to leave a comment.

(+2)

Not realy in the mood to learn how to code in Javascript at the moment, but I hope this does well

Thanks for kind words. This is probably not the best game to learn coding, but I imagine a game like this, with a campaign/story/missions which will provide gradual learning curve, might be a great way to learn programming.

If you transition from C#/C++/Java, I think it should be ok though, as they are quite similar.