forked from retoor/devplacepy
696 lines
34 KiB
HTML
696 lines
34 KiB
HTML
{% set api_key = user.get('api_key') if user else 'YOUR_API_KEY' %}
|
|
{% set uname = user.get('username') if user else 'YOUR_USERNAME' %}
|
|
<div class="docs-content" data-render>
|
|
# Code Farm
|
|
|
|
Code Farm is a cooperative idle game built into DevPlace. Every member owns a farm of plots,
|
|
plants software projects that build over real time, harvests the finished builds for coins and
|
|
experience, and grows the farm with faster CI, more plots, and permanent perks. You can also
|
|
visit other members' farms to water their growing builds for a reward, or raid a ready build that
|
|
its owner left sitting too long.
|
|
|
|
Open it from your user menu or go straight to `{{ base }}/game`. You need a member account to
|
|
play. Visiting another farm at `{{ base }}/game/farm/{username}` is public.
|
|
|
|
Everything on this page also runs over the JSON API, so the game can be driven by a script as
|
|
well as by hand. The full request and response reference is the
|
|
[Code Farm API group](/docs/game.html); this page explains the rules and the exact numbers behind
|
|
them, then documents every field a client sees and shows a complete automated client at the end.
|
|
|
|
## The core loop
|
|
|
|
1. **Plant** a crop in an empty plot. Planting costs coins.
|
|
2. The crop **builds** over real time. The build finishes at a fixed wall-clock moment
|
|
(`ready_at`); there is no server tick, the clock alone decides.
|
|
3. **Harvest** the finished build for coins and experience, which empties the plot again.
|
|
4. Spend the coins on faster CI, more plots, and perks so the next loop pays more.
|
|
|
|
A farm starts with **50 coins** and **4 plots**. Nothing is lost while you are away: builds keep
|
|
progressing and wait for you, so the game is safe to check once an hour or once a day.
|
|
|
|
## Crops
|
|
|
|
Each crop has a coin cost to plant, a base build time, a coin and experience reward on harvest,
|
|
and a level at which it unlocks. Slower crops pay far more per build.
|
|
|
|
| Crop | Key | Cost | Base build time | Coins | XP | Unlocks at |
|
|
|------|-----|-----:|----------------:|------:|---:|:----------:|
|
|
| π Shell Script | `shell` | 5 | 30s | 11 | 2 | level 1 |
|
|
| π Python Script | `python` | 15 | 2m | 36 | 5 | level 1 |
|
|
| π Web App | `webapp` | 40 | 5m | 98 | 12 | level 2 |
|
|
| πΉ Go Service | `api` | 90 | 10m | 224 | 25 | level 3 |
|
|
| π¦ Rust Engine | `rust` | 200 | 30m | 520 | 60 | level 4 |
|
|
| Ξ» Compiler | `haskell` | 500 | 1h | 1380 | 150 | level 6 |
|
|
| βοΈ Kernel | `kernel` | 1200 | 2h | 3600 | 400 | level 8 |
|
|
| πΈοΈ Distributed System | `distsys` | 5000 | 4h | 11300 | 900 | level 20 + Mastery |
|
|
| π§ ML Pipeline | `mlpipe` | 12000 | 6h | 21000 | 1800 | level 20 + Mastery |
|
|
| π Security Fortress | `secfort` | 30000 | 8h | 48000 | 3200 | level 20 + Mastery |
|
|
|
|
The three Mastery-tier crops require **level 20** and at least **one earned Mastery point** (see
|
|
Mastery, below). The Mastery unlock is permanent - it checks points ever earned, not points held,
|
|
so spending your points never re-locks the crops. Security Fortress is **raid-immune**: it can
|
|
never be stolen.
|
|
|
|
Build time is the base time divided by the farm build speed (CI tier, the Build Cache perk, the
|
|
Bare-Metal Legacy upgrade, and the Private Registry for its three crops), so upgrades finish
|
|
everything proportionally faster. Coin and experience rewards shown in the API already include
|
|
your perks, refactor bonus, Legacy multiplier, and the current Market Saturation factor, so read
|
|
them from the live state rather than from this table. Each crop in the state also carries a
|
|
`market_state` of `normal`, `saturated`, or `boosted`.
|
|
|
|
## Plots
|
|
|
|
A farm starts with 4 plots and can grow to **12**. Each extra plot costs more than the last: the
|
|
price starts at **100 coins** and doubles for every plot you have already added.
|
|
|
|
| Plot number | Cost |
|
|
|:-----------:|-----:|
|
|
| 5th | 100 |
|
|
| 6th | 200 |
|
|
| 7th | 400 |
|
|
| 8th | 800 |
|
|
| 9th | 1600 |
|
|
| 10th | 3200 |
|
|
| 11th | 6400 |
|
|
| 12th | 12800 |
|
|
|
|
More plots is more builds in parallel, which is the main way to scale output.
|
|
|
|
## CI tier (build speed)
|
|
|
|
Upgrading your CI tier multiplies build speed for the whole farm. The upgrade is permanent (until
|
|
a refactor resets it).
|
|
|
|
| Tier | Name | Build speed | Upgrade cost |
|
|
|:----:|------|:-----------:|-------------:|
|
|
| 1 | Local Build | 1.0x | starting |
|
|
| 2 | Shared Runner | 1.25x | 150 |
|
|
| 3 | Fast Runner | 1.6x | 400 |
|
|
| 4 | Parallel Matrix | 2.0x | 1000 |
|
|
| 5 | Distributed Cache | 2.5x | 2600 |
|
|
|
|
## Levels and experience
|
|
|
|
Harvesting grants experience. Experience raises your level, and higher levels unlock the more
|
|
valuable crops. The maximum level is **20**. Reaching a level needs `50 * (level - 1)^2` total
|
|
experience, so level 2 is at 50 XP, level 5 at 800, level 10 at 4050, and level 20 at 18050. The
|
|
state reports `level`, `level_into` (XP into the current level), `level_span` (XP from this level
|
|
to the next), and `level_is_max`.
|
|
|
|
## Perks
|
|
|
|
Perks are permanent upgrades bought with coins (until a refactor resets them). The cost of level
|
|
`n+1` is `round(base * growth^n)`, so each level costs more than the last. There are four:
|
|
|
|
| Perk | Key | Effect per level | Max level | First cost | Cost growth |
|
|
|------|-----|------------------|:---------:|-----------:|:-----------:|
|
|
| π Optimizer | `yield` | +5% harvest coins | 10 | 120 | 1.6x |
|
|
| β‘ Build Cache | `growth` | +4% build speed | 10 | 150 | 1.7x |
|
|
| π·οΈ Bulk Licenses | `discount` | -3% planting cost | 8 | 100 | 1.7x |
|
|
| π Mentorship | `xp` | +5% harvest experience | 10 | 140 | 1.6x |
|
|
|
|
The live state reports each perk's current level and the exact cost of its next level - read
|
|
`cost` from the state rather than recomputing it.
|
|
|
|
## Daily bonus and streak
|
|
|
|
Once per UTC day you can claim a coin bonus of `20 + 12 * (streak_day - 1)`, where the streak day
|
|
caps at seven: **20 coins** on day one up to **92 coins** from the seventh consecutive day on.
|
|
Missing a day resets the streak to one. The state field `daily_available` tells you when a claim
|
|
is ready, and `daily_reward` is the exact amount the next claim pays.
|
|
|
|
## Daily quests
|
|
|
|
Each day you are given three small goals, deterministically chosen per user and day, such as
|
|
planting a number of crops, harvesting a number of builds, watering neighbour builds, or earning a
|
|
number of coins from harvests. Progress is tracked automatically as you play. A completed quest is
|
|
claimed by its **kind** (`plant`, `harvest`, `water`, or `earn`) for a coin and experience reward.
|
|
The state field `can_claim` on each quest marks the ones that are ready; claiming an incomplete or
|
|
already-claimed quest returns an error.
|
|
|
|
## Fertilizer
|
|
|
|
Fertilizing a growing build spends coins to **halve its remaining time**. The exact cost is
|
|
`ceil(realizable_harvest_coins * skipped_seconds / full_build_seconds * 1.05)`, where
|
|
`realizable_harvest_coins` is what *this specific build* will actually pay out - it includes your
|
|
perks, prestige, Legacy multiplier, and the market factor, **and** the golden multiplier, an
|
|
active weekly-contract boost, an active Underdog boost, and the Canary upside. Because the price
|
|
is computed from the same value the harvest pays, fully fertilizing a build always costs at least
|
|
105% of what it can return. Fertilizer is a pure time-skip, never a profit, at any prestige, on
|
|
any build, with any combination of boosts. Each growing plot in the state reports its current `fertilize_cost`; a build
|
|
with less than two seconds remaining cannot be fertilized.
|
|
|
|
## Golden builds
|
|
|
|
Every planting has a **5% chance** to come out **golden**, decided the moment it is planted and
|
|
fixed for that build's lifetime. A golden harvest pays **5x coins** (experience is unchanged).
|
|
The plot field `is_golden` marks it - the owner always sees it, a visitor only when the build is
|
|
currently stealable (a golden build is a 5x raid target too, so watch your grace window).
|
|
|
|
## Watering a neighbour (cooperation)
|
|
|
|
Visit another member's farm and water one of their **growing** builds. Watering reduces that
|
|
build's remaining time by **8% of its full (speed-adjusted) build time** and rewards **you**, the
|
|
visitor, with **6 coins scaled by your own prestige and Tech Debt Payoff multiplier** (so watering
|
|
stays worth doing at every stage of the game) plus **3 experience**. The daily bonus and daily
|
|
quest coin rewards scale the same way. Each visitor can water a given build **once per
|
|
growth cycle**, and a single build takes at most **3 waterings** total across all visitors, so
|
|
popular farms fill up. Each plot reports `can_water` (true only for signed-in non-owners who have
|
|
not watered it yet), `watered_count`, and `max_waters`. Watering also advances your own `water`
|
|
quest.
|
|
|
|
## Raiding a ready build (competition)
|
|
|
|
If an owner leaves a build **ready** without harvesting it, another member can raid ("steal") it,
|
|
but only after a protection window has passed since the build became ready. The window is **60
|
|
seconds** base, **+30s** per level of the owner's Branch Protection Legacy upgrade, plus the
|
|
owner's Defense tier grace bonus (table below).
|
|
|
|
**A raid takes a share, it does not destroy the build.** The raider receives
|
|
`min(cap, max(floor, (50% - 5% x Branch Protection level) x (1 - Defense tier reduction)))` of the
|
|
build's realized coin value, and that share is recorded on the plot as `raided_fraction`. The
|
|
**owner still harvests everything that was not taken** - a build raided for 35% still pays its
|
|
owner the remaining 65%. A build can be raided until its shares add up to 100%, after which
|
|
`steal_reason` is `stripped`. A Security Fortress build can never be raided.
|
|
|
|
The `cap` is 100% normally and **20%** when the owner owns the Observability Suite, so that
|
|
building genuinely limits raid losses. The `floor` is the owner's Defense tier minimum. The owner
|
|
is notified of the raider's name, the crop, and the exact amount taken.
|
|
|
|
You can raid any given neighbour only **once per hour**, and any given farm can be raided at most
|
|
**3 times per day** in total, so an inactive player can never be stripped by an unlimited queue of
|
|
raiders. Raiding a farm holding more than **10x** your own coins grants you a 24-hour **Underdog**
|
|
boost (+25% harvest coins, visible as `underdog_boost_seconds_remaining` in your state).
|
|
|
|
Each plot on a farm you view reports:
|
|
|
|
- `can_steal` - true when everything below is satisfied and you can raid right now.
|
|
- `steal_coins` - the exact payout a raid would give.
|
|
- `steal_reason` - why a ready build is not stealable: `protected` (grace window still running),
|
|
`cooldown` (you raided this owner within the hour), `stripped` (the build has already been
|
|
raided for its full value), or `immune` (Security Fortress). Empty when stealable or not
|
|
applicable.
|
|
- `raided_fraction` / `raided_pct` - how much of this build has already been taken by raiders.
|
|
- `steal_cooldown_seconds` - seconds until your per-owner cooldown ends (only set with
|
|
`steal_reason` of `cooldown`; also mirrored farm-wide as `steal_cooldown_seconds` on the farm).
|
|
- `ready_at` - add the protection window to compute when a raid becomes possible.
|
|
|
|
Harvest your own ready builds promptly to keep them safe, or invest in Defense (below).
|
|
|
|
## Market Saturation
|
|
|
|
The game tracks the last **48 hours** of league-wide harvests of each crop and converts them into
|
|
supply measured in build time ("plot-days" at base rate), so a 30-second Shell Script and a
|
|
2-hour Kernel saturate on the same real-terms scale - quick crops are not punished for being
|
|
quick. As supply piles up, the crop's payout steps down:
|
|
|
|
Supply is measured **per active farm**, so a busy server is not permanently floored by a handful
|
|
of heavy players - the thresholds scale with how many people are actually farming.
|
|
|
|
| Supply (plot-days in 48h, per active farm) | Payout |
|
|
|:-------------------------:|:------:|
|
|
| under 8 | 100% |
|
|
| 8 or more | 85% |
|
|
| 24 or more | 70% |
|
|
| 48 or more | 55% |
|
|
| 96 or more | 40% |
|
|
|
|
Separately, while the high-tier market (Rust Engine, Compiler, Kernel) is saturated, the four
|
|
starter crops (Shell Script, Python Script, Web App, Go Service) pay a boost of up to **+15%**
|
|
(scaling with how collapsed the high tier is) as long as they are not overfarmed themselves - a
|
|
crop is either penalized or boosted, never both. This rewards planting what the market is short
|
|
on instead of printing one crop nonstop. Nothing else about the crop changes - cost, build time,
|
|
and unlock level are unaffected. The live factor is folded into each crop's `reward_coins` and
|
|
summarized as `market_state` (`normal`, `saturated`, or `boosted`); the server refreshes market
|
|
factors about every 30 seconds.
|
|
|
|
## Infrastructure, Defense, and Cosmetics (coin sinks)
|
|
|
|
Once you are earning more coins than you can spend on plots and perks, three permanent systems
|
|
give large coins a purpose.
|
|
|
|
### Infrastructure
|
|
|
|
One-time, prestige-gated buildings bought with `POST /game/infrastructure/buy`:
|
|
|
|
| Building | Key | Effect | Cost | Requires |
|
|
|----------|-----|--------|-----:|:--------:|
|
|
| π¦ Private Registry | `registry` | Rust, Compiler, and Kernel builds finish 15% faster (watering them is 15% more effective too) | 3,000,000 | prestige 3 |
|
|
| π€ Canary Deployments | `canary` | Every harvest has a 12% chance to double and a 6% chance to only refund its planting cost | 6,000,000 | prestige 8 |
|
|
| π Observability Suite | `observability` | Caps what any raider can take from you at 20% of a build's value (see Raiding and Defense) | 15,000,000 | prestige 15 |
|
|
|
|
### Defense
|
|
|
|
An upgradeable building (`POST /game/defense/upgrade`) that lowers your raid losses and lengthens
|
|
your protection window per tier:
|
|
|
|
| Tier | Name | Upgrade cost | Daily upkeep (min) | Raid loss reduction | Undefended raider share | Extra grace |
|
|
|:----:|------|-------------:|-------------------:|:-------------------:|:-----------------------:|:-----------:|
|
|
| 0 | Undefended | - | 0 | 0% | 50.0% | +0s |
|
|
| 1 | Firewall | 5,000 | 500 | 5% | 47.5% | +15s |
|
|
| 2 | WAF | 40,000 | 2,500 | 12% | 44.0% | +30s |
|
|
| 3 | SOC Monitoring | 300,000 | 15,000 | 20% | 40.0% | +60s |
|
|
| 4 | Zero Trust Mesh | 2,000,000 | 100,000 | 30% | 35.0% | +120s |
|
|
|
|
The reduction is multiplicative and stacks with Branch Protection: a Zero Trust Mesh owner with
|
|
Branch Protection 5 hands over 17.5% instead of 50%. Grace stacks on top of the base 60 seconds
|
|
and any Branch Protection levels. The Observability Suite caps the raider's share at 20%
|
|
regardless of tier.
|
|
|
|
Unlike a one-time purchase, Defense costs a **daily coin upkeep** of
|
|
`max(tier_minimum, 0.2% of your coin balance)` - a large balance pays real money, not a flat fee.
|
|
Upkeep is charged lazily whenever you load your own farm, for every day elapsed since the last
|
|
charge, so staying away is not cheaper than playing. If your balance cannot cover what is due,
|
|
**only what you can afford is taken** and the tier decays by one level - your balance is never
|
|
emptied, and you are notified. You can also leave the commitment deliberately with
|
|
`POST /game/defense/downgrade` (no refund). The state reports `defense_level`,
|
|
`defense_tier_name`, `defense_upkeep_daily` (today's exact charge), `defense_next_cost`, and
|
|
`defense_downgrade_available`.
|
|
|
|
### Cosmetics
|
|
|
|
Purely cosmetic titles and plot skins bought with coins (`POST /game/cosmetics/buy`) and, for
|
|
titles, equipped with `POST /game/cosmetics/equip`. Zero gameplay effect; an equipped title shows
|
|
next to your name on the leaderboard.
|
|
|
|
| Cosmetic | Key | Kind | Cost |
|
|
|----------|-----|:----:|-----:|
|
|
| ποΈ The Architect | `title_architect` | title | 500,000 |
|
|
| β» Serial Refactorer | `title_refactorer` | title | 250,000 |
|
|
| β Kernel Hacker | `title_kernel_hacker` | title | 1,000,000 |
|
|
| π Neon Terminal | `skin_neon` | skin | 750,000 |
|
|
|
|
Era-exclusive cosmetics (when an Era awards one) appear in your owned list but are never sold in
|
|
the shop. The state's `cosmetics` list carries each purchasable cosmetic with an `owned` flag,
|
|
and `active_title` is your equipped title key.
|
|
|
|
## Mastery (beyond prestige)
|
|
|
|
Refactoring past **prestige 50** starts earning a second currency: one Mastery point the moment
|
|
you cross 50, then one more every 5 further prestige (`total earned = 1 + (prestige - 50) / 5`,
|
|
rounded down). Points never expire, and crop unlocks check points **ever earned**
|
|
(`mastery_points_earned_total`), so spending never re-locks content. Spend points with
|
|
`POST /game/mastery` on three permanent upgrades:
|
|
|
|
| Mastery upgrade | Key | Effect | Cost (points) |
|
|
|------------------|-----|--------|:-------------:|
|
|
| π Continuous Delivery | `autoreplant` | Auto-replant the same crop right after every harvest, if still affordable and unlocked | 3 |
|
|
| π Farm Analytics | `analytics` | Unlocks lifetime stats: `lifetime_coins_earned` and `lifetime_harvests` | 2 |
|
|
| π Legacy Contracts | `contracts` | Unlocks a weekly contract slot paying Stars and a temporary coin boost | 4 |
|
|
|
|
Each has a single level. The state reports `mastery_points` (spendable),
|
|
`mastery_points_earned_total`, and each upgrade's level and cost.
|
|
|
|
### Weekly contracts
|
|
|
|
With Legacy Contracts owned, one **weekly contract** appears in your `quests` list with
|
|
`scope: "weekly"` - a larger goal of the same four kinds, deterministic per user and ISO week.
|
|
A coin-denominated contract scales its goal with your own earning power, so it stays a week's work
|
|
at every prestige. Claiming it (`POST /game/quests/claim` with the contract's `quest` kind and
|
|
`scope=weekly`) pays a fixed **3 Stars** (5 for a coin contract) plus experience, and grants a
|
|
**+20% harvest-coin boost for 48 hours**, shown as `contract_boost_seconds_remaining`.
|
|
|
|
## Refactor (prestige)
|
|
|
|
At level 10 or above you can **refactor**: coins, XP, level, CI tier, perks, and extra plots
|
|
reset, but you gain a permanent **+25% coin bonus per refactor** that multiplies with your perks.
|
|
Refactoring is the long-term progression and the single largest factor in the leaderboard. The
|
|
state reports `prestige`, `prestige_multiplier`, `prestige_min_level`, and `prestige_available`.
|
|
|
|
Refactoring is not free. The fee is:
|
|
|
|
```
|
|
fee = round(20000 * (1 + prestige) * (1 + 0.25 * prestige) + 0.15 * coins)
|
|
```
|
|
|
|
so it grows with both your refactor count and your current balance (a wealth tax), and each
|
|
refactor takes longer to afford than the last. The live state reports the exact `refactor_cost`
|
|
and whether you can pay it right now (`refactor_affordable`). After the fee, **10%** of your
|
|
remaining coins carry over into the new run - up to **35%** with the Golden Parachute Legacy
|
|
upgrade - previewed exactly as `refactor_carryover_preview` (and `refactor_carryover_pct`). The
|
|
new run starts with the 50 starting coins plus that carry-over.
|
|
|
|
Each refactor also awards **Stars**: `1 + level / 5 + prestige` (rounded down, using the level
|
|
and prestige you refactor from). Stars are never reset and are spent on permanent **Legacy
|
|
upgrades**. What survives a refactor: prestige, Stars, Legacy upgrades, Mastery points and
|
|
upgrades, Infrastructure, Defense, cosmetics, lifetime stats, and your Era counters.
|
|
|
|
## Community treasury and weekly grant
|
|
|
|
Every refactor fee flows into a shared **community treasury**. Once per ISO week, an active farm
|
|
that is still building up - at least **5 harvests this week**, fewer than **10,000 coins**, and
|
|
at most **prestige 5** - can claim a grant with `POST /game/grant`. The treasury is **shared
|
|
out between everyone currently eligible** rather than paid first-come-first-served: the amount is
|
|
`treasury_balance / eligible_farms`, capped at **2,500 coins** and suppressed entirely below a
|
|
**250 coin** minimum so nobody claims dust. The state reports `grant_available`, `grant_amount`,
|
|
`grant_reason` (a human-readable explanation when unavailable), and the current
|
|
`treasury_balance`.
|
|
|
|
## Legacy upgrades
|
|
|
|
Stars buy Legacy upgrades, permanent boosts that persist through every future refactor. The cost
|
|
of level `n+1` is `round(base * growth^n)` Stars. There are six:
|
|
|
|
| Legacy upgrade | Key | Effect | Max level | First cost | Cost growth |
|
|
|----------------|-----|--------|:---------:|-----------:|:-----------:|
|
|
| π€ CI Bot | `autoharvest` | Auto-collect ready builds whenever you load your farm | 1 | 3 | - |
|
|
| π Tech Debt Payoff | `multiplier` | +10% harvest coins per level, stacks with refactor | 10 | 1 | 1.6x |
|
|
| ποΈ Bare-Metal | `speed` | +5% base build speed per level | 8 | 1 | 1.7x |
|
|
| ποΈ Monorepo | `plots` | +1 starting plot after each refactor per level | 8 | 3 | 2.0x |
|
|
| π‘οΈ Branch Protection | `defense` | +30s steal grace and -5% steal loss per level | 5 | 2 | 1.8x |
|
|
| πͺ Golden Parachute | `carryover` | +5% refactor coin carry-over per level | 10 | 2 | 1.8x |
|
|
|
|
The live state reports your `stars` balance and each legacy upgrade's current level and the exact
|
|
Star cost of its next level.
|
|
|
|
## Leaderboards and scoring
|
|
|
|
The default leaderboard ranks the top 25 farms by a composite score. Refactors dominate the
|
|
formula, then lifetime harvests, level, and everything else. The coin term is **capped**, so the
|
|
board measures what you have built rather than what you are sitting on, and refactoring - which
|
|
spends your balance - never costs you rank:
|
|
|
|
```
|
|
score = xp
|
|
+ prestige * 5000
|
|
+ total_harvests * 10
|
|
+ min(coins / 20, 100000)
|
|
+ (ci_tier - 1) * 250
|
|
+ (plots - 4) * 200
|
|
+ total_perk_levels * 120
|
|
+ min(streak, 30) * 15
|
|
```
|
|
|
|
Read the top farms with `GET {{ base }}/game/leaderboard` (public, no account needed; results are
|
|
cached server-side for about 15 seconds). Add `?board=` to switch boards:
|
|
|
|
| Board | Ranked by |
|
|
|-------|-----------|
|
|
| `score` | The composite score above (default). |
|
|
| `prestige` | Prestige count, Stars as tiebreak. |
|
|
| `harvests` | Harvests this ISO week (`harvests_week`). |
|
|
| `raids` | Average coins per successful raid over the last 30 days, minimum 3 qualifying raids; each entry carries `raid_avg`. |
|
|
| `time_to_kernel` | Fastest Kernel harvest since the player's last refactor; each entry carries `time_to_kernel_seconds`. |
|
|
| `fair_play` | `harvests_week * 50 - coins / 200000` - rewards recent activity over hoarding. |
|
|
| `era` | The current Era's score (below); empty when no Era is running. |
|
|
|
|
Every entry carries `rank`, `username`, `level`, `xp`, `coins`, `total_harvests`, `prestige`,
|
|
`score`, and `title` (the display name of the player's equipped cosmetic title, empty when none).
|
|
|
|
## Eras (seasons)
|
|
|
|
Administrators can occasionally start an **Era**: a fresh, visible "this season" leaderboard
|
|
(`board=era`) that everyone starts at zero on, while their real coins, prestige, Stars, Legacy,
|
|
and Mastery are completely untouched. Era score is `era_coins / 20 + era_harvests * 10 + prestige
|
|
* 2000`, so veterans keep an edge without it being insurmountable. When an Era ends, the top 10
|
|
by Era score earn permanent Stars (50, 30, 20, 15, 10, then 5 each for ranks 6-10) and sometimes
|
|
an Era-exclusive cosmetic. Your own state reports `era_active`, `era_name`, `era_coins`, and
|
|
`era_harvests` while one is running; an Era can also make Era-exclusive crops plantable for its
|
|
duration.
|
|
|
|
## Live updates
|
|
|
|
A farm page subscribes to the pub/sub topic `public.game.farm.{username}` and refreshes whenever
|
|
that farm changes, so watering, harvesting, and raids appear without a reload. A scripted client
|
|
does not need pub/sub: it can simply re-read the state after each action, since every action
|
|
endpoint returns the full updated farm.
|
|
|
|
## Playing through the API
|
|
|
|
Every action is a normal DevPlace endpoint that negotiates HTML or JSON. Send
|
|
`Accept: application/json` to get JSON, and authenticate exactly like the rest of the API: with
|
|
your **API key** in an `X-API-KEY` header (or `Authorization: Bearer`). Your key is on your
|
|
[profile page]({% if user %}/profile/{{ uname }}{% else %}/profile/YOUR_USERNAME{% endif %}).
|
|
|
|
### Endpoints
|
|
|
|
| Method | Path | Purpose |
|
|
|--------|------|---------|
|
|
| `GET` | `/game` | Your farm page (HTML, or the same JSON as `/game/state` when asked). |
|
|
| `GET` | `/game/state` | Your full farm state (always JSON). |
|
|
| `GET` | `/game/leaderboard` | Top farms (public). Accepts `?board=`. |
|
|
| `GET` | `/game/farm/{username}` | Another member's farm. |
|
|
| `POST` | `/game/plant` | Plant `crop` in `slot`. |
|
|
| `POST` | `/game/harvest` | Harvest the build in `slot`. |
|
|
| `POST` | `/game/fertilize` | Halve the remaining time of `slot`. |
|
|
| `POST` | `/game/buy-plot` | Unlock one more plot. |
|
|
| `POST` | `/game/upgrade` | Raise the CI tier. |
|
|
| `POST` | `/game/perk` | Upgrade `perk` (`yield`, `growth`, `discount`, `xp`). |
|
|
| `POST` | `/game/daily` | Claim the daily bonus. |
|
|
| `POST` | `/game/quests/claim` | Claim a completed quest by `quest` kind, optional `scope` (`daily` or `weekly`). |
|
|
| `POST` | `/game/prestige` | Refactor at level 10 or above; costs the current `refactor_cost` in coins. |
|
|
| `POST` | `/game/grant` | Claim the weekly community grant from the treasury. |
|
|
| `POST` | `/game/legacy` | Buy a Legacy upgrade (`key`) with Stars. |
|
|
| `POST` | `/game/mastery` | Buy a Mastery upgrade (`key`) with Mastery points. |
|
|
| `POST` | `/game/infrastructure/buy` | Buy an Infrastructure building (`key`) with coins. |
|
|
| `POST` | `/game/defense/upgrade` | Buy the next Defense tier with coins. |
|
|
| `POST` | `/game/defense/downgrade` | Drop one Defense tier to escape its upkeep (no refund). |
|
|
| `POST` | `/game/cosmetics/buy` | Buy a cosmetic (`key`) with coins. |
|
|
| `POST` | `/game/cosmetics/equip` | Equip an owned title cosmetic (`key`). |
|
|
| `POST` | `/game/farm/{username}/water` | Water a neighbour's build in `slot`. |
|
|
| `POST` | `/game/farm/{username}/steal` | Raid a neighbour's unprotected ready build in `slot`. |
|
|
|
|
POST bodies are form encoded (`application/x-www-form-urlencoded`). Form fields are `slot` (an
|
|
integer plot index, 0-based), `crop`, `perk`, `quest`, `scope`, and `key` (a
|
|
Legacy/Mastery/Infrastructure/cosmetic key) where the table notes them. Every own-farm POST
|
|
returns `{"ok": true, "farm": {...}}` - the full updated farm - so one call both performs the
|
|
action and gives you the new state. The two neighbour actions return the **neighbour's** farm as
|
|
you see it (`{"farm": {...}}`), and a successful steal adds `"stole_coins"` with your payout.
|
|
|
|
### Errors
|
|
|
|
An invalid action (not enough coins, wrong plot state, a still-protected harvest, an active
|
|
cooldown, an unmet requirement) returns **HTTP 400** with a human-readable reason:
|
|
|
|
```json
|
|
{"error": {"status": 400, "message": "Not enough coins to plant that."}}
|
|
```
|
|
|
|
An unknown farm username is **404**. Invalid credentials are **401**; a request with no
|
|
credentials at all is redirected (303) to the login page, so always send your API key. Mutating
|
|
requests count against the sitewide rate limit (per client IP, 60 per minute by default) - reads
|
|
do not.
|
|
|
|
### Two things that happen on state reads
|
|
|
|
Loading your own farm (`GET /game`, `GET /game/state`, or the farm returned by any action) is
|
|
when lazy owner-side effects run, so a scripted client should expect them:
|
|
|
|
- With the **CI Bot** Legacy upgrade, every ready build is auto-harvested (and with Continuous
|
|
Delivery, auto-replanted) during the read - the state you get back is post-collection.
|
|
- With a **Defense** building, any daily upkeep due is charged during the read, so your `coins`
|
|
can be lower than the previous response predicted (and the tier one lower, if you could not
|
|
pay).
|
|
|
|
### Reading the state
|
|
|
|
```python
|
|
import json, urllib.request
|
|
|
|
request = urllib.request.Request(
|
|
"{{ base }}/game/state",
|
|
headers={"X-API-KEY": "{{ api_key }}", "Accept": "application/json"},
|
|
)
|
|
with urllib.request.urlopen(request) as response:
|
|
farm = json.loads(response.read())["farm"]
|
|
|
|
print("coins", farm["coins"], "level", farm["level"], "plots", farm["plot_count"])
|
|
for plot in farm["plots"]:
|
|
print(plot["slot"], plot["state"], plot.get("crop_name"), plot.get("remaining_seconds"))
|
|
```
|
|
|
|
### The plot shape
|
|
|
|
`GET /game/state` returns `{"ok": true, "farm": {...}}`. The farm carries your totals plus the
|
|
lists you act on. A plot looks like this:
|
|
|
|
```json
|
|
{
|
|
"slot": 0,
|
|
"state": "growing",
|
|
"crop_key": "python",
|
|
"crop_name": "Python Script",
|
|
"crop_icon": "π",
|
|
"reward_coins": 36,
|
|
"reward_xp": 5,
|
|
"ready_at": "2026-06-23T12:34:56+00:00",
|
|
"remaining_seconds": 73,
|
|
"watered_count": 1,
|
|
"max_waters": 3,
|
|
"can_water": false,
|
|
"can_steal": false,
|
|
"steal_coins": 0,
|
|
"steal_cooldown_seconds": 0,
|
|
"steal_reason": "",
|
|
"is_golden": false,
|
|
"fertilize_cost": 22,
|
|
"raided_fraction": 0.0,
|
|
"raided_pct": 0
|
|
}
|
|
```
|
|
|
|
A plot's `state` is `empty`, `growing`, or `ready`. `reward_coins`/`reward_xp` on a plot are the
|
|
crop's **base** rewards; the multiplied live values are on the matching entry in `crops`. An
|
|
entry in `crops` carries the live `cost`, `reward_coins`, `reward_xp`, `grow_seconds`,
|
|
`min_level`, `market_state`, and a `locked` flag, so a client can decide what is both unlocked
|
|
and affordable without hard-coding the tables above.
|
|
|
|
### The farm state reference
|
|
|
|
Every field on the `farm` object, grouped. Fields marked *(owner)* are only populated when you
|
|
read your **own** farm - on someone else's farm the lists are empty and the flags false/zero.
|
|
|
|
**Identity:** `owner_username`, `owner_uid`, `is_owner`.
|
|
|
|
**Progress and currency:** `coins`, `xp`, `level`, `level_into`, `level_span`, `level_is_max`,
|
|
`total_harvests`, `plot_count`, `max_plots`, `next_plot_cost` (0 when maxed).
|
|
|
|
**CI:** `ci_tier`, `ci_label`, `ci_speed`, `ci_next_tier`, `ci_next_label`, `ci_next_cost` (all
|
|
`next` fields 0/empty at the top tier).
|
|
|
|
**Lists:** `plots`, `crops`, plus *(owner)* `perks`, `quests` (daily entries, and the weekly
|
|
contract when unlocked), `legacy`, `mastery`, `infrastructure`, `cosmetics`. Each purchasable
|
|
entry carries `key`, `name`, `icon`, `description`, its current `level`/`owned` state, the exact
|
|
next `cost`, and a `maxed` flag where applicable.
|
|
|
|
**Refactor:** `prestige`, `prestige_multiplier`, `prestige_min_level`, `prestige_available`
|
|
*(owner)*, `refactor_cost`, `refactor_affordable` *(owner)*, `refactor_carryover_pct`,
|
|
`refactor_carryover_preview`, `stars`.
|
|
|
|
**Grant and treasury** *(owner)*: `grant_available`, `grant_amount`, `grant_reason`,
|
|
`treasury_balance`.
|
|
|
|
**Daily:** `streak`, `daily_available` *(owner)*, `daily_streak_reset` (true when your streak
|
|
lapsed, so `daily_reward` already reflects the reset value), `daily_reward`.
|
|
|
|
**Raiding:** `steal_cooldown_seconds` (your remaining cooldown against this farm's owner; 0 on
|
|
your own farm), `steal_max_per_victim_per_day` (how many raids any single farm can absorb per
|
|
day).
|
|
|
|
**Mastery and lifetime stats:** `mastery_points`, `mastery_points_earned_total`,
|
|
`mastery_analytics_unlocked`, `lifetime_coins_earned`, `lifetime_harvests`, `harvests_week`.
|
|
|
|
**Defense:** `defense_level`, `defense_tier_name`, `defense_upkeep_daily`, `defense_next_cost`
|
|
(0 at the top tier), `defense_downgrade_available` *(owner)*.
|
|
|
|
**Cosmetics and boosts:** `active_title`, `underdog_boost_seconds_remaining`,
|
|
`contract_boost_seconds_remaining`.
|
|
|
|
**Auto-harvest** *(owner)*: `auto_harvested`, `auto_harvest_coins`, `auto_harvest_xp` - what the
|
|
CI Bot collected during this read, so a client can report it. They are 0 unless the CI Bot Legacy
|
|
upgrade is owned and something was ready.
|
|
|
|
**Era:** `era_active`, `era_name`, `era_coins`, `era_harvests`.
|
|
|
|
### A complete automated farmer
|
|
|
|
This script plays the core loop on a schedule: it claims the daily bonus and any finished quests,
|
|
harvests every ready build, replants empty plots with the most valuable crop it can afford, and
|
|
prints a one-line summary. It uses only the Python standard library. Set your URL and API key,
|
|
then run it under `cron` or a `systemd` timer, or leave it looping.
|
|
|
|
```python
|
|
#!/usr/bin/env python3
|
|
"""Plays the DevPlace Code Farm automatically over the JSON API."""
|
|
|
|
import json
|
|
import time
|
|
import urllib.error
|
|
import urllib.parse
|
|
import urllib.request
|
|
|
|
BASE = "{{ base }}"
|
|
API_KEY = "{{ api_key }}"
|
|
POLL_SECONDS = 60
|
|
|
|
|
|
def call(method, path, fields=None):
|
|
headers = {"X-API-KEY": API_KEY, "Accept": "application/json"}
|
|
data = None
|
|
if fields is not None:
|
|
data = urllib.parse.urlencode(fields).encode()
|
|
headers["Content-Type"] = "application/x-www-form-urlencoded"
|
|
request = urllib.request.Request(BASE + path, data=data, headers=headers, method=method)
|
|
with urllib.request.urlopen(request) as response:
|
|
return json.loads(response.read())
|
|
|
|
|
|
def state():
|
|
return call("GET", "/game/state")["farm"]
|
|
|
|
|
|
def best_affordable_crop(farm):
|
|
options = [c for c in farm["crops"] if not c["locked"] and c["cost"] <= farm["coins"]]
|
|
if not options:
|
|
return None
|
|
return max(options, key=lambda c: c["reward_coins"])
|
|
|
|
|
|
def claim_free_rewards(farm):
|
|
if farm.get("daily_available"):
|
|
call("POST", "/game/daily")
|
|
if farm.get("grant_available"):
|
|
call("POST", "/game/grant")
|
|
for quest in farm.get("quests", []):
|
|
if quest.get("can_claim"):
|
|
call("POST", "/game/quests/claim", {"quest": quest["kind"], "scope": quest["scope"]})
|
|
|
|
|
|
def harvest_and_replant(farm):
|
|
for plot in farm["plots"]:
|
|
if plot["state"] == "ready":
|
|
call("POST", "/game/harvest", {"slot": plot["slot"]})
|
|
farm = state()
|
|
for plot in farm["plots"]:
|
|
if plot["state"] != "empty":
|
|
continue
|
|
crop = best_affordable_crop(farm)
|
|
if not crop:
|
|
break
|
|
call("POST", "/game/plant", {"slot": plot["slot"], "crop": crop["key"]})
|
|
farm = state()
|
|
return farm
|
|
|
|
|
|
def run():
|
|
print("Code Farm automation started.")
|
|
while True:
|
|
try:
|
|
farm = state()
|
|
claim_free_rewards(farm)
|
|
farm = harvest_and_replant(state())
|
|
print(f"coins={farm['coins']} level={farm['level']} harvests={farm['total_harvests']}")
|
|
except urllib.error.HTTPError as error:
|
|
print("api error:", error.code, error.read().decode()[:200])
|
|
except OSError as error:
|
|
print("network error, retrying:", error)
|
|
time.sleep(POLL_SECONDS)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run()
|
|
```
|
|
|
|
From here the natural extensions are easy: spend surplus coins with `POST /game/buy-plot` and
|
|
`POST /game/upgrade` when you can afford them, raise perks with `POST /game/perk`, water
|
|
neighbours by walking `GET /game/farm/{username}` and posting to its `/water` path for plots where
|
|
`can_water` is true, raid where `can_steal` is true, and refactor with `POST /game/prestige` once
|
|
`refactor_affordable` is set. Be polite to the rate limiter: mutating calls are limited per
|
|
client, so a poll interval of a minute or more with one action per finished build stays well
|
|
within limits.
|
|
|
|
## Ask Devii
|
|
|
|
You can also play in plain language through the Devii assistant, which calls the same endpoints
|
|
for you:
|
|
|
|
> Check my Code Farm, harvest anything that is ready, and replant with the best crop I can afford.
|
|
|
|
Devii reads your state, performs the actions, and reports your new coin and level totals.
|
|
|
|
</div>
|
|
|
|
<div class="devii-doc-cta">
|
|
<a href="/game" class="sidebar-link">Open Code Farm</a>
|
|
</div>
|